mirror of
https://github.com/anomalyco/opentui.git
synced 2026-09-19 01:26:03 +08:00
feat(native): filter Ghostty logs (#1426)
## Summary - recognize the selected Ghostty `std.log` scopes in OpenTUI's root logger - keep all standard-library logs silent by default - read `OTUI_GHOSTTY_LOG_LEVEL` inside the native `logFn` and forward enabled messages through the existing `logger.logMessage` path - support `error`/`err`, `warn`/`warning`, `info`, and `debug` thresholds - document the environment variable ## Behavior Unset or invalid `OTUI_GHOSTTY_LOG_LEVEL` values emit no `std.log` messages. Recognized Ghostty scopes are forwarded up to the configured severity. Logs from every other scope are discarded. Explicit OpenTUI logger calls are unchanged. ## Testing - release `bun run build` from `packages/core` - `bun run test:native` from `packages/core` (2066 passed, 8 skipped) - `zig fmt --check packages/native/src/lib.zig packages/native/src/logger.zig` - `oxfmt --check packages/web/src/content/docs/reference/env-vars.mdx`
This commit is contained in:
@@ -4,19 +4,58 @@ const build_options = @import("build_options");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = discardStdLog,
|
||||
.log_level = .debug,
|
||||
.logFn = handleStdLog,
|
||||
};
|
||||
|
||||
fn discardStdLog(
|
||||
fn handleStdLog(
|
||||
comptime message_level: std.log.Level,
|
||||
comptime scope: @EnumLiteral(),
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void {
|
||||
_ = message_level;
|
||||
_ = scope;
|
||||
_ = format;
|
||||
_ = args;
|
||||
const ghostty_scope = switch (scope) {
|
||||
.parser,
|
||||
.stream,
|
||||
.stream_terminal,
|
||||
.screen,
|
||||
.terminal,
|
||||
.terminal_mem,
|
||||
.terminal_apc,
|
||||
.terminal_dcs,
|
||||
.osc,
|
||||
.osc_color,
|
||||
.osc_iterm2,
|
||||
.kitty_gfx,
|
||||
.key_encode,
|
||||
.mouse_encode,
|
||||
.render_state_c,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
if (!ghostty_scope) return;
|
||||
const configured = ghosttyLogLevel() orelse return;
|
||||
if (@intFromEnum(message_level) > @intFromEnum(configured)) return;
|
||||
|
||||
const level: logger.LogLevel = switch (message_level) {
|
||||
.err => .err,
|
||||
.warn => .warn,
|
||||
.info => .info,
|
||||
.debug => .debug,
|
||||
};
|
||||
logger.logMessage(level, "(" ++ @tagName(scope) ++ ") " ++ format, args);
|
||||
}
|
||||
|
||||
fn ghosttyLogLevel() ?std.log.Level {
|
||||
const Environment = struct {
|
||||
extern "c" fn getenv(name: [*:0]const u8) ?[*:0]const u8;
|
||||
};
|
||||
const value = std.mem.span(Environment.getenv("OTUI_GHOSTTY_LOG_LEVEL") orelse return null);
|
||||
if (std.ascii.eqlIgnoreCase(value, "error") or std.ascii.eqlIgnoreCase(value, "err")) return .err;
|
||||
if (std.ascii.eqlIgnoreCase(value, "warning") or std.ascii.eqlIgnoreCase(value, "warn")) return .warn;
|
||||
if (std.ascii.eqlIgnoreCase(value, "info")) return .info;
|
||||
if (std.ascii.eqlIgnoreCase(value, "debug")) return .debug;
|
||||
return null;
|
||||
}
|
||||
|
||||
var io_threaded: std.Io.Threaded = .init_single_threaded;
|
||||
|
||||
@@ -112,16 +112,21 @@ Tree-sitter worker started. An explicit client `workerPath` option takes precede
|
||||
|
||||
## Security-sensitive diagnostics
|
||||
|
||||
| Variable | Type | Default | Read time | Purpose |
|
||||
| ---------------- | --------- | ------- | ----------------- | ----------------------------------------- |
|
||||
| `OTUI_DEBUG` | `boolean` | `false` | Renderer creation | Retain raw input sequences for debugging |
|
||||
| `OTUI_STDIN_LOG` | `string` | `""` | Renderer creation | Write the raw stdin byte stream to a file |
|
||||
| Variable | Type | Default | Read time | Purpose |
|
||||
| ------------------------ | --------- | ------- | --------------------- | ------------------------------------------------------------- |
|
||||
| `OTUI_DEBUG` | `boolean` | `false` | Renderer creation | Retain raw input sequences for debugging |
|
||||
| `OTUI_STDIN_LOG` | `string` | `""` | Renderer creation | Write the raw stdin byte stream to a file |
|
||||
| `OTUI_GHOSTTY_LOG_LEVEL` | `string` | `""` | Native initialization | Forward scoped Ghostty logs through the normal OpenTUI logger |
|
||||
|
||||
`OTUI_STDIN_LOG=/tmp/opentui-stdin.bin` records stdin before parsing. The renderer truncates the file when it starts
|
||||
and writes to it synchronously. The binary data can contain passwords and other sensitive input. Use this option only
|
||||
for short debugging sessions, and protect the recorded file. Treat `OTUI_DEBUG` input captures and
|
||||
`OTUI_DUMP_CAPTURES` output as sensitive data too.
|
||||
|
||||
`OTUI_GHOSTTY_LOG_LEVEL` accepts `error`, `warn`, `info`, or `debug` (`err` and `warning` are aliases). The selected level
|
||||
includes all more severe messages. Unset or invalid values disable Ghostty logs. Standard-library logs outside the
|
||||
recognized Ghostty scopes are always discarded.
|
||||
|
||||
## Remote sessions
|
||||
|
||||
A renderer with `remote: true` forwards no local environment keys to native terminal detection by default. Add only
|
||||
|
||||
Reference in New Issue
Block a user