2.4 KiB
Logging standard
Lumi uses the structured logger in src/services/logger.js for operational
events. It stores searchable entries for the admin UI, attaches request context,
redacts common credential fields, and publishes live admin updates.
Operational logging
Core services create a named logger:
const { createLogger } = require("./logger");
const logger = createLogger("updater");
logger.info("Update check completed", { version }, {
category: "updates",
event: "update_check_completed"
});
Plugins receive a plugin-scoped logger in their init() dependencies. Use
that injected logger when practical. A plugin module that must log outside
init() may create a logger named plugin:<plugin-id>.
Use:
debugfor detailed, low-value troubleshooting information.infofor meaningful lifecycle and administrative actions.warnfor degraded behavior that Lumi can continue through.errorfor a failed operation that may require attention.
Pass an Error as the details argument when one is available. The logger
preserves its stack trace while applying credential redaction:
logger.error("Plugin refresh failed", error, {
event: "plugin_refresh_failed"
});
Do not include passwords, tokens, cookies, pairing secrets, authorization headers, or full request bodies in messages or metadata. Redaction is a safety net, not a reason to collect secrets.
Metrics and high-frequency events
Do not write high-frequency counters or per-frame events to the operational log. There is no global metrics API.
A feature may retain its own bounded metrics only when it also owns the storage,
retention, and inspection UI. Lumi AI is one example:
plugins/lumi_ai/backend/metrics.js aggregates AI timings and retains bounded
work history. Operational failures in such a feature still belong in the core
logger.
Console output
Direct console.* calls are captured after hookConsole() starts, but they lose
the useful source and event metadata of a named logger. Prefer a named logger in
runtime code. Console output remains reasonable in standalone verification and
build scripts where the terminal is the intended consumer.
Retention and context
Operational logs default to 30 days and at most 100,000 entries. Request
correlation is inherited through withLogContext() and logger run() scopes.
The logger redacts common sensitive keys and credential-looking text before an
entry is stored or published.