Skip to content

Tracing

As introduced in [Overview], nanopie provides pluggable solutions for tracing, in the form of tracing handlers. You may add tracing handlers to an endpoint or a service to log the beginning and the end of the processing of a request automatically, or use these handlers separately in your code.

nanopie tracing handlers integrate closely with OpenTelemetry to provide a robust, portable, and industry standard tracing solution. At its core, a tracing handler configures a OpenTelemetry tracer, which traces an operation and exports the trace to its destination.

OpenTelemetryTracingHandler is the foundation for all tracing handlers in nanopie; this handler simply writes the traces to the standard streams in the form of JSON strings. Other tracing handlers extend OpenTelemetryTracingHandler and add the capability of exporting traces to a variety of destinations, including Jaeger and Zipkin.

Using tracing handlers

To add a tracing handler to an endpoint or a service, specify it when you create the endpoint or the service.

from flask import Flask
from nanopie import FlaskService, OpenTelemetryTracingHandler

app = Flask(__name__)
svc = FlaskService(app=app)

tracing_handler = OpenTelemetryTracingHandler()

@svc.list(name="list_users",
          rule="/users",
          tracing_handler=tracing_handler)
def list_users():
    do_something()

When added to an endpoint, the tracing handler will start a trace when the endpoint starts processing a request, and ends the trace when the endpoint finishes processing the request. If you add a tracing handler to a service, it will run for all endpoints in the service.

Alternatively, you may use a tracing handler separately by getting the OpenTelemetry tracer it configures:

from nanopie import OpenTelemetryTracingHandler

tracing_handler = OpenTelemetryTracingHandler()

tracer = tracing_handler.get_tracer())

Note

See OpenTelemetry for Python Documentation for instructions on how to use the tracer.

Configuring tracing handlers

Tracing handlers provide the following options for configuring its tracing behavior:

Argument Description
with_span_name The name of the trace span.
with_span_attributes The attributes of the trace span.
with_span_kind The kind of the trace span.
with_endpoint_config If set to True, the tracing handler will add the basic information about the current endpoint to the span attributes.
with_endpoint_extras If set to True, the tracing handler will add the user provided extra information about the current endpoint to the span attributes.
propagated If set to True, trace propagation will be enabled. See the discussion below for more information.
trace_ctx_extractor If set to True, the tracing handlers will run quietly when extracting trace contexts, i.e. it will not report any error should a trace context cannot be extracted or processed.
batched If set to True, trace spans will be sent to sources in batch for better performance.
with_sampler An OpenTelemetry trace sampler.
probability The rate for probability sampling.
write_to_console If set to True, the traces (spans) will be written to standard streams (stdout/stderr) in addition to source transmission.
jsonprint If set to True, the traces (spans) will be output in the format of JSON strings when written to standard streams.

Distributed tracing (trace context propagation)

It is common for a trace to span across a number of services; to correlate spans, services must exchange (propagate) trace contexts, which is also known as distributed tracing. nanopie tracing handlers support distributed tracing via trace context extractors. Once configured with a trace context extractor, tracing handlers will extract trace contexts automatically when processing a request, and use the contexts to set up the trace (span).

To create a trace context extractor, subclass the TraceContextExtractor class and override the extract method. It should return an instance if the TraceContext class. For specifics, see the source code.

For developers of HTTP microservices/API backends, W3C has standardized the way trace context is propagated in HTTP requests, and nanopie provides a reference implementation of TraceContext and TraceContextExtractor under the W3C standard that you can use:

from nanopie import (
    HTTPW3CTraceContext,
    HTTPW3CTraceContextExtractor,
    OpenTelemetryTracingHandler
)

trace_ctx_extractor = HTTPW3CTraceContextExtractor()
tracing_handler = OpenTelemetryTracingHandler(
    propagated=True,
    trace_ctx_extractor=http_w3c_trace_ctx_extractor
)

Connecting tracing handlers to other services

The OpenTelemetryTracingHandler, as specified in the beginning of this document, writes traces (trace spans) to the standard streams. If you would like to send traces (trace spans) to other destinations, such as distributed tracing systems, nanopie provides a number of additional tracing handlers; they accept the same set of tracing options and function in the same way as the foundation OpenTelemetryTracingHandler, with the only difference being the destination of traces (trace spans).

Available Tracing Handlers Description
JaegerTracingHandler A tracing handler that transmits traces to a Jaeger service.
ZipkinTracingHandler A tracing handler that transmits traces to a Zipkin service.

Using JaegerTracingHandler

Aside from the options inherited from OpenTelemetryTracingHandler, this tracing handler accepts the following additional arguments:

Argument Description
service_name The name of the service.
agent_host_name The hostname or address of the Jaeger agent.
agent_port The port of the Jaeger agent.
collector_host_name The hostname or address of the Jaeger collector.
collector_port The port of the Jaeger collector.
collector_endpoint The endpoint of the Jaeger collector.
username The username.
password The password.
from nanopie import JaegerTracingHandler

tracing_handler = JaegerTracingHandler(service_name="SERVICE")

Using ZipkinTracingHandler

Aside from the options inherited from OpenTelemetryTracingHandler, this tracing handler accepts the following additional arguments:

Argument Description
service_name The name of the service.
host_name The hostname or address of the Zipkin service.
port The port of the Zipkin service.
endpoint The endpoint of the Zipkin service.
protocol The protocol to use.
ipv4 Primary IPv4 address associated with this connection.
ipv6 Primary IPv6 address associated with this connection.
retry If set to True, the exporter will retry upon failure.
from nanopie import ZipkinTracingHandler

tracing_handler = ZipkinTracingHandler(service_name="SERVICE")