macos: send logs to unified logging

This commit is contained in:
Mitchell Hashimoto
2022-10-31 15:15:32 -07:00
parent 7608d7921f
commit 9e3bbc1598
3 changed files with 60 additions and 9 deletions

View File

@ -115,3 +115,11 @@ than 5 MB on all platforms. The debug version is around 70MB.
When targeting macOS, a macOS application bundle will be created at
`zig-out/Ghostty.app`. This can be copied as-is and used like a normal app.
This app will be not be signed or notarized.
When running the app, logs are available via macOS unified logging such
as `Console.app`. The easiest way I've found is to just use the CLI:
```sh
$ sudo log stream --level debug --predicate 'subsystem=="com.mitchellh.ghostty"'
...
```

View File

@ -6,5 +6,5 @@ void zig_os_log_with_type(
os_log_type_t type,
const char *message
) {
os_log_with_type(log, type, "%s", message);
os_log_with_type(log, type, "%{public}s", message);
}

View File

@ -5,6 +5,7 @@ const glfw = @import("glfw");
const fontconfig = @import("fontconfig");
const freetype = @import("freetype");
const harfbuzz = @import("harfbuzz");
const macos = @import("macos");
const tracy = @import("tracy");
const renderer = @import("renderer.zig");
@ -12,15 +13,13 @@ const App = @import("App.zig");
const cli_args = @import("cli_args.zig");
const Config = @import("config.zig").Config;
const log = std.log.scoped(.main);
pub fn main() !void {
// Output some debug information right away
log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()});
std.log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()});
if (options.fontconfig) {
log.info("dependency fontconfig={d}", .{fontconfig.version()});
std.log.info("dependency fontconfig={d}", .{fontconfig.version()});
}
log.info("renderer={}", .{renderer.Renderer});
std.log.info("renderer={}", .{renderer.Renderer});
const GPA = std.heap.GeneralPurposeAllocator(.{});
var gpa: ?GPA = gpa: {
@ -92,7 +91,7 @@ pub fn main() !void {
return error.ConfigFileInConfigFile;
}
}
log.info("config={}", .{config});
std.log.info("config={}", .{config});
// We want to log all our errors
glfw.setErrorCallback(glfwErrorCallback);
@ -112,10 +111,54 @@ pub fn tracy_enabled() bool {
return options.tracy_enabled;
}
//pub const log_level: std.log.Level = .debug;
// Our log level is always at least info in every build mode.
pub const log_level: std.log.Level = switch (builtin.mode) {
.Debug => .debug,
else => .info,
};
// The function std.log will call.
pub fn log(
comptime level: std.log.Level,
comptime scope: @TypeOf(.EnumLiteral),
comptime format: []const u8,
args: anytype,
) void {
// Stuff we can do before the lock
const level_txt = comptime level.asText();
const prefix = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
// Lock so we are thread-safe
std.debug.getStderrMutex().lock();
defer std.debug.getStderrMutex().unlock();
// On Mac, we use unified logging. To view this:
//
// sudo log stream --level debug --predicate 'subsystem=="com.mitchellh.ghostty"'
//
if (builtin.os.tag == .macos) {
// Convert our levels to Mac levels
const mac_level: macos.os.LogType = switch (level) {
.debug => .debug,
.info => .info,
.warn => .err,
.err => .fault,
};
// Initialize a logger. This is slow to do on every operation
// but we shouldn't be logging too much.
const logger = macos.os.Log.create("com.mitchellh.ghostty", @tagName(scope));
defer logger.release();
logger.log(std.heap.c_allocator, mac_level, format, args);
}
// Always try default to send to stderr
const stderr = std.io.getStdErr().writer();
nosuspend stderr.print(level_txt ++ prefix ++ format ++ "\n", args) catch return;
}
fn glfwErrorCallback(code: glfw.Error, desc: [:0]const u8) void {
log.warn("glfw error={} message={s}", .{ code, desc });
std.log.warn("glfw error={} message={s}", .{ code, desc });
}
test {