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 freeStructured Logging in Django with LogFlow
Set up structured logging in Django to capture request logs, errors, and Celery tasks in LogFlow — with full search and alerting.
Kubernetes Logging with LogFlow
Collect structured logs from your Kubernetes pods and send them to LogFlow with service, namespace, and pod metadata automatically attached.
Add Structured Logging to FastAPI in 10 Minutes
Set up structured JSON logging in FastAPI and ship logs to LogFlow with automatic request context and error tracking.