Docs » µAPM Instrumentation Guide » Send Traces From a Python Application to SignalFx

Send Traces From a Python Application to SignalFx 🔗

Important

The original µAPM product, released in 2019, is now called µAPM Previous Generation (µAPM PG). In the documentation, µAPM now refers to the product released on March 31, 2020.

If you are using µAPM Previous Generation (µAPM PG), see µAPM PG Instrumentation Guide.

Automatically instrument a Python application to capture and send traces to SignalFx with the SignalFx Python Tracing Library. The SignalFx Python Tracing Library uses OpenTracing API 2.0 to instrument a Python application. To set up instrumentation, see the SignalFx Python Tracing Library on GitHub.

Configure the SignalFx Python Tracing Library to send traces to a Smart Agent. The Smart Agent forwards data to a µAPM ingest endpoint in SignalFx. Configure the Smart Agent to add tags to identify spans that belong to specific hosts or microservices. If you want to configure instrumentation for an application and can’t deploy a Smart Agent, you can use the SignalFx Python Tracing Library to send traces directly to an OpenTelemetry Collector or µAPM ingest endpoint in SignalFx instead. For more information about deploying a Smart Agent, see Installing the SignalFx Smart Agent.

Optionally, deploy an OpenTelemetry Collector between a Smart Agent or instrumented code and the µAPM ingest endpoint. The OpenTelemetry Collector supports protocols the Smart Agent doesn’t support and allows for larger retry buffers to prevent packet loss. For more information about deploying an OpenTelemetry Collector for µAPM, see Deploy an OpenTelemetry Collector for SignalFx µAPM.

Requirements and supported software 🔗

To view a full list of the requirements and supported libraries and frameworks, see Supported Frameworks and Libraries on GitHub.

Add custom instrumentation to a Python application 🔗

After you use the SignalFx Python Tracing Library to instrument a Python application, you can modify traces the library created throughout your application. You can also create new traces.

To view examples of instrumented applications, see Libraries and Framework Examples on GitHub you can download, run, and modify.

import opentracing
from signalfx_tracing import create_tracer

create_tracer(service_name='MyTracedApplication')

def my_function():
    tracer = opentracing.tracer
    with tracer.start_active_span('my_operation') as scope:
        parent_span = scope.span
        parent_span.set_tag('my_tag', 'my_value')
        try:
            # do something

            # create child span
            with tracer.start_active_span('child_operation') as child_scope:
                child_span = child_scope.span
                child_span.set_tag('child_tag', 'child_value')
                try:
                    utility_value = my_utility()
                    child_span.set_tag('my_utility.returned', utility_value)
                except Exception:
                    child_span.set_tag('error', True)
                    child_span.log_kv({'event': 'error',
                                       'error.object': traceback.format_exc()})

        except Exception:
            parent_span.set_tag('error', True)
            parent_span.log_kv({'event':'error',
                                'error.object': traceback.format_exc()})

You can do the same thing without a context manager:

import opentracing
from signalfx_tracing import create_tracer

create_tracer(service_name='MyOtherTracedApplication')

def my_second_function():
    # Handling span creation without a context manager:
    tracer = opentracing.tracer
    scope = tracer.start_active_span('my_other_operation')

    try:
        fn_span = scope.span
        fn_span.log_kv({'event': 'Process initiated'})
        # do something
    except Exception:
        fn_span.set_tag('error', True)
        fn_span.log_kv({'event': 'error',
                        'error.object': traceback.format_exc()})
    finally:
        scope.close()