Skip to content

createLogger: migrate to pluggable log adapters (stdout + file + custom sinks) #1238

Open

Description

@willwashburn

Motivation

packages/utils/src/logger.ts (createLogger) is env-driven and picks one implicit sink: if AGENT_RELAY_LOG_FILE is set it writes to the file and returns, otherwise it writes to the console. Fleet-node structured logging (#1237 — capabilities registered, actions invoked/completed/failed) now flows through it, which surfaces the limitations:

  • No simultaneous sinks. You cannot tee to both a file and stdout — the file path short-circuits console output entirely (logger.ts ~L90-102).
  • No pluggable adapters. Format (text vs JSON) and destination are hardcoded and chosen by env vars; there's no way to register a custom sink (ship to relaycast, PostHog, syslog, an in-memory ring buffer for tests).
  • Process-global config. Level/file/format are read from process.env per call, so every component (broker, router, connection, fleet) shares one destination — you can't route fleet to its own file while leaving broker logs on the console.
  • Blocking writes. appendFileSync per line; no buffering/rotation.

Proposal

Introduce an adapter interface and let a logger fan out to N adapters:

interface LogAdapter {
  write(entry: LogEntry): void;      // or Promise<void> for async sinks
  minLevel?: LogLevel;               // per-adapter filtering
}

createLogger('fleet', { adapters: [stdoutAdapter(), fileAdapter('./node.log', { json: true })] })
  • Ship built-in stdoutAdapter / stderrAdapter / fileAdapter (with JSON option, and optional rotation/buffering).
  • Keep the AGENT_RELAY_LOG_* env vars as a default adapter set for back-compat so existing callers (and the relay node up --log-* flags added in Fleet node structured logging: capabilities registered and actions invoked #1237) keep working.
  • Per-component adapter overrides so fleet logs can go somewhere distinct from broker/router logs.

Context

Surfaced while adding fleet-node structured logging (#1237). That change deliberately reused createLogger and injects it into serveNode via a FleetLogger seam, so once adapters land, fleet gains multi-sink/custom-sink output with no changes on the fleet side.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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