Skip to content

Commit 7080f81

Browse files
FUDCoclaude
andauthored
feat(kernel-cli): filter daemon log entries below a minimum severity (#1008)
Small, self-contained quality-of-life change to the daemon's log transport, extracted from `chip/orchestration-demo`. Independent of the kernel work in #1007 — this branches off `main` directly rather than stacking. ## Problem `daemon.log` recorded every level. In practice `debug` output — refcount churn especially — dominated the file badly enough to make it hard to read while debugging anything else. On a busy daemon the signal you actually want is buried. ## Change The file transport drops entries below a minimum severity, defaulting to `info`. Set `$OCAP_DAEMON_LOG_LEVEL=debug` to record everything again. Two details worth a reviewer's eye: - `LOG_LEVELS` mirrors `@metamask/logger`'s level ordering locally because `logLevels` isn't part of that package's public surface. If it's ever exported, this should switch to importing it rather than keeping a copy in sync. - It's declared *above* the file-scope logger construction deliberately. The transport factory is invoked during module init, so a later declaration would put `LOG_LEVELS` in its temporal dead zone at exactly the moment it's read. ## Not included The fatal-path handler work that lives in the same file is already on `main` (#966), so this PR touches only the level-filtering lines. ## Validation `@metamask/kernel-cli` builds, lints, and its tests pass. Changelog entry follows in a second commit once this PR has a number to link to. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Observability-only change to log file filtering; no auth, RPC, or persistence behavior is affected. > > **Overview** > **`daemon.log` now skips entries below a minimum severity** (default **`info`**) in the daemon file transport, so noisy **`debug`** lines no longer bury useful output. > > The threshold comes from **`OCAP_DAEMON_LOG_LEVEL`**; set it to **`debug`** to record all levels again. **`makeFileTransport`** compares each entry against a local **`LOG_LEVELS`** map (mirroring `@metamask/logger` ordering, since levels aren’t exported). Changelog documents the behavior change. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 66dc26d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 9cdc6ec commit 7080f81

2 files changed

Lines changed: 41 additions & 3 deletions

File tree

packages/kernel-cli/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
### Changed
1717

18+
- 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))
1819
- 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))
1920

2021
### Fixed

packages/kernel-cli/src/commands/daemon-entry.ts

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,41 @@ import { join } from 'node:path';
1111
import { getOcapHome } from '../ocap-home.ts';
1212
import { isProcessAlive } from '../utils.ts';
1313

14+
// Mirror of @metamask/logger's level ordering (`logLevels` is not part
15+
// of the package's public surface). Higher numbers are more severe.
16+
// Declared above the file-scope logger construction so the transport
17+
// factory doesn't hit a temporal-dead-zone reference when it's called
18+
// during module init.
19+
const LOG_LEVELS = {
20+
debug: 1,
21+
info: 2,
22+
log: 3,
23+
warn: 4,
24+
error: 5,
25+
} as const;
26+
27+
type LogLevelName = keyof typeof LOG_LEVELS;
28+
29+
/**
30+
* Resolve the daemon's minimum log level from `OCAP_DAEMON_LOG_LEVEL`.
31+
* Defaults to `info` so noisy `debug` entries (refcount churn etc.)
32+
* are dropped; set the env var to `debug` to re-enable everything.
33+
*
34+
* @returns The minimum log level to record.
35+
*/
36+
function resolveMinLogLevel(): LogLevelName {
37+
const raw = process.env.OCAP_DAEMON_LOG_LEVEL;
38+
if (raw !== undefined && raw in LOG_LEVELS) {
39+
return raw as LogLevelName;
40+
}
41+
return 'info';
42+
}
43+
1444
const ocapDir = getOcapHome();
1545
const logPath = join(ocapDir, 'daemon.log');
1646
const logger = new Logger({
1747
tags: ['daemon'],
18-
transports: [makeFileTransport(logPath)],
48+
transports: [makeFileTransport(logPath, resolveMinLogLevel())],
1949
});
2050

2151
// Install exit-cause handlers at module load, before main() runs, so
@@ -139,13 +169,20 @@ async function readDaemonPid(pidPath: string): Promise<number | undefined> {
139169
}
140170

141171
/**
142-
* Create a file transport that writes logs to a file.
172+
* Create a file transport that writes logs to a file, filtering out
173+
* entries below `minLevel`.
143174
*
144175
* @param logFilePath - The log file path.
176+
* @param minLevel - Minimum severity to write; entries below this are
177+
* dropped silently.
145178
* @returns A log transport function.
146179
*/
147-
function makeFileTransport(logFilePath: string) {
180+
function makeFileTransport(logFilePath: string, minLevel: LogLevelName) {
181+
const minIdx = LOG_LEVELS[minLevel];
148182
return (entry: LogEntry): void => {
183+
if (LOG_LEVELS[entry.level] < minIdx) {
184+
return;
185+
}
149186
const line = `[${new Date().toISOString()}] [${entry.level}] ${entry.message ?? ''} ${(entry.data ?? []).map(String).join(' ')}\n`;
150187
// eslint-disable-next-line n/no-sync -- synchronous write needed for log transport reliability
151188
appendFileSync(logFilePath, line);

0 commit comments

Comments
 (0)