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.

Steps to receive Jaeger traces with the OpenTelemetry Collector:

  1. Confirm the Collector build includes the jaeger receiver and debug exporter.
    $ 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.

  2. Open the active Collector configuration file.
    $ sudo vi /etc/otelcol/config.yaml
  3. Add a Jaeger receiver, batch processor, and debug exporter.
    /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.

  4. Validate the Collector configuration.
    $ sudo otelcol validate --config=/etc/otelcol/config.yaml

    No output and exit status 0 mean the configuration parsed successfully.

  5. Restart the otelcol service.
    $ sudo systemctl restart otelcol
  6. Confirm the Jaeger compact receiver started.
    $ 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.

  7. Create a temporary virtual environment for the smoke-test sender.
    $ python3 -m venv /tmp/jaeger-smoke
  8. Install the temporary Jaeger client packages.
    $ /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.

  9. Create the temporary Jaeger sender script.
    /tmp/send-jaeger-trace.py
    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.

  10. Send the Jaeger test traces.
    $ /tmp/jaeger-smoke/bin/python /tmp/send-jaeger-trace.py
    sent three Jaeger thrift_compact traces to collector.example.net:6831
  11. Check the Collector log for the received spans.
    $ 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.

  12. Remove the temporary smoke-test files.
    $ rm -rf /tmp/jaeger-smoke /tmp/send-jaeger-trace.py