# 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: ```js 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:`. Use: - `debug` for detailed, low-value troubleshooting information. - `info` for meaningful lifecycle and administrative actions. - `warn` for degraded behavior that Lumi can continue through. - `error` for 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: ```js 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.