Before you can view the trace data of your application in the Tracing Analysis console, you must use a client to submit the trace data to Tracing Analysis. This topic describes how to use OpenTelemetry SDK for Python to submit the trace data of a Python application.

Prerequisites

To obtain an endpoint of OpenTelemetry, perform the following steps:
  1. Log on to the Tracing Analysis console.
  2. In the left-side navigation pane, click Cluster Configurations. Then, click the Access point information tab.
  3. In the top navigation bar, select a region. In the Cluster Information section, turn on Show Token.
  4. In the Client section, click OpenTelemetry.
    Obtain an endpoint of OpenTelemetry in the Related Information column of the table in the lower part. Endpoint of OpenTelemetry
    Note If your application is deployed in an Alibaba Cloud production environment, use a private endpoint. Otherwise, use a public endpoint.

Sample code

Download the sample code from python-opentelemetry-demo.

Method 1: Automatically instrument the application

  1. Download the required packages:
    pip install opentelemetry-api
    pip install opentelemetry-sdk
    pip install opentelemetry-exporter-otlp
  2. Configure the OpenTelemetry initialization code in the manual.py file.
    • Replace the <endpoint> parameter in the <token> section of the code with the endpoint information obtained in Prerequisites.
    • Replace the <service-name> parameter and the <host-name> parameter in the code with the actual service name and hostname.
    from opentelemetry import trace, baggage
    from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as OTLPSpanGrpcExporter
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as OTLPSpanHttpExporter
    from opentelemetry.sdk.resources import SERVICE_NAME, Resource, HOST_NAME
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    
    def init_opentelemetry():
        # Set the service name and hostname.
        resource = Resource(attributes={
            SERVICE_NAME: "<service-name>",
            HOST_NAME: "<host-name>"
        })
        # Use the GRPC protocol to submit data.
        span_processor = BatchSpanProcessor(OTLPSpanGrpcExporter(
            endpoint="<endpoint>",
            headers=("Authentication=<token>")
        ))
        # Use the HTTP protocol to submit data.
        # span_processor = BatchSpanProcessor(OTLPSpanHttpExporter(
        #     endpoint="<endpoint>",
        # ))
        trace_provider = TracerProvider(resource=resource, active_span_processor=span_processor)
        trace.set_tracer_provider(trace_provider)
                            
  3. Create a span:
    tracer=trace.get_tracer (__name__) # Obtain the tracer.
    with tracer.start_as_current_span("child_span") as child_span: # Create a span named child_span.
        print("hello world")
  4. Use OpenTelemetry Baggage API to propagate the custom tags of the service.
    When you create the baggage_parent_span span, set the attributes parameter to configure attributes.
    def baggage_and_attribute_usage():
        tracer = trace.get_tracer(__name__)
        global_ctx=baggage.set_baggage ("key", "value_from_global_ctx")  # Use Baggage API to transfer data between different spans.
        with tracer.start_as_current_span(name='baggage_parent_span', attributes={'attribute_key': 'value'}) as baggage_parent_span:
            parent_ctx = baggage.set_baggage("key", "value_from_parent_ctx")
            with tracer.start_as_current_span(name='baggage_child_span', context=parent_ctx) as baggage_child_span:
                child_ctx = baggage.set_baggage("key", "value_from_child_ctx")
    
        # Obtain the values of keys in different contexts.
        print(baggage.get_baggage("key", global_ctx))
        print(baggage.get_baggage("key", parent_ctx))
        print(baggage.get_baggage("key", child_ctx))
    View the complete sample code
    from opentelemetry import trace, baggage
    from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as OTLPSpanGrpcExporter
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as OTLPSpanHttpExporter
    from opentelemetry.sdk.resources import SERVICE_NAME, Resource, HOST_NAME
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    
    def inner_method():
        tracer = trace.get_tracer(__name__)
        with tracer.start_as_current_span("child_span") as child_span:
            print("hello world")
    
    
    def outer_method():
        tracer = trace.get_tracer(__name__)
        with tracer.start_as_current_span("parent_span") as parent_span:
            inner_method()
    
    def baggage_and_attribute_usage():
        tracer = trace.get_tracer(__name__)
        global_ctx=baggage.set_baggage ("key", "value_from_global_ctx")  # Use Baggage API to transfer data between different spans.
        with tracer.start_as_current_span(name='baggage_parent_span', attributes={'attribute_key': 'value'}) as baggage_parent_span:
            parent_ctx = baggage.set_baggage("key", "value_from_parent_ctx")
            with tracer.start_as_current_span(name='baggage_child_span', context=parent_ctx) as baggage_child_span:
                child_ctx = baggage.set_baggage("key", "value_from_child_ctx")
    
        print(baggage.get_baggage("key", global_ctx))
        print(baggage.get_baggage("key", parent_ctx))
        print(baggage.get_baggage("key", child_ctx))
    
    
    
    def init_opentelemetry():
        # Set the service name and hostname.
        resource = Resource(attributes={
            SERVICE_NAME: "<service-name>",
            HOST_NAME: "<host-name>"
        })
        # Use the GRPC protocol to submit data.
        span_processor = BatchSpanProcessor(OTLPSpanGrpcExporter(
            endpoint="<endpoint>",
            headers=("Authentication=<token>")
        ))
        # Use the HTTP protocol to submit data.
        # span_processor = BatchSpanProcessor(OTLPSpanHttpExporter(
        #     endpoint="<endpoint>",
        # ))
        trace_provider = TracerProvider(resource=resource, active_span_processor=span_processor)
        trace.set_tracer_provider(trace_provider)
    
    
    if __name__ == '__main__':
        init_opentelemetry()
        outer_method()
        baggage_and_attribute_usage()
  5. Run the program:
    python manual.py

Method 2: Implement automatic instrumentation in a Django application

  1. Download the required packages:
    pip install django
    pip install opentelemetry-sdk
    pip install opentelemetry-instrumentation-django
    pip install requests
  2. Create a HelloWorld application.
    1. Create a helloworld folder in the project:
      python manage.py startapp helloworld
    2. Add the following code to the helloworld/views.py file:
      from django.http import HttpResponse
      from datetime import datetime
      
      # Create your views here.
      def hello_world_view(request):
          result = "Hello World! Current Time =" + str(get_time())
          return HttpResponse(result)
      
      def get_time():
          now = datetime.now()
          return now.strftime("%H:%M:%S")
    3. Add the following code to the helloworld/urls.py file:
      from django.urls import path
      
      from . import views
      
      urlpatterns = [
          path('', views.hello_world_view, name='helloworld')
      ]
    4. Modify the AutoAndManualDemo/urls.py file and add the path of the helloworld file:
      from django.contrib import admin
      from django.urls import path, include
      
      urlpatterns = [
          path('admin/', admin.site.urls),
          path('helloworld/', include('helloworld.urls')),
      ]
  3. Modify the contents of the manage.py file.
    1. Install the following package:
      from opentelemetry.instrumentation.django import DjangoInstrumentor
    2. Add the following code to the main method:
      DjangoInstrumentor().instrument()
  4. Run the project:
    python manage.py runserver --noreload
    Note The --noreload parameter is used to prevent the manage.main method from executing twice.
    If a ImportError(symbol not found in flat namespace '_CFRelease') error occurs on the run time, run the following command to download the Grpcio package and run the project again:
    pip install grpcio

Method 3: Combine automatic instrumentation with manual instrumentation

If you want to use OpenTelemetry to enable automatic instrumentation for custom services, perform the following steps based on Method 2:

  1. Download the following package:
    pip install opentelemetry-exporter-otlp
  2. Configure the OpenTelemetry initialization code in the manual.py file.
    • Replace the <endpoint> parameter in the <token> section of the code with the endpoint information obtained in Prerequisites based on the protocol.
    • Replace the <service-name> parameter and the <host-name> parameter in the code with the actual service name and hostname.
    from opentelemetry import trace
    from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter  # Use the GRPC protocol to submit data.
    # from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter # Use the HTTP protocol to submit data.
    from opentelemetry.sdk.resources import SERVICE_NAME, Resource, HOST_NAME
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
    
    
    
    resource = Resource(attributes={
            SERVICE_NAME: "<service-name>",
            HOST_NAME: "<host-name>"
    })
    trace.set_tracer_provider(TracerProvider(resource=resource))
    trace.get_tracer_provider().add_span_processor(
        BatchSpanProcessor(OTLPSpanExporter(
            endpoint="<endpoint>",
            headers="Authentication=<token>" # The headers parameter is required only for the gRPC protocol.
    )))  # Use OTLPSpanExporter to submit trace data.
    trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))  # Obtain trace data in the Tracing Analysis console.
  3. Modify the content of the helloworld/views.py file.
    Obtain the tracer, create a span, and then configure the span name:
    from django.http import HttpResponse
    from opentelemetry import trace
    from datetime import datetime
    
    
    # Create your views here.
    def hello_world_view(request):
        tracer = trace.get_tracer(__name__)
    
        with tracer.start_as_current_span("hello_world_span") as hello_world_span:
            result = "Hello World! Current Time =" + str(get_time())
            return HttpResponse(result)
    
    
    def get_time():
        now = datetime.now()
        tracer = trace.get_tracer(__name__)
        # Create a new span.
        with tracer.start_as_current_span("time_span") as time_span:
            return now.strftime("%H:%M:%S")
  4. Run the project:
    python manage.py runserver --noreload
    Note The --noreload parameter is used to prevent the manage.main method from executing twice.
    If a ImportError(symbol not found in flat namespace '_CFRelease') error occurs on the run time, run the following command to download the Grpcio package and run the project again:
    pip install grpcio
  5. Visit 127.0.0.1:8000/helloworld in a browser, to submit trace data to the Tracing Analysis console.

View monitoring data

On the Applications page in the Tracing Analysis console, click the name of the application. On the page that appears, view the trace data.