Skip to content

feat(log): implement Pino-based logger#2

Open
sheplu wants to merge 4 commits into
mainfrom
base-logger
Open

feat(log): implement Pino-based logger#2
sheplu wants to merge 4 commits into
mainfrom
base-logger

Conversation

@sheplu

@sheplu sheplu commented Jul 21, 2026

Copy link
Copy Markdown
Member

First real implementation of @express/log, replacing the hello() placeholder.

API

const logger = createLogger({ service: "my-api", version: "1.2.3" });
logger.info("request received");
logger.child({ req_id: "abc" }).info({ user_id: "u-1" }, "authenticated");
  • Standard base fields on every line: service, version, env, host, pid, runtime, logger.name
  • Reserved correlation fields (req_id, trace_id, span_id, …) populated by consumers via logger.child() — not set by core
  • Default redaction (auth headers, passwords, tokens, secrets) with mergeable overrides and remove: true support
  • Transport: NDJSON to stdout in production, pino-pretty to stderr in development
  • Error serializer wraps pino.stdSerializers.err and adds Node err.code

Tests

  • unit: pure-function tests, 100% line coverage
  • integration: factory → capture stream → JSON parse
  • e2e: subprocess smoke tests against the built dist/

CI

Adds e2e and manifest jobs that reuse the build artifact.

Out of scope

Express middleware, OTel bindings, AsyncLocalStorage, file transports — follow-up work.

sheplu added 3 commits July 20, 2026 21:54
ESM project targeting Node 24+ with a GitHub Actions
quality-gates workflow.
Replace the bootstrap hello() placeholder with a real Pino-based logger
that emits a consistent set of base fields (service, version, env, host,
pid, runtime, logger.name) across every log line.

- createLogger() factory with required service option, env/level defaults
  from NODE_ENV/LOG_LEVEL, and child-logger seam for future correlation
- Standard field schema with reserved names (req_id, trace_id, span_id)
- Default redaction paths (auth headers, passwords, tokens, secrets)
  with mergeable caller overrides and remove:true support
- Transport selection: stdout NDJSON in production, pino-pretty to stderr
  in development, with explicit overrides and DestinationStream support
- Error serializer wrapping pino stdSerializers.err with Node err.code
- Levels re-exported as stable const so consumers don't depend on pino
Three layers covering the logger implementation:

- test/unit/: pure-function tests
- test/integration/: factory to capture stream to JSON parse
- test/e2e/: subprocess smoke tests against the built artifact
Add two jobs to the quality gates workflow:

- e2e: downloads the dist artifact from the build job and runs test:e2e:run
- manifest: downloads the dist artifact and runs test:manifest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant