You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[DOCS-11944] Add Node.js examples and non-JSON log correlation for OTel traces
Add a Node.js tab to the trace context injection section showing
Winston auto-instrumentation, and add a new sub-section for
correlating non-JSON logs with a manual Winston formatter example
and regex_parser Collector config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@@ -39,7 +39,7 @@ To correlate OpenTelemetry traces and logs in Datadog, you must:
39
39
40
40
### 1. Inject trace context into your logs
41
41
42
-
The following examples for Go and Java use logging bridges. These bridges intercept logs from common logging libraries (such as `zap`and `Logback`), convert them into the OpenTelemetry log data model, and forward them to the OpenTelemetry SDK. This process automatically enriches the logs with the active trace context.
42
+
The following examples use logging bridges or auto-instrumentation. These tools intercept logs from common logging libraries (such as `zap`, `Logback`, and `Winston`), convert them into the OpenTelemetry log data model, and forward them to the OpenTelemetry SDK. This process automatically enriches the logs with the active trace context.
43
43
44
44
For complete, working applications, see the [Datadog OpenTelemetry Examples repository][2].
45
45
@@ -88,6 +88,51 @@ For complete, working example configuration, see the [full Java example in the e
For Node.js, use the `@opentelemetry/instrumentation-winston` package with [Winston][300] to automatically inject trace context into your logs. Install the required packages:
After the instrumentation is registered, any Winston logger automatically includes `trace_id`, `span_id`, and `trace_flags` fields when a log is emitted within an active trace:
117
+
118
+
```javascript
119
+
constwinston=require('winston');
120
+
121
+
constlogger=winston.createLogger({
122
+
level:'info',
123
+
format:winston.format.json(),
124
+
transports: [newwinston.transports.Console()],
125
+
});
126
+
127
+
// Logs emitted within a traced context automatically include trace_id and span_id
128
+
logger.info('Processing user request');
129
+
```
130
+
131
+
The same approach works with [Pino][301] using the `@opentelemetry/instrumentation-pino` package.
132
+
133
+
[300]: https://github.com/winstonjs/winston
134
+
[301]: https://github.com/pinojs/pino
135
+
91
136
{{% /tab %}}
92
137
{{< /tabs >}}
93
138
@@ -141,25 +186,27 @@ The OpenTelemetry Collector and the Datadog Agent can both receive OTLP logs.
141
186
exporters: [datadog]
142
187
```
143
188
144
-
#### Scrape logs from files
189
+
#### Scrape logs from files
145
190
146
191
This approach is useful if you have a requirement to keep local log files for compliance or other tooling.
147
192
148
-
For Datadog to correlate your logs and traces, your JSON log files must contain specific fields formatted correctly:
193
+
For Datadog to correlate your logs and traces, your log files must contain specific fields formatted correctly:
149
194
- `trace_id`: The ID of the trace. It must be a 32-character lowercase hexadecimal string.
150
-
- `span_id`: The ID of the span. It must be a 16-character lowercase hexadecimal string.
195
+
- `span_id`: The ID of the span. It must be a 16-character lowercase hexadecimal string.
151
196
152
197
The OpenTelemetry SDK typically provides these in a raw format (such as an integer or byte array), which must be formatted into hexadecimal strings without any <code>0x</code> prefix.
153
198
199
+
##### JSON logs
200
+
154
201
1. **Configure your Application to Output JSON Logs**: Use a standard logging library to write logs as JSON to a file or `stdout`. The following Python example uses the standard `logging` library.
155
-
2. **Manually Inject Trace Context**: In your application code, retrieve the current span context and add the `trace_id` and `span_id` to your log records. The following Python example shows how to create a custom logging.Filter to do this automatically:
202
+
2. **Manually Inject Trace Context**: In your application code, retrieve the current span context and add the `trace_id` and `span_id` to your log records. The following Python example shows how to create a custom `logging.Filter` to do this automatically:
156
203
157
204
```python
158
205
import logging
159
206
import sys
160
207
from opentelemetry import trace
161
208
from pythonjsonlogger import jsonlogger
162
-
209
+
163
210
# 1. Create a filter to inject trace context
164
211
class TraceContextFilter(logging.Filter):
165
212
def filter(self, record):
@@ -169,25 +216,25 @@ The OpenTelemetry SDK typically provides these in a raw format (such as an integ
logger.info("Processing user request with trace context.")
189
236
```
190
-
237
+
191
238
3. **Configure the Collector to Scrape Log Files**: In your Collector's `config.yaml`, enable the `filelog` receiver. Configure it to find your log files and parse them as JSON.
192
239
```yaml
193
240
receivers:
@@ -197,14 +244,77 @@ The OpenTelemetry SDK typically provides these in a raw format (such as an integ
197
244
- type: json_parser
198
245
# The timestamp and severity fields should match your JSON output
199
246
timestamp:
200
-
parse_from: attributes.asctime
247
+
parse_from: attributes.asctime
201
248
layout: '%Y-%m-%d %H:%M:%S,%f'
202
249
severity:
203
250
parse_from: attributes.levelname
204
251
# ... your logs pipeline ...
205
252
```
206
253
207
-
This manual approach gives you full control over the log format, ensuring it is clean and easily parsable by the Collector or Datadog Agent.
254
+
##### Non-JSON logs
255
+
256
+
If your application outputs logs in a plain text or key-value format instead of JSON, you can still correlate them with traces. You need to manually inject the trace context into the log string and configure the Collector to extract it using a `regex_parser`.
257
+
258
+
The following Node.js example uses Winston with a custom formatter to inject `trace_id` and `span_id` into a plain text log line:
0 commit comments