Lightstep from ServiceNow Logo

Products

Solutions

Documentation

Resources

Lightstep from ServiceNow Logo
< all blogs

Tracing with OpenTelemetry and Lightstep in Python

In "Getting Started with OpenTelemetry Alphas: PythonGetting Started with OpenTelemetry Alphas: Python", we scratched the surface of distributed tracingdistributed tracing with OpenTelemetry in Python. In this article, we'll dive deeper into span exporters and learn how to get traces into Lightstep from your Python application. You can create a free-forever Lightstep account herehere to follow along.

Span Exporters

In OpenTelemetry, an exporterexporter allows us to send data to a variety of backends. The Span ExporterSpan Exporter is the interface exporters must adhere to in order to integrate with the SDK. This interface allows the exporter to free the SDK from knowing about protocol-specific logic. The interface exposes two methods export and shutdown; here's what it looks like in Python:

class SpanExporter:
    """Interface for exporting spans.
    Interface to be implemented by services that want to export recorded in
    its own format.
    To export data this MUST be registered to the :class`..Tracer` using a
    `SimpleExportSpanProcessor` or a `BatchSpanProcessor`.
    """

    def export(self, spans: typing.Sequence[Span]) -> "SpanExportResult":
        """Exports a batch of telemetry data.
        Args:
            spans: The list of `Span`s to be exported
        Returns:
            The result of the export
        """

    def shutdown(self) -> None:
        """Shuts down the exporter.
        Called when the SDK is shut down.
        """

Using the Jaeger Exporter with Lightstep

In the first part of our example, we'll leverage the JaegerSpanExporter to send tracing information to Lightstep. The application we'll use is a client and server example available in the open-telemetry/opentelemetry-pythonopen-telemetry/opentelemetry-python repo. First, download the Jaeger agentdownload the Jaeger agent and run it with the following parameters. 

NOTE: You'll need a Lightstep access tokenLightstep access token before running the agent.

jaeger-agent \
--reporter.grpc.host-port=ingest.lightstep.com:443 \
--reporter.grpc.tls=true \
--jaeger.tags=access_token=<YOUR ACCESS TOKEN HERE>

Next, we'll configure a JaegerSpanExporter in the server and client. Here's the code for the server:

#!/usr/bin/env python3
import os

import flask
import requests

from opentelemetry import trace
from opentelemetry.ext import http_requests
from opentelemetry.ext.jaeger import JaegerSpanExporter
from opentelemetry.ext.wsgi import OpenTelemetryMiddleware
from opentelemetry.sdk.trace import Tracer
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor

exporter = JaegerSpanExporter(
    service_name="http-server",
    agent_host_name="localhost",
    agent_port=6831,
)

trace.set_preferred_tracer_implementation(lambda T: Tracer())
tracer = trace.tracer()

span_processor = BatchExportSpanProcessor(exporter)
tracer.add_span_processor(span_processor)

http_requests.enable(tracer)
app = flask.Flask(__name__)
app.wsgi_app = OpenTelemetryMiddleware(app.wsgi_app)

@app.route("/")
def hello():
    with tracer.start_as_current_span("parent"):
        requests.get("https://www.wikipedia.org/wiki/Rabbit")
    return "hello"

if __name__ == "__main__":
    app.run(debug=True)
    span_processor.shutdown()

And the client:

#!/usr/bin/env python3
import os

import requests

from opentelemetry import trace
from opentelemetry.ext import http_requests
from opentelemetry.ext.jaeger import JaegerSpanExporter
from opentelemetry.sdk.trace import Tracer
from opentelemetry.sdk.trace.export import BatchExportSpanProcessor

exporter = JaegerSpanExporter(
    service_name="http-client",
    agent_host_name="localhost",
    agent_port=6831,
)

trace.set_preferred_tracer_implementation(lambda T: Tracer())
tracer = trace.tracer()

span_processor = BatchExportSpanProcessor(exporter)
tracer.add_span_processor(span_processor)

http_requests.enable(tracer)
response = requests.get(url="http://127.0.0.1:5000/")
span_processor.shutdown()

After starting the server and sending some requests via the client, tracing information starts flowing into the Lightstep dashboard.

tracing-with-opentelemetry-and-lightstep-in-python

Using the Lightstep exporter

If using the OpenTelemetry alpha libraries is not bleeding edge enough, you'll love the next section. You can configure an experimental LightstepSpanExporter to make shipping your tracing information to Lightstep even easier. With the exporter, you'll be able to ship directly to Lightstep's public satellites. First, let's install the library.

NOTE: The exporter is experimental, your mileage may vary.

pip install -e git+https://github.com/lightstep/opentelemetry-exporter-python

Then configure the exporter in both client and server code:

from opentelemetry.ext.lightstep import LightstepSpanExporter
exporter = LightstepSpanExporter(
    name="exporter-demo-server",
    token="<YOUR ACCESS TOKEN HERE>",
)

Restart the server and run the client. Tracing information is now available in the Lightstep dashboard, with one less component to install!

tracing-with-opentelemetry-and-lightstep-in-python

If you'd like to learn more about OpenTelemetry, checkout the project's websitewebsite, we'd love to have you contribute to the project! If you're keen on improving the observabilityobservability of your systems and want to see how Lightstep can help achieve that, check out our SandboxSandbox.

Interested in joining our team? See our open positions herehere.

December 3, 2019
2 min read
OpenTelemetry

Share this article

About the author

Alex Boten

From Day 0 to Day 2: Reducing the anxiety of scaling up cloud-native deployments

Jason English | Mar 7, 2023

The global cloud-native development community is facing a reckoning. There are too many tools, too much telemetry data, and not enough skilled people to make sense of it all.  See how you can.

Learn moreLearn more

OpenTelemetry Collector in Kubernetes: Get started with autoscaling

Moh Osman | Jan 6, 2023

Learn how to leverage a Horizontal Pod Autoscaler alongside the OpenTelemetry Collector in Kubernetes. This will enable a cluster to handle varying telemetry workloads as the collector pool aligns to demand.

Learn moreLearn more

Observability-Landscape-as-Code in Practice

Adriana Villela, Ana Margarita Medina | Oct 25, 2022

Learn how to put Observability-Landscape-as-Code in this hands-on tutorial. In it, you'll use Terraform to create a Kubernetes cluster, configure and deploy the OTel Demo App to send Traces and Metrics to Lightstep, and create dashboards in Lightstep.

Learn moreLearn more
THE CLOUD-NATIVE RELIABILITY PLATFORM

Lightstep sounds like a lovely idea

Monitoring and observability for the world’s most reliable systems