Lumi/docs/LOGGING_STANDARD.md
2026-07-26 14:22:51 +02:00

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:

  • 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:

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.