Log correlation links your log records to the trace that was active when the log was emitted. In Datadog, this lets you jump directly from a log entry to the full distributed trace, and vice versa.
How log correlation works
dd-trace injects trace identifiers into log records as structured fields:
dd.trace_id — The current trace ID
dd.span_id — The current span ID
dd.service — The service name
dd.env — The environment
dd.version — The application version
The Datadog log pipeline uses these fields to correlate logs with traces when both are forwarded to Datadog.
Automatic log injection
For supported logging libraries (pino, bunyan, winston), dd-trace can inject trace context automatically. Enable it with the DD_LOGS_INJECTION environment variable or the logInjection init option.
Environment variable
Programmatic
DD_LOGS_INJECTION=true node app.js
const tracer = require('dd-trace').init({
logInjection: true
})
require('dd-trace').init() must be called before importing your logging library. Automatic injection patches the logger at import time.
With automatic injection enabled, trace fields are added to every log record without any code changes to your logging calls.
Logger examples
require('dd-trace').init({ logInjection: true })
const pino = require('pino')
const logger = pino()
// dd-trace automatically injects dd.trace_id, dd.span_id, etc.
logger.info('user logged in')
// Output: { "level": 30, "dd": { "trace_id": "...", "span_id": "...", ... }, "msg": "user logged in" }
Manual log injection
If your logging library is not automatically supported, or you need finer control, inject trace context manually using tracer.scope().active().
const tracer = require('dd-trace').init()
function getLogContext() {
const span = tracer.scope().active()
if (!span) return {}
const context = span.context()
return {
dd: {
trace_id: context.toTraceId(),
span_id: context.toSpanId(),
service: tracer._service,
env: tracer._env,
version: tracer._version
}
}
}
// Use with any logger
console.log(JSON.stringify({
msg: 'user logged in',
...getLogContext()
}))
Getting individual fields
Access specific trace identifiers from the active span context:
const tracer = require('dd-trace').init()
function handle(req, res) {
const span = tracer.scope().active()
if (span) {
const context = span.context()
const traceId = context.toTraceId() // trace ID as string
const spanId = context.toSpanId() // span ID as string
// Add to a custom logger or structured log payload
myLogger.info({
message: 'Handling request',
'dd.trace_id': traceId,
'dd.span_id': spanId
})
}
}
For Datadog to correlate logs with traces, log records must be sent as JSON and include the trace fields in one of these formats:
Nested under dd key (preferred):
{
"msg": "user logged in",
"dd": {
"trace_id": "7901582778751081715",
"span_id": "4809171762464685135",
"service": "my-service",
"env": "production",
"version": "1.2.3"
}
}
At the top level:
{
"msg": "user logged in",
"dd.trace_id": "7901582778751081715",
"dd.span_id": "4809171762464685135",
"dd.service": "my-service",
"dd.env": "production",
"dd.version": "1.2.3"
}
Ensure logs are shipped to Datadog using the Datadog Agent or a supported log forwarder. The log pipeline processes the dd.trace_id field to create the correlation link in the Datadog UI.
Confirming log correlation is working
To verify that trace IDs are appearing in logs, run your application with a request and check the log output for dd.trace_id or the dd object. In the Datadog UI, open a log entry and look for the “View Trace” button, which appears when correlation is working.