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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions