All Products
Search
Document Center

Application Real-Time Monitoring Service:Use Jaeger to report trace data from a Python application

Last Updated:Sep 08, 2026

Instrument a Python application with the Jaeger client to report trace data to Managed Service for OpenTelemetry. After you connect, the ARMS console displays the application topology, traces, abnormal and slow transactions, and SQL analysis.

Important

For advanced features and tracing capabilities, we recommend connecting your application to Managed Service for OpenTelemetry using the OpenTelemetry protocol.

Our detailed OpenTelemetry integration guides and best practices help you get started with Managed Service for OpenTelemetry. For more information, see Connect an application.

How it works

Jaeger supports two data reporting architectures:

  • Without the Jaeger agent: The Jaeger client sends trace data directly to the Managed Service for OpenTelemetry backend.

image
  • With the Jaeger agent: The Jaeger client sends trace data to a locally running Jaeger agent, which forwards it to the backend over gRPC.

image

Constraints

  • The Python Jaeger client (v1.25) can only report trace data through the Jaeger agent, not over HTTP. See Client Library Features.

  • The client communicates with the agent over UDP, which does not guarantee delivery. To minimize data loss, run both on the same host.

Step 1: Start the Jaeger agent

  1. Pull the Jaeger agent image:

       docker pull jaegertracing/jaeger-agent:1.25
  2. Start the Jaeger agent container: Replace the following placeholders with values from the Cluster Configurations page:

    PlaceholderDescription
    <endpoint>gRPC endpoint of Managed Service for OpenTelemetry
    <auth>Authentication token
       docker run -d --name jaeger-agent \
         -p 5775:5775/udp \
         -p 6831:6831/udp \
         -p 6832:6832/udp \
         -p 5778:5778/tcp \
         jaegertracing/jaeger-agent:1.25 \
         --reporter.type=grpc \
         --reporter.grpc.host-port=<endpoint> \
         --agent.tags=<auth>
  3. Verify the agent is running: A status of Up confirms the agent started. If the container is not running, check the logs:

       docker ps --filter name=jaeger-agent
       docker logs jaeger-agent

Step 2: Instrument the Python application

  1. Install the required packages. Save the following to a requirements.txt file: Then install the packages:

       certifi==2021.5.30
       charset-normalizer==2.0.4
       idna==3.2
       jaeger-client==4.6.0
       opentracing==2.4.0
       requests==2.26.0
       six==1.16.0
       threadloop==1.0.2
       thrift==0.13.0
       tornado==6.1
       urllib3==1.26.6
       pip install -r requirements.txt
  2. Create a Python file (for example, tracing_demo.py) with the following code: Key configuration parameters:

    ParameterValueDescription
    sampler.typeconstSamples every trace. For production, use probabilistic with a lower param value.
    sampler.param1With const type, 1 means sample all traces, 0 means sample none.
    reporting_host127.0.0.1Address of the Jaeger agent. Use 127.0.0.1 when running on the same host.
    reporting_port6831UDP port the Jaeger agent listens on for spans.
    service_namemytest3The name that identifies your application in the ARMS console.
       import logging
       import time
       from jaeger_client import Config
    
    
       def construct_span(tracer):
           with tracer.start_span('AliyunTestSpan') as span:
               span.log_kv({'event': 'test message', 'life': 42})
               print("tracer.tags: ", tracer.tags)
               with tracer.start_span('AliyunTestChildSpan', child_of=span) as child_span:
                   span.log_kv({'event': 'down below'})
               return span
    
    
       if __name__ == "__main__":
           log_level = logging.DEBUG
           logging.getLogger('').handlers = []
           logging.basicConfig(format='%(asctime)s %(message)s', level=log_level)
    
           config = Config(
               config={
                   'sampler': {
                       'type': 'const',  # Sample every trace. Use 'probabilistic' in production.
                       'param': 1,
                   },
                   'local_agent': {
                       # The Jaeger agent address. Keep this as 127.0.0.1 when the agent
                       # runs on the same host, which is recommended for UDP reliability.
                       'reporting_host': '127.0.0.1',
                       'reporting_port': 6831,
                   },
                   'logging': True,
               },
               service_name="mytest3",  # Replace with your application name.
               validate=True
           )
    
           # Initialize the tracer. This also sets opentracing.tracer.
           tracer = config.initialize_tracer()
    
           span = construct_span(tracer)
    
           # Allow the IOLoop to flush buffered spans before closing.
           # See: https://github.com/jaegertracing/jaeger-client-python/issues/50
           time.sleep(2)
           tracer.close()
  3. Run the file: On successful initialization, the debug output shows the tracer configuration and confirms spans are being reported to the Jaeger agent.

       python tracing_demo.py

Verify trace data in the console

  1. Log on to the ARMS console. In the left-side navigation pane, choose Application Monitoring > Applications.

  2. On the Applications page, select a region in the top navigation bar and click your application name.

    Note

    If the image icon appears in the Language column, the application uses Application Monitoring. A hyphen (-) indicates Managed Service for OpenTelemetry.

  3. In the Application Overview section, check the key performance metrics and topology.

    The Overview Analysis tab of the Application Overview page shows the following core metrics:

    • Total Requests: the number of requests, with week-over-week and day-over-day changes.

    • Average Response Time: the response time and its trend.

    • Exceptions: the number of abnormal requests.

    • Span Count: the total number of spans in the trace.

    Below these metrics, the Services Provided and Dependent Services areas each show trend line charts for request volume and average response time.

  4. In the left-side navigation pane, click Application Details. The Overview tab shows the application summary.

    On the Application Details page, the Overview tab is displayed by default. It shows the application topology and three monitoring charts: Requests, response time, and Exceptions. The left-side service list shows the response time, request count, and exception count of each interface.

  5. Click the Traces tab to view the trace data reported from your application.

Troubleshoot missing trace data

If trace data does not appear in the console after you run your application, check the following:

IssueAction
Jaeger agent not runningRun docker ps --filter name=jaeger-agent and verify the status shows Up. Check agent logs with docker logs jaeger-agent.
Incorrect endpoint or tokenVerify the <endpoint> and <auth> values match the Cluster Configurations page. Restart the agent after correcting them.
Agent and client on different hostsThe Jaeger client sends data over UDP, which is unreliable across hosts. Run the agent on the same host as the application and set reporting_host to 127.0.0.1.
Spans not flushedMake sure time.sleep(2) is called before tracer.close() to allow the IOLoop to flush buffered spans.
Network connectivityVerify that the host can reach the Managed Service for OpenTelemetry endpoint on the configured gRPC port.

Common Jaeger operations

The following examples cover common Jaeger tracing operations. For more details, see Getting Started.

Create a tracer

from jaeger_client import Config

def init_jaeger_tracer(service_name='your-app-name'):
    config = Config(config={}, service_name=service_name)
    return config.initialize_tracer()

Create and finish spans

# Start a root span (no parent).
tracer.start_span('TestSpan')

# Start a child span.
tracer.start_span('ChildSpan', child_of=span)

# Finish the span.
span.finish()

Propagate SpanContext across services

# Inject: serialize the SpanContext into a carrier for downstream services.
tracer.inject(
    span_context=span.context, format=Format.TEXT_MAP, carrier=carrier
)

# Extract: deserialize the SpanContext from an incoming request.
span_ctx = tracer.extract(format=Format.TEXT_MAP, carrier={})