patterntypescriptModerate
Distributed tracing with OpenTelemetry: propagate trace context across service boundaries
Viewed 0 times
@opentelemetry/sdk-node ^0.50
opentelemetrydistributed tracingtrace contextjaegertempootelspanw3c trace-contextcorrelation id
Problem
A request touches five microservices. Something is slow but logs from individual services show nothing obviously wrong. There is no way to correlate log lines across services or see the end-to-end call tree.
Solution
Instrument each service with OpenTelemetry SDK. Propagate trace context in HTTP headers (W3C Trace-Context) or Kafka message headers. Export spans to Jaeger or Tempo.
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter({ url: 'http://otel-collector:4318/v1/traces' }),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();Why
A single trace ID ties together every span across every service for a single request. Waterfall views reveal exactly which service added latency and why.
Gotchas
- Auto-instrumentation covers HTTP and DB but misses Kafka and custom code — add manual spans for business-critical operations
- Always propagate context through async boundaries (setTimeout, event emitters) using context.with()
- Head-based sampling at 1% is a good start — switch to tail-based sampling (Tempo/OpenTelemetry Collector) when you need to capture 100% of errors
- Do not log sensitive data in span attributes — traces may be stored long-term
Code Snippets
Manual span around a critical business operation
import { trace, context, propagation } from '@opentelemetry/api';
// Manual span for a critical business operation
const tracer = trace.getTracer('order-service');
const span = tracer.startSpan('processPayment');
context.with(trace.setSpan(context.active(), span), async () => {
try {
await paymentGateway.charge(order);
span.setStatus({ code: SpanStatusCode.OK });
} catch (err) {
span.recordException(err as Error);
span.setStatus({ code: SpanStatusCode.ERROR });
throw err;
} finally {
span.end();
}
});Context
Any microservices system where debugging cross-service latency or errors is needed
Revisions (0)
No revisions yet.