mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
implement sentry transport to write crash reports to XDG_STATE_HOME
This commit is contained in:
@ -1004,6 +1004,7 @@ fn addDeps(
|
|||||||
const sentry_dep = b.dependency("sentry", .{
|
const sentry_dep = b.dependency("sentry", .{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
.backend = .inproc,
|
||||||
});
|
});
|
||||||
const zlib_dep = b.dependency("zlib", .{
|
const zlib_dep = b.dependency("zlib", .{
|
||||||
.target = target,
|
.target = target,
|
||||||
|
@ -7,4 +7,12 @@ pub const Envelope = opaque {
|
|||||||
pub fn deinit(self: *Envelope) void {
|
pub fn deinit(self: *Envelope) void {
|
||||||
c.sentry_envelope_free(@ptrCast(self));
|
c.sentry_envelope_free(@ptrCast(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn writeToFile(self: *Envelope, path: []const u8) !void {
|
||||||
|
if (c.sentry_envelope_write_to_file_n(
|
||||||
|
@ptrCast(self),
|
||||||
|
path.ptr,
|
||||||
|
path.len,
|
||||||
|
) != 0) return error.WriteFailed;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,10 @@ const c = @import("c.zig").c;
|
|||||||
pub const UUID = struct {
|
pub const UUID = struct {
|
||||||
value: c.sentry_uuid_t,
|
value: c.sentry_uuid_t,
|
||||||
|
|
||||||
|
pub fn init() UUID {
|
||||||
|
return .{ .value = c.sentry_uuid_new_v4() };
|
||||||
|
}
|
||||||
|
|
||||||
pub fn isNil(self: UUID) bool {
|
pub fn isNil(self: UUID) bool {
|
||||||
return c.sentry_uuid_is_nil(&self.value) != 0;
|
return c.sentry_uuid_is_nil(&self.value) != 0;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,15 @@ pub fn cache(alloc: Allocator, opts: Options) ![]u8 {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the XDG state directory. The returned value is allocated.
|
||||||
|
pub fn state(alloc: Allocator, opts: Options) ![]u8 {
|
||||||
|
return try dir(alloc, opts, .{
|
||||||
|
.env = "XDG_STATE_HOME",
|
||||||
|
.windows_env = "LOCALAPPDATA",
|
||||||
|
.default_subdir = ".local/state",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const InternalOptions = struct {
|
const InternalOptions = struct {
|
||||||
env: []const u8,
|
env: []const u8,
|
||||||
windows_env: []const u8,
|
windows_env: []const u8,
|
||||||
|
@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
const build_config = @import("build_config.zig");
|
const build_config = @import("build_config.zig");
|
||||||
const sentry = @import("sentry");
|
const sentry = @import("sentry");
|
||||||
const internal_os = @import("os/main.zig");
|
const internal_os = @import("os/main.zig");
|
||||||
|
const state = &@import("global.zig").state;
|
||||||
|
|
||||||
const log = std.log.scoped(.sentry);
|
const log = std.log.scoped(.sentry);
|
||||||
|
|
||||||
@ -61,10 +62,42 @@ pub fn deinit() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const Transport = struct {
|
pub const Transport = struct {
|
||||||
pub fn send(envelope: *sentry.Envelope, state: ?*anyopaque) callconv(.C) void {
|
pub fn send(envelope: *sentry.Envelope, ud: ?*anyopaque) callconv(.C) void {
|
||||||
_ = state;
|
_ = ud;
|
||||||
defer envelope.deinit();
|
defer envelope.deinit();
|
||||||
|
|
||||||
log.warn("sending envelope", .{});
|
// Call our internal impl. If it fails there is nothing we can do
|
||||||
|
// but log to the user.
|
||||||
|
sendInternal(envelope) catch |err| {
|
||||||
|
log.warn("failed to persist crash report err={}", .{err});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementation of send but we can use Zig errors.
|
||||||
|
fn sendInternal(envelope: *sentry.Envelope) !void {
|
||||||
|
var arena = std.heap.ArenaAllocator.init(state.alloc);
|
||||||
|
defer arena.deinit();
|
||||||
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
|
// Generate a UUID for this envelope. The envelope DOES have an event_id
|
||||||
|
// header but I don't think there is any public API way to get it
|
||||||
|
// afaict so we generate a new UUID for the filename just so we don't
|
||||||
|
// conflict.
|
||||||
|
const uuid = sentry.UUID.init();
|
||||||
|
|
||||||
|
// Get our XDG state directory where we'll store the crash reports.
|
||||||
|
// This directory must exist for writing to work.
|
||||||
|
const crash_dir = try internal_os.xdg.state(alloc, .{ .subdir = "ghostty/crash" });
|
||||||
|
try std.fs.cwd().makePath(crash_dir);
|
||||||
|
|
||||||
|
// Build our final path and write to it.
|
||||||
|
const path = try std.fs.path.join(alloc, &.{
|
||||||
|
crash_dir,
|
||||||
|
try std.fmt.allocPrint(alloc, "{s}.ghosttycrash", .{uuid.string()}),
|
||||||
|
});
|
||||||
|
log.debug("writing crash report to disk path={s}", .{path});
|
||||||
|
try envelope.writeToFile(path);
|
||||||
|
|
||||||
|
log.warn("crash report written to disk path={s}", .{path});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user