Skip to content

Adopt loglevel-based frontend logger (match BoxVault pattern) #173

@MarkProminic

Description

@MarkProminic

Context

The frontend currently uses raw console.* throughout. This was not the original intent; preference is a logger abstraction, not raw console.

All claims in this issue were verified against the current codebase, not asserted from memory:

  • grep console\.(log|error|warn|info|debug) web/src/: 76 occurrences across 21 files
  • glob web/src/**/logger*: no results
  • grep '"loglevel"' web/package.json: no match
  • grep -R /api/health routes/: no match

Reference implementation

BoxVault (G:\Projects\BoxVault) already runs the intended pattern. Verified by reading:

  • frontend/src/utils/Logger.js (full file, in-repo)
  • backend/app/controllers/health/info.js (full file, in-repo)
  • frontend/package.json (dep line)
  • BoxVault's app config YAML (the frontend_logging section is defined there, not hardcoded in JS)

Frontend side:

  • Dep: "loglevel": "^1.9.2"
  • Wrapper: frontend/src/utils/Logger.js — exports a log object with 6 categories (app, auth, api, file, component, error), each with methods trace/debug/info/warn/error.
  • Call signature: log.auth.info("message", { optional: "metadata" }) — two args, message is a plain string, metadata is an optional object.
  • Auto-prefix: [CATEGORY] (uppercase) prepended to every message.
  • Lazy config: fetches /api/health on first log call. Response includes frontend_logging: { enabled, level, categories: { app, auth, api, file, component } }. Calls issued before the fetch resolves are promise-buffered, not dropped.
  • Silencing: enabled: false in config → logger.setLevel("silent") → all categories silenced.
  • Fallback: on /api/health failure (network error, non-2xx, etc.), Logger uses a hardcoded dev config (all categories at debug) so dev ergonomics never depend on the backend being reachable.

Backend side:

  • /api/health endpoint returns { status, timestamp, version, environment, supported_languages, default_language, frontend_logging, services } — a full health check, not just the logging config.
  • Config source: a frontend_logging section in BoxVault's app YAML config file (per-category level strings). The backend reads this via its config loader and exposes the resolved values through the health endpoint. Changing a category's level is a YAML edit + restart, no code change required.
  • The endpoint also performs DB connectivity checks, storage/disk-usage checks, OIDC issuer pings, and optional SMTP disk-alert emails — these are BoxVault-specific and out of scope for armor's initial port.

Proposed scope

Frontend

  • Add "loglevel": "^1.9.2" to web/package.json dependencies
  • Port web/src/utils/Logger.js from the BoxVault reference — no shape changes (keep same 6 categories + method names for consistency across repos)
  • Replace all 76 console.* calls across the 21 frontend files with the appropriate log.<category>.<level>() call
  • Add no-console to the frontend ESLint config with an exception only for web/src/utils/Logger.js (or wherever internal fallbacks are allowed)

Backend

  • Add /api/health endpoint to armor that returns at minimum { status, timestamp, version, environment, frontend_logging: { enabled, level, categories } }. Defer BoxVault's full scope (disk checks, OIDC probes, SMTP alerting) to a follow-up issue unless explicitly requested.
  • Add a frontend_logging section to packaging/config/production-config.yaml and the config template, matching BoxVault's per-category structure
  • Wire a configLoader.getFrontendLoggingConfig() method; expose the resolved config via the health endpoint handler

Validation

  • CI lint passes with no-console rule active
  • Runtime check: set frontend_logging.enabled: false in config → no frontend log output at runtime; set an individual category to error → only errors visible for that category
  • /api/health failure path: Logger falls back to dev defaults silently, app still functions

Out of scope

  • Backend logger changes — winston is already in place via config/logger.js; not touched.
  • Translation of log messages — dev-facing strings, not user-facing; separate discussion (and BoxVault does not translate its log messages either).
  • BoxVault's full health-check (disk, OIDC probes, SMTP alerts) — open a follow-up issue if we want those.

References

  • BoxVault Logger: G:\Projects\BoxVault\frontend\src\utils\Logger.js
  • BoxVault health endpoint: G:\Projects\BoxVault\backend\app\controllers\health\info.js
  • BoxVault frontend package.json (for loglevel version pin)
  • Current armor frontend console call sites: grep -rn 'console\.\(log\|error\|warn\|info\|debug\)' web/src/ (76 / 21 files at time of filing)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions