From 11081dd7bd3fcbe46533380dda32b770dbfe0b26 Mon Sep 17 00:00:00 2001 From: Chip Morningstar Date: Tue, 4 Aug 2026 16:58:04 -0700 Subject: [PATCH 1/2] feat(kernel-cli): filter daemon log entries below a minimum severity The daemon log was recording every level, and high-volume `debug` output (refcount churn and similar) dominated `daemon.log` to the point of making it hard to read while debugging anything else. The file transport now drops entries below a minimum severity, defaulting to `info`; set `$OCAP_DAEMON_LOG_LEVEL` to `debug` to record everything again. `LOG_LEVELS` mirrors @metamask/logger's ordering because `logLevels` is not part of that package's public surface, and it is declared above the file-scope logger construction so the transport factory does not hit a temporal-dead-zone reference when called during module init. Co-Authored-By: Claude Opus 4.7 --- .../kernel-cli/src/commands/daemon-entry.ts | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/packages/kernel-cli/src/commands/daemon-entry.ts b/packages/kernel-cli/src/commands/daemon-entry.ts index 5a091735f..77d96b00e 100644 --- a/packages/kernel-cli/src/commands/daemon-entry.ts +++ b/packages/kernel-cli/src/commands/daemon-entry.ts @@ -11,11 +11,41 @@ import { join } from 'node:path'; import { getOcapHome } from '../ocap-home.ts'; import { isProcessAlive } from '../utils.ts'; +// Mirror of @metamask/logger's level ordering (`logLevels` is not part +// of the package's public surface). Higher numbers are more severe. +// Declared above the file-scope logger construction so the transport +// factory doesn't hit a temporal-dead-zone reference when it's called +// during module init. +const LOG_LEVELS = { + debug: 1, + info: 2, + log: 3, + warn: 4, + error: 5, +} as const; + +type LogLevelName = keyof typeof LOG_LEVELS; + +/** + * Resolve the daemon's minimum log level from `OCAP_DAEMON_LOG_LEVEL`. + * Defaults to `info` so noisy `debug` entries (refcount churn etc.) + * are dropped; set the env var to `debug` to re-enable everything. + * + * @returns The minimum log level to record. + */ +function resolveMinLogLevel(): LogLevelName { + const raw = process.env.OCAP_DAEMON_LOG_LEVEL; + if (raw !== undefined && raw in LOG_LEVELS) { + return raw as LogLevelName; + } + return 'info'; +} + const ocapDir = getOcapHome(); const logPath = join(ocapDir, 'daemon.log'); const logger = new Logger({ tags: ['daemon'], - transports: [makeFileTransport(logPath)], + transports: [makeFileTransport(logPath, resolveMinLogLevel())], }); // Install exit-cause handlers at module load, before main() runs, so @@ -139,13 +169,20 @@ async function readDaemonPid(pidPath: string): Promise { } /** - * Create a file transport that writes logs to a file. + * Create a file transport that writes logs to a file, filtering out + * entries below `minLevel`. * * @param logFilePath - The log file path. + * @param minLevel - Minimum severity to write; entries below this are + * dropped silently. * @returns A log transport function. */ -function makeFileTransport(logFilePath: string) { +function makeFileTransport(logFilePath: string, minLevel: LogLevelName) { + const minIdx = LOG_LEVELS[minLevel]; return (entry: LogEntry): void => { + if (LOG_LEVELS[entry.level] < minIdx) { + return; + } const line = `[${new Date().toISOString()}] [${entry.level}] ${entry.message ?? ''} ${(entry.data ?? []).map(String).join(' ')}\n`; // eslint-disable-next-line n/no-sync -- synchronous write needed for log transport reliability appendFileSync(logFilePath, line); From 05b82b58e6a00c43f07e762dc7972ea3f1d6898b Mon Sep 17 00:00:00 2001 From: Chip Morningstar Date: Tue, 4 Aug 2026 16:58:47 -0700 Subject: [PATCH 2/2] docs(kernel-cli): changelog entry for daemon log-level filtering Co-Authored-By: Claude Opus 4.7 --- packages/kernel-cli/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/kernel-cli/CHANGELOG.md b/packages/kernel-cli/CHANGELOG.md index 01ef62cb9..6d2f04471 100644 --- a/packages/kernel-cli/CHANGELOG.md +++ b/packages/kernel-cli/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- The daemon log filters entries below a minimum severity, defaulting to `info`, so high-volume `debug` output (refcount churn and similar) no longer dominates `daemon.log`; set `$OCAP_DAEMON_LOG_LEVEL` to `debug` to record everything again ([#1008](https://github.com/MetaMask/ocap-kernel/pull/1008)) - Relay state files (`relay.pid`, `relay.addr`) now live in their own directory (default `~/.libp2p-relay`, overridable via `$LIBP2P_RELAY_HOME`) instead of under `$OCAP_HOME`, so one libp2p relay can serve daemons with different OCAP_HOMEs ([#952](https://github.com/MetaMask/ocap-kernel/pull/952)) ### Fixed