For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/nodejs.md. A documentation index is available at /llms.txt.

Automatic injection

Enables automatic trace ID injection for bunyan, pino, and winston when structured application loggers are used.

For older tracer versions injection can be enabled the environment variable DD_LOGS_INJECTION=true or by configuring the SDK directly:

// This line must come before importing the logger.
const tracer = require('dd-trace').init({
    logInjection: false
});

If you haven’t done so already, configure the Node.js tracer with DD_ENV, DD_SERVICE, and DD_VERSION. This will provide the best experience for adding env, service, and version (see Unified Service Tagging for more details).

Note: Automatic injection only works for logs formatted as JSON.

Example with Winston and Express

Here’s an example using Winston with Express:

// init tracer first
require('dd-trace').init({ logInjection: true });

const express = require('express');
const { createLogger, format, transports } = require('winston');

const logger = createLogger({
  level: 'info',
  format: format.json(),       // JSON required for auto-injection
  transports: [new transports.Console()]
});

const app = express();

app.get('/hello', (req, res) => {
  logger.info('hello world');  
  // dd.trace_id & dd.span_id will be auto-added
  res.json({ ok: true });
});

const port = process.env.PORT || 3000;
app.listen(port, () => logger.info(`listening on ${port}`));

This would return a log in the format:

{"dd":{"service":"minimal-nodejs-datadog-log-injection","span_id":"8985025821692657638","trace_id":"68c2114800000000669b6b6b2aaf59c9","version":"1.0.0"},"level":"info","message":"hello world"}

Manual injection

If you are using a logging library not supported for automatic injection but are using JSON format, it’s possible to do manual injection directly in your code.

Example using console as the underlying logger:

const tracer = require('dd-trace');
const formats = require('dd-trace/ext/formats');

class Logger {
    log(level, message) {
        const span = tracer.scope().active();
        const time = new Date().toISOString();
        const record = { time, level, message };

        if (span) {
            tracer.inject(span.context(), formats.LOG, record);
        }

        console.log(JSON.stringify(record));
    }
}

module.exports = Logger;

Further Reading