This topic describes the Tracing Analysis feature of the Python runtime environment.

Background

Alibaba Cloud Tracing Analysis adopts the OpenTracing standard and is compatible with open source communities. Tracing Analysis provides developers of distributed applications with various features. For example, it enables developers to query and diagnose distributed traces, dynamically discover distributed topologies, and summarize application performance in real time.

Function Compute integrates with Tracing Analysis. You can use Jaeger SDK or OpenTelemetry to upload trace information so that you can track function invocation. Tracing Analysis helps you analyze and diagnose performance bottlenecks in a serverless architecture. This improves development and diagnostics efficiency in serverless scenarios.

Overview

You can configure Tracing Analysis in the Function Compute console. For more information, see Enable Tracing Analysis.

After you enable Tracing Analysis for a service, Function Compute automatically records the time consumed in the system. The time includes the cold start time, execution time of an initializer function, and execution time of a function. For more information about system spans in the following figure, see Span name description. Tracing Analysis

You can record the time consumed for the function on the business side. For example, you can record the time taken to access services such as ApsaraDB RDS and Apsara File Storage NAS within the function by using Create custom spans.

Sample code

Tracing Analysis for Function Compute allows you to create custom spans by using OpenTelemetry based on the Jaeger implementation of the OpenTracing specification:

In Python code, you can use the OpenTelemetry SDK to manually tag data and report the data to the Tracing Analysis server. For the complete sample code, see python-tracing-openTelemetry.

In the preceding code:
  • Configure the dependency file requirements.txt in the project directory.
    opentelemetry-api==1.12.0
    opentelemetry-sdk==1.12.0
    opentelemetry-exporter-jaeger==1.12.0
  • Report data to the Tracing Analysis server.
    trace.set_tracer_provider(
        TracerProvider(
            resource=Resource.create({SERVICE_NAME: "my-helloworld-service"})
        )
    )
    tracer = trace.get_tracer(__name__)
    def handler(event, context):
        init_tracer(context.tracing.jaeger_endpoint)
        span_context = get_fc_span(context.tracing.span_context)
        start_my_span(trace.set_span_in_context(NonRecordingSpan(span_context)))
        return 'hello world'
  • Initialize a tracer object to provide accesses to tracers.
    def init_tracer(endpoint):
        jaeger_exporter = JaegerExporter(
            collector_endpoint=endpoint
        )
    
        span_processor = SimpleSpanProcessor(jaeger_exporter)
    
        trace.get_tracer_provider().add_span_processor(span_processor)
  • Get the Context object tracing information and convert it to a SpanContext object.
    def get_fc_span(jaeger_span_context):
        jaeger_span_context_arr = jaeger_span_context.split(":")
        tid = int(jaeger_span_context_arr[0], 16)
        sid = int(jaeger_span_context_arr[1], 16)
    
        span_context = trace.SpanContext(
            trace_id=tid,
            span_id=sid,
            is_remote=True,
            trace_flags=trace.TraceFlags(0x01),
        )
        return span_context
  • Create a tracer and a child span by using the converted context. Each span represents a named and timed continuous execution fragment in the call chain. You can also create child spans based on the span.
    def start_my_span(context):
        with tracer.start_as_current_span(name="fc-operation", context=context):
            time.sleep(0.15)
            with tracer.start_as_current_span("child"):
                time.sleep(0.1)