OpenTelemetry in Python — A Full Guide

A Comprehensive Deployment Guide on Using OpenTelemetry in Python

Chameera Dulanga
Python in Plain English

--

OpenTelemetry (OTel) is an open-source observability framework that allows you to collect telemetry data from cloud-native applications. It offers tools, APIs, and SDKs to collect and generate metrics, logs, and traces. It supports multiple languages, including Java, Python, Go, Ruby, C++, and Javascript.

This guide will cover how to instrument OpenTelemetry in your Python service using Jaeger, an open-source tool developed initially by Uber. This will give you the classic observability and monitoring use case.

If you are looking for capabilities like automatic payload collection, the ability to replay scenarios with a few clicks, and generate trace-based tests, I recommend that you look into using Helios. I included a section about how to install OpenTelemetry using Helios down below.

What’s unique about OpenTelemetry for Python

Python is an open-source, dynamic, and widely used programming language by developers. It supports object-oriented and procedural-oriented programming techniques and does not require variable declarations since it is a dynamically typed language.

Like all other instrumentation libraries, OpenTelemetry wraps existing function implementations and extracts the necessary data.

First, you must define the module name, class, and function. After that, you can provide a wrapper function with the original implementation as an argument. For example, if you want to instrument kafka-python, the standard Python Kafka client, you need to capture Kafka messages sent by the “send” function of KafkaProducer class.

wrap_function_wrapper( 
kafka.KafkaProducer,
"send",
_wrap_send(tracer, produce_hook)
)

For more details, you can see how instrumentation is defined in this OpenTelemetry kafka-python instrumentation project.

Getting started with OpenTelemetry in Python

Configuring OpenTelemetry with Python is pretty straightforward. In this example, I will use a simple Flask application to demonstrate the steps of integrating OpenTelemetry in Python.

Step 1: Creating the Python application

To begin with, install the Flask framework using pip3 install flask command. Then, create a file named server.py and update it with the code below:

from flask import Flask

app = Flask(name)

@app.route('/')
def index():
return 'Hello World!'

app.run(host='0.0.0.0', port=8000)

Step 2: Installing OpenTelemetry libraries

Install the OpenTelemetry libraries required to instrument the Python applications. Here, we will be using the opentelemetry-api and opentelemetry-sdk libraries.

pip install opentelemetry-api 
pip install opentelemetry-sdk

Once the libraries are installed, you can update the server.py with a tracer object like the following code:

from flask import Flask
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.trace.export import ConsoleSpanExporter

provider = TracerProvider()
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(name)

app = Flask(name)

@app.route('/')
def index():
with tracer.start_as_current_span("server_request"):
return 'Hello World!'

app.run(host='0.0.0.0', port=8000)

Now, if you run the application with opentelemetry-instrument --traces_exporter console --metrics_exporter console flask --app server run command, and you will see a console output with trace and metrics details.

Step 3: Installing Jaeger

You can install Jaeger for Python using the command given below.

pip install opentelemetry-exporter-jaeger

But before that, make sure Jaeger is running on your local machine. You can easily setup Jaeger locally using the Docker command below:

docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 -p 5775:5775/udp -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 14268:14268 -p 14250:14250 -p 9411:9411 jaegertracing/all-in-one:1.23

Then, you can update the tracing provider on your server.py file with Jaeger.

from flask import Flask
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource

provider = TracerProvider()
processor = BatchSpanProcessor(ConsoleSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(
TracerProvider(
resource=Resource.create({SERVICE_NAME: "my-python-service"})
)
)
jaeger_exporter = JaegerExporter(
agent_host_name="localhost",
agent_port=6831,
)
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(jaeger_exporter)
)

tracer = trace.get_tracer(name)

app = Flask(name)

@app.route('/')
def index():
with tracer.start_as_current_span("server_request"):
return 'Hello World!'

app.run(host='0.0.0.0', port=8000)

Now, you can rerun the application and monitor the traces in Jaeger at http://localhost:16686/.

Although this approach provides good insights into your application, the most advanced way of adapting instrumentation based on your requirements is by recompiling an agent from scratch. Furthermore, it will allow you to customize the instrumentation features according to your requirements.

Doing more with OpenTelemetry for Python

As mentioned, Jaeger provides solid trace filtering features. But there is a lot more you can do once Open Telemetry is installed.

If you deploy OpenTelemetry with Helios, you can use the Helios OpenTelemetry Python distro agent to collect additional data like HTTP and messaging payloads and see your service map and API catalog easily.

Here’s how to do it:

Step 1: Instrument Helios in your Python microservice

You can directly install Helios for your Python service with the below command:

pip install helios-opentelemetry-sdk

You can also use Helios with all the major Python web frameworks, including Django, Flask, and FastAPI.

Step 2: Configuring Environment Variables

After that, you need to configure the Helios agent with environment variables when running the service:

# TODO: Variable should be set before process starts

export AUTOWRAPT_BOOTSTRAP=helios

# TODO: Replace value with API token from Helios.

export HS_TOKEN=<API_TOKEN>

# TODO: Replace value with service name.

export HS_SERVICE_NAME=<SERVICE_NAME>

# TODO: Replace value with service environment.

export HS_ENVIRONMENT="<ENVIRONMENT_NAME>"

Or, you can directly configure Helios in your project’s init.py file.

from helios import initialize 

initialize(
api_token=<API_TOKEN>, # TODO: Insert API token from Helios.
service_name=<SERVICE_NAME>, # TODO: Insert service name.
enabled=True, # Defaults to False if omitted.
environment=<ENVIRONMENT>, # Defaults to os.environ.get('DEPLOYMENT_ENV') if omitted.
commit_hash=<COMMIT_HASH>, # Defaults to os.environ.get('COMMIT_HASH') if omitted.

)

You can find more configuration options here.

That’s it! Your service will now show up in Helios, where you can leverage tracing data from OpenTelemetry and use it for error monitoring and troubleshooting.

With Helios, you can:

  • See payloads and error data and easily identify bottlenecks.
  • Reproduce broken flows with a few clicks.
  • Develop and deploy production-ready code with confidence by seeing data flows, payloads, dependencies, and errors in your local environment.
  • Share and reuse requests, queries, and payloads with team members.
  • Automatically generate trace-based tests and gain observability to your existing test runs.

Similar to Python, you can easily use Helios for instrumentation in many other languages and frameworks, including JavaScript, Node.js, Java, Ruby, .NET, Go, C++ and Collector. So, if you are looking for detailed tracing information on your distributed system, take a look at Helios. You can sign up with Helios free tier from here.

--

--