Propagate trace IDs across microservices using OpenTelemetry and connect them to LogFlow's trace correlation and Service Map features.
When a request touches multiple microservices, a trace ID connects all the logs together. Without it, debugging means grep-ing through logs from five different services hoping to reconstruct what happened. With OpenTelemetry and LogFlow, you click one log line and see the entire trace.
Every log that includes a trace_id field becomes part of a trace. In the Logs Explorer, click any log → View trace → LogFlow shows every log from every service that shares that trace ID, sorted chronologically with relative timestamps (+0ms, +23ms, +340ms).
The Service Map uses the same data to draw edges between services automatically.
For Node.js services, install the SDK and HTTP propagator:
npm install @opentelemetry/sdk-node \
@opentelemetry/auto-instrumentations-node \
@opentelemetry/exporter-trace-otlp-http \
@opentelemetry/api
Create src/tracing.js and load it before anything else:
import { NodeSDK } from '@opentelemetry/sdk-node'
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
const sdk = new NodeSDK({
serviceName: process.env.SERVICE_NAME || 'my-service',
traceExporter: new OTLPTraceExporter({
url: 'https://api.getlogflow.com/v1/otlp/traces',
headers: {
Authorization: `Bearer ${process.env.LOGFLOW_API_KEY}`,
},
}),
instrumentations: [getNodeAutoInstrumentations()],
})
sdk.start()
process.on('SIGTERM', () => sdk.shutdown())
Start your app with tracing enabled:
node --import ./src/tracing.js src/index.js
OpenTelemetry sets a trace ID on every request. Extract it and pass it to LogFlow:
import { trace, context } from '@opentelemetry/api'
import { LogFlow } from '@getlogflow/js'
const logger = new LogFlow({
apiKey: process.env.LOGFLOW_API_KEY,
service: process.env.SERVICE_NAME,
})
// Helper: get current trace ID
function getTraceId() {
const span = trace.getActiveSpan()
return span?.spanContext().traceId
}
// Use in your code:
logger.info('Processing payment', {
traceId: getTraceId(),
orderId: order.id,
amount: order.total,
})
When Service A calls Service B, the trace ID must be included in the HTTP request. OpenTelemetry's auto-instrumentation handles this automatically for fetch, axios, and http calls — the W3C traceparent header is added without any extra code.
To extract the trace ID on the receiving side:
import { propagation, context, trace } from '@opentelemetry/api'
// Express middleware to extract incoming trace context
app.use((req, res, next) => {
const extractedContext = propagation.extract(context.active(), req.headers)
context.with(extractedContext, () => {
const span = trace.getActiveSpan()
req.traceId = span?.spanContext().traceId
next()
})
})
Alternatively, skip the SDK and send logs directly via OpenTelemetry's log format. LogFlow accepts OTLP/HTTP at https://api.getlogflow.com/v1/otlp/logs:
curl -X POST https://api.getlogflow.com/v1/otlp/logs \
-H "Authorization: Bearer lf_your_key" \
-H "Content-Type: application/json" \
-d '{
"resourceLogs": [{
"resource": {
"attributes": [{"key": "service.name", "value": {"stringValue": "payment-service"}}]
},
"scopeLogs": [{
"logRecords": [{
"timeUnixNano": "1715000000000000000",
"severityNumber": 9,
"severityText": "INFO",
"body": {"stringValue": "Payment processed"},
"attributes": [
{"key": "traceId", "value": {"stringValue": "abc123"}},
{"key": "orderId", "value": {"stringValue": "ord_456"}}
]
}]
}]
}]
}'
After logs start arriving with trace_id fields:
trace_id field in the details panelThe TraceTimeline shows each log with relative timestamps so you can see exactly where time was spent.
Does LogFlow store OpenTelemetry spans?
Currently LogFlow stores the trace_id and span_id from spans as log attributes and uses them for correlation. Full span storage and waterfall views are on the roadmap.
What if I'm not using OpenTelemetry?
You can add trace IDs manually. Generate a UUID at the entry point of each request and pass it to every log call and downstream HTTP request via a custom header like x-trace-id.
Does the Service Map work without OpenTelemetry?
Yes. The Service Map builds edges from logs that include a service field — it doesn't require OTel. But OTel trace correlation adds the ability to click a node and see its traces.
Free plan available. No credit card required. Up and running in 2 minutes.
Get started freePino Logging Integration
Connect Pino (the fastest Node.js logger) to LogFlow in under 5 minutes.
Winston Logging Integration
Plug LogFlow into an existing Winston setup without changing your application code.
Add Logging to a Next.js App
Set up LogFlow in a Next.js project — capture server errors, API route logs, and frontend exceptions in under 15 minutes.