Skip to content

Log Correlation ​

Log correlation is the practice of ensuring every log line can be tied to:

  • a single HTTP request
  • a distributed trace (when tracing is enabled)
  • a user/tenant (when appropriate)

In ZinTrust, correlation is built around RequestContext and the HTTP LoggingMiddleware.

Correlation fields ​

requestId ​

requestId is the primary per-request identifier.

Where it comes from:

  • If the client sends x-request-id, ZinTrust uses it.
  • Otherwise ZinTrust generates a UUID.

Where it is stored:

  • RequestContext (the canonical runtime object)
  • req.context['requestId'] (mirrored for easy access)

traceId ​

traceId is the distributed trace identifier.

Where it comes from:

  • If the client sends W3C traceparent, ZinTrust extracts the 32-hex trace id.
  • Otherwise, if the client sends x-trace-id, ZinTrust uses it.
  • Otherwise, if microservices tracing has populated req.context.trace.traceId, ZinTrust uses it.
  • Otherwise, if req.context['traceId'] is already set (by middleware or an upstream adapter), ZinTrust uses it.

Where it is stored:

  • RequestContext.traceId
  • req.context['traceId']

What LoggingMiddleware logs ​

The middleware in src/middleware/LoggingMiddleware.ts prefixes request logs with:

  • [requestId] when only requestId is known
  • [requestId trace=<traceId>] when a traceId is available

It logs a start and a completion line:

  • ↓ METHOD /path
  • ↑ METHOD /path STATUS DURATIONms

This pattern makes it easy to find all logs for a specific request, and then jump to its trace.

Incoming requests ​

  • Preserve x-request-id from your edge/load balancer (or set one if missing).
  • Preserve traceparent (and optionally tracestate) from OpenTelemetry-enabled clients/edges.

Outgoing requests ​

If you use ZinTrust’s OpenTelemetry integration, outgoing HTTP calls can propagate trace context. See docs/opentelemetry.md.

Suggested logging shape ​

Correlation is strongest when your logs are structured and always include the same keys.

Recommended fields (at minimum):

  • requestId
  • traceId (optional)
  • method
  • path (prefer route templates if available)
  • status
  • durationMs
  • tenantId (optional; consider privacy)
  • userId (optional; consider privacy)

ZinTrust’s Logger supports redaction and structured formats; prefer that over ad-hoc logging.

Common pitfalls ​

  • Regenerating IDs mid-request: ensure your own middleware does not overwrite req.context['requestId'] or traceId.
  • Cardinality explosion: do not put raw user identifiers into metric labels; prefer logs/traces for high-cardinality identifiers.
  • Proxy stripping headers: some proxies drop unknown headers; explicitly allow-list x-request-id and traceparent.
  • Leaking secrets: never log tokens, cookies, passwords, or raw Authorization headers.

Quick debugging workflow ​

  1. From an error log line, copy the requestId (and traceId if present).
  2. Search your log store for requestId=<id>.
  3. If traceId exists, jump to your tracing backend and open the trace.
  4. Use /metrics to check latency/error spikes, then pivot back to sampled logs.

Released under the MIT License.