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
    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