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.traceIdreq.context['traceId']
What LoggingMiddleware logs
The middleware in src/middleware/LoggingMiddleware.ts prefixes request logs with:
[requestId]when onlyrequestIdis known[requestId trace=<traceId>]when atraceIdis 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.
Recommended header propagation
Incoming requests
- Preserve
x-request-idfrom your edge/load balancer (or set one if missing). - Preserve
traceparent(and optionallytracestate) 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):
requestIdtraceId(optional)methodpath(prefer route templates if available)statusdurationMstenantId(optional; consider privacy)userId(optional; consider privacy)
ZinTrust’s Logger supports redaction and structured formats; prefer that over ad-hoc console.log.
Common pitfalls
- Regenerating IDs mid-request: ensure your own middleware does not overwrite
req.context['requestId']ortraceId. - 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-idandtraceparent. - Leaking secrets: never log tokens, cookies, passwords, or raw Authorization headers.
Quick debugging workflow
- From an error log line, copy the
requestId(andtraceIdif present). - Search your log store for
requestId=<id>. - If
traceIdexists, jump to your tracing backend and open the trace. - Use
/metricsto check latency/error spikes, then pivot back to sampled logs.