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.
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.
- 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)