Receiving Jaeger traces with the OpenTelemetry Collector lets a service that still sends Jaeger Thrift data feed the same trace pipeline used by newer OTLP instrumentation. The Collector listens with a Jaeger receiver, converts the spans into the OpenTelemetry trace model, and passes them through the configured processors and exporters.
The compatibility point is the receiver, not a new Jaeger backend. Enable only the protocol that existing clients use, such as thrift_compact on UDP port 6831 for agent-style clients or thrift_http on port 14268 for clients that post Jaeger Thrift over HTTP.
Use the debug exporter first so the Collector log shows the received service name and span count before routing the same pipeline to production storage. Bind the receiver to localhost when only local agents send data, and bind it to a network interface only when remote clients must reach the Collector.
$ otelcol components
buildinfo:
command: otelcol
description: OpenTelemetry Collector
version: 0.154.0
receivers:
##### snipped #####
- name: jaeger
module: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/jaegerreceiver v0.154.0
stability:
traces: Beta
##### snipped #####
exporters:
##### snipped #####
- name: debug
module: go.opentelemetry.io/collector/exporter/debugexporter v0.154.0
stability:
traces: Alpha
The standard otelcol build includes the Jaeger receiver. If your environment runs a custom Collector build, confirm the component list before changing the active service configuration.
$ sudo vi /etc/otelcol/config.yaml
receivers: jaeger: protocols: thrift_compact: endpoint: 0.0.0.0:6831 processors: batch: exporters: debug: verbosity: detailed service: pipelines: traces: receivers: [jaeger] processors: [batch] exporters: [debug]
thrift_compact receives Jaeger agent-style UDP traffic on port 6831. Use thrift_http with an endpoint such as 0.0.0.0:14268 instead when clients send to http://collector.example.net:14268/api/traces. Keep debug only for the smoke test; for a Jaeger backend that accepts OTLP, export with an OTLP exporter instead of the removed legacy Jaeger exporter.
$ sudo otelcol validate --config=/etc/otelcol/config.yaml
No output and exit status 0 mean the configuration parsed successfully.
$ sudo systemctl restart otelcol
$ sudo journalctl -u otelcol --since "5 minutes ago" --no-pager
Jun 18 06:18:39 collector.example.net otelcol[2204]: Starting otelcol...
Jun 18 06:18:39 collector.example.net otelcol[2204]: Starting UDP server for Compact Thrift {"endpoint": "0.0.0.0:6831"}
Jun 18 06:18:39 collector.example.net otelcol[2204]: Everything is ready. Begin running and processing data.
If the log still shows localhost:6831, the endpoint override was not loaded or the service is using a different configuration file.
$ python3 -m venv /tmp/jaeger-smoke
$ /tmp/jaeger-smoke/bin/python -m pip install --quiet --disable-pip-version-check jaeger-client opentracing six
The jaeger-client package is used here only to create a legacy Jaeger-format test span. New application instrumentation should use OpenTelemetry SDKs and export OTLP.
import time from jaeger_client import Config config = Config( config={ "sampler": {"type": "const", "param": 1}, "local_agent": { "reporting_host": "collector.example.net", "reporting_port": 6831, }, "reporter_flush_interval": 1, "logging": False, }, service_name="checkout-api", ) tracer = config.initialize_tracer() for attempt in range(3): with tracer.start_span("checkout") as span: span.set_tag("component", "checkout") span.log_kv({"event": "order-created", "attempt": attempt + 1}) time.sleep(2) tracer.close() print("sent three Jaeger thrift_compact traces to collector.example.net:6831")
Replace collector.example.net with the Collector host name or IP address that the application host can reach.
$ /tmp/jaeger-smoke/bin/python /tmp/send-jaeger-trace.py sent three Jaeger thrift_compact traces to collector.example.net:6831
$ sudo journalctl -u otelcol --since "5 minutes ago" --no-pager
##### snipped #####
Jun 18 06:18:49 collector.example.net otelcol[2204]: Traces {"otelcol.component.id": "debug", "resource spans": 1, "spans": 3}
Jun 18 06:18:49 collector.example.net otelcol[2204]: Resource attributes:
Jun 18 06:18:49 collector.example.net otelcol[2204]: -> service.name: Str(checkout-api)
Jun 18 06:18:49 collector.example.net otelcol[2204]: Span #0
Jun 18 06:18:49 collector.example.net otelcol[2204]: Name : checkout
Jun 18 06:18:49 collector.example.net otelcol[2204]: Attributes:
Jun 18 06:18:49 collector.example.net otelcol[2204]: -> component: Str(checkout)
The debug exporter output proves the Collector received Jaeger-format trace data and passed it through the traces pipeline.
$ rm -rf /tmp/jaeger-smoke /tmp/send-jaeger-trace.py