Skip to content

Implement structured request/response logging and observability middleware #205

@grantfox-development

Description

@grantfox-development

Problem

Observability is fragmented and inconsistent across the backend:

  • The custom Logger utility in src/utils/logger.ts only wraps console.log/error/warn, providing no log levels, structured fields, or transports.
  • 20+ raw console.* statements remain across src/ (middleware, controllers, services).
  • There is no request/response logging middleware, making it hard to debug API issues in production.
  • The health-check endpoint in src/index.ts:53-105 mixes Date.now() timing with console.error, producing unstructured output.
  • The rate-limit middleware logs via console.log(allowed, remaining) at rateLimitMiddleware.ts:18.
  • winston is in package.json but unused.
  • No correlation IDs, no consistent error context (user ID, route, stack), no JSON output suitable for production log aggregators.

Proposed Solution

  1. Create src/middleware/requestLoggingMiddleware.ts that logs every incoming request (method, path, query, authenticated user ID when available) and the outgoing response (status, duration in ms, response size).
  2. Refactor src/utils/logger.ts to delegate to Winston with JSON formatter and configurable transports (console + file).
  3. Wire the logging middleware into the Express app in src/index.ts.
  4. Replace console.* calls in middleware, auth, services, and controllers with logger.info/warn/error calls (priority: middleware and auth paths).
  5. Update the health-check endpoint to emit structured logs via the logger instead of raw console.
  6. Add tests/logging.test.ts that verifies a request/response cycle emits a log line with the expected fields.

Acceptance Criteria

  • Request/response logging middleware captures method, path, status, duration, and optional user context.
  • Winston is configured with a JSON formatter and at least console + file transports; log level is env-configurable.
  • At least 80% of console.* statements in middleware and auth paths are replaced with logger calls.
  • Health-check endpoint emits structured logs (no raw console.error or ad-hoc Date.now() prints).
  • Rate-limit middleware uses the centralized logger; no console.log left in the hot path.
  • Log output is valid JSON and includes timestamp, level, message, and request context fields.
  • Tests pass and a new logging test verifies the end-to-end request log.

Out of Scope

  • Adding APM/distributed tracing (OpenTelemetry) — separate effort.
  • Shipping logs to an external aggregator (Datadog, Loki, etc.).

Suggested Labels

enhancement, observability, developer-experience

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions