Configuring OpenTelemetry SDK with W3C Trace Context Propagator and BatchSpanProcessor for Production Export
Learn how to configure the W3C Trace Context propagator and BatchSpanProcessor in OpenTelemetry SDK, verify trace continuity, and handle export failures.
11 Jan 2026, 03:13 UTC

Desired Outcome
You want every exported span to carry the W3C Trace Context header so that traces continue across service boundaries, and you want the SDK to batch spans for efficient backend load rather than sending each span individually.
Prerequisites
- OpenTelemetry SDK version 1.24.0 or newer installed in your language runtime.
- Access to the host or container where the SDK is initialized, with permission to edit configuration files or source code.
- An OpenTelemetry Collector or backend endpoint reachable via gRPC or HTTP/Protobuf.
- Network permissions to open the exporter port.
Procedure
Initialize the SDK with resource attributes
Set service.name and service.version once during SDK creation so every span carries service identity.
import opentelemetry.sdk.resources as resources
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.propagate import set_global_textmap
from opentelemetry.propagators.w3c_tracecontext import W3CTraceContextPropagator
resource = resources.Resource.create({
'service.name': 'my-service',
'service.version': '1.0.0',
})
provider = TracerProvider(resource=resource)
set_global_textmap(W3CTraceContextPropagator())
batch_processor = BatchSpanProcessor(
exporter=OTLSpanExporter(endpoint="collector.example.com:4317", insecure=True),
scheduled_delay_millis=5000,
max_export_batch_size=512,
max_queue_size=10000,
export_timeout_millis=5000,
)
provider.add_span_processor(batch_processor)
tracer = provider.get_tracer(__name__)
The placeholders exporter and endpoint must be replaced with your actual collector address and protocol settings.
Configure the exporter
Choose gRPC or HTTP. Example for gRPC:
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
otlp_exporter = OTLPSpanExporter(endpoint="collector.example.com:4317", insecure=True)
If you prefer HTTP/Protobuf, replace the exporter with OTLPProtobufSpanExporter and adjust the endpoint accordingly.
Verify configuration
Run a test request between two instrumented services and confirm that the downstream span shares the upstream traceId and that the HTTP header traceparent is present.
- Start a client that creates a span.
- Make an HTTP call to a server that also creates a span.
- Inspect the server logs or use a collector UI to confirm the
traceparentheader was forwarded.
Expected Checks
- Confirm that the SDK logs indicate "BatchSpanProcessor started" and show periodic "Exporting X spans" messages at the scheduled interval.
- Monitor the collector’s queue length; it should stay below the
max_queue_sizethreshold. - Compare the number of exported spans with the number of created spans under load; no unexpected drops should occur.
Recovery Options
If the exporter becomes unreachable:
- Inspect SDK export error callbacks or logs for "Export failed" messages.
- Restart the collector or fix network connectivity, then allow the SDK to re‑queue spans.
- For short‑lived processes, temporarily switch to SimpleSpanProcessor to avoid loss when the process exits before the export cycle completes.
Rollback is not required because configuration changes are applied at process start; redeploy the updated code or restart the service to revert.
Limitations
BatchSpanProcessor may drop spans if the process exits before the export cycle finishes, especially in serverless environments. Use a synchronous flush or SimpleSpanProcessor in those cases.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.