Dec 20th, ‘24/14 min read

OpenTelemetry with Flask: A Comprehensive Guide for Web Apps

Learn how to integrate OpenTelemetry with Flask to monitor and trace your web app’s performance with easy-to-follow setup and troubleshooting tips.

OpenTelemetry with Flask: A Comprehensive Guide for Web Apps

Observability has become a critical aspect of web application development. If you're working with Flask, a popular microweb framework for Python, you might have heard of OpenTelemetry, the open-source framework that provides a set of APIs, libraries, agents, and instrumentation to enable the collection of metrics, traces, and logs from your applications.

But how do you integrate OpenTelemetry with Flask? And why should you do it in the first place?

In this guide, we’ll walk through the process of setting up OpenTelemetry with Flask, explore the key concepts, and highlight best practices to ensure that your application’s observability is top-notch.

What is OpenTelemetry?

OpenTelemetry is an open-source project that provides a unified set of APIs, libraries, and tools for collecting distributed traces, metrics, and logs from applications.

With OpenTelemetry, you can collect performance data from your application, track its behavior across microservices, and gain valuable insights into how your system behaves under different conditions.

OpenTelemetry with Flask helps you gain a better understanding of your application’s performance, identify bottlenecks, track errors, and improve the overall user experience.

It works by automatically capturing telemetry data from your application and sending it to your observability backend (like Prometheus, Jaeger, or OpenTelemetry-compatible platforms).

OpenTelemetry vs. Prometheus | Last9
OpenTelemetry vs. Prometheus - Difference in architecture, and metrics

Why Use OpenTelemetry with Flask?

Flask is a powerful micro-framework, but managing observability can be challenging when your app grows. Flask applications often involve multiple components, from databases to third-party services, making it hard to pinpoint performance issues or bugs.

By integrating OpenTelemetry with Flask, you unlock several benefits:

End-to-end Tracing

Trace requests from the user’s browser all the way to your backend services, helping you pinpoint latency issues and understand the lifecycle of each request.

Automatic Metrics Collection

Track key performance indicators like request durations, error rates, and throughput automatically without much setup.

Log Correlation

Correlate logs with traces and metrics for a more comprehensive view of application health.

Proactive Issue Detection

Use metrics and traces to detect performance issues, slow queries, and other anomalies before they affect users.

Improved Debugging

When issues arise, having traces and metrics makes debugging faster and more efficient.

Convert OpenTelemetry Traces to Metrics with SpanMetrics | Last9
Already implemented tracing but lack metrics? With SpanConnector, you can convert trace data into actionable metrics. Here’s how to configure it.

Setting Up a Virtual Environment for Your Flask Application

Before integrating OpenTelemetry with Flask, it’s important to set up a clean environment for your application. Using a virtual environment ensures that your project’s dependencies are isolated from your global Python setup. This helps avoid version conflicts and makes managing your project’s libraries more manageable.

Here’s how you can create and set up a virtual environment for your Flask application:

Step 1: Install virtualenv

First, install virtualenv, a tool for creating isolated Python environments. You can install it using pip:

pip install virtualenv

Step 2: Create a Virtual Environment

Once virtualenv is installed, navigate to your project directory and create a new virtual environment by running:

virtualenv venv

This will create a directory named venv within your project folder, containing a fresh Python environment. You can name the virtual environment anything you want, but venv is a common convention.

Step 3: Activate the Virtual Environment

Next, activate the virtual environment to install libraries and run Flask within this isolated environment.

On Windows, run:

venv\Scripts\activate

On macOS/Linux, run:

source venv/bin/activate

Once activated, your command prompt will change to show the virtual environment’s name (usually (venv)), indicating that you’re now working inside an isolated environment.

Instrumenting AWS Lambda Functions with OpenTelemetry | Last9
Learn how to instrument AWS Lambda functions with OpenTelemetry to gain valuable insights and improve the performance of your serverless apps.

Step 4: Install Flask and Other Dependencies

With your virtual environment activated, you can now install Flask and any other dependencies for your project, including OpenTelemetry.

To install Flask:

pip install Flask

To install OpenTelemetry and other necessary packages:

pip install opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation-flask opentelemetry-exporter-jaeger

You can add more packages as needed for your project. All dependencies will be installed locally in the venv folder, ensuring your global Python environment remains untouched.

Step 5: Deactivate the Virtual Environment

When you’re done working in the virtual environment, deactivate it by running:

deactivate

This will return you to your system’s global Python environment.

Step 6: Managing Dependencies with requirements.txt

To make it easier to manage and share your project’s dependencies, create a requirements.txt file. This file contains a list of all the packages installed in your virtual environment.

To generate the requirements.txt file, run:

pip freeze > requirements.txt

Now, anyone else working on the project can create the same environment by running:

pip install -r requirements.txt

This simplifies setting up the project on a different machine or for a new developer!

A Complete Guide to Integrating OpenTelemetry with FastAPI | Last9
Learn how to integrate OpenTelemetry with FastAPI for enhanced observability, including automatic instrumentation, environment variables, and custom exporters.

Why Use a Virtual Environment?

Isolation

Keep your project dependencies separate from other projects or the system’s global packages.

Easier Dependency Management

You can track exactly what packages your project requires, ensuring consistent setups across machines and teams.

Preventing Version Conflicts

Avoids conflicts between different versions of the same package across projects.

With the virtual environment set up, you’re now ready to start building your Flask app and integrating OpenTelemetry for full observability!

Setting Up OpenTelemetry with Flask: A Step-by-Step Guide

Now, let’s get hands-on and see how to set up OpenTelemetry in your Flask application. Here’s how you can do it in a few simple steps:

Step 1: Install the Required Packages

To get started, you’ll need to install the necessary OpenTelemetry libraries. You can install them using pip:

pip install opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation-flask opentelemetry-exporter-jaeger

This command installs:

  • opentelemetry-api: The core API that defines the interfaces for tracing, metrics, and logs.
  • opentelemetry-sdk: The SDK implementation of the OpenTelemetry API.
  • opentelemetry-instrumentation-flask: The Flask-specific integration that automatically instruments your Flask app.
  • opentelemetry-exporter-jaeger: The Jaeger exporter, sends trace data to Jaeger, a popular observability platform.

You can replace Jaeger with your preferred backend exporter, such as opentelemetry-exporter-prometheus for Prometheus integration.

Introduction to OpenTelemetry Express for Node.js Applications | Last9
OpenTelemetry Express simplifies trace collection for Node.js apps, helping you monitor performance and diagnose issues across distributed systems.

Step 2: Set Up OpenTelemetry in Your Flask App

Next, you’ll need to configure OpenTelemetry to start capturing data from your Flask app. Here’s a simple example of setting it up:

from flask import Flask
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor

# Initialize the Flask app
app = Flask(__name__)

# Set up OpenTelemetry tracing
trace.set_tracer_provider(TracerProvider())
jaeger_exporter = JaegerExporter(
    agent_host_name='localhost',  # Your Jaeger agent's host
    agent_port=6831,  # The port your Jaeger agent is listening on
)
span_processor = BatchSpanProcessor(jaeger_exporter)
trace.get_tracer_provider().add_span_processor(span_processor)

# Instrument Flask with OpenTelemetry
FlaskInstrumentor().instrument_app(app)

@app.route('/')
def hello():
    return "Hello, OpenTelemetry with Flask!"

if __name__ == '__main__':
    app.run(debug=True)

In this example:

  • Tracer Provider: We set up the OpenTelemetry TracerProvider, which handles the tracing of requests.
  • Jaeger Exporter: The Jaeger exporter sends trace data to a Jaeger instance running locally. If you’re using another observability backend, you’ll need to use the appropriate exporter.
  • Flask Instrumentation: The FlaskInstrumentor().instrument_app(app) line automatically instruments your Flask app to capture request data and generate spans.

Step 3: Verify the Integration

Once the setup is complete, run your Flask application:

python app.py

Now, visit http://127.0.0.1:5000/ in your browser. If everything is set up correctly, you should see traces generated in your chosen observability backend (like Jaeger or Prometheus).

You can visualize the traces and analyze the performance of each HTTP request, which will help you identify bottlenecks and troubleshoot issues.

Kafka with OpenTelemetry: Distributed Tracing Guide | Last9
Learn how to integrate Kafka with OpenTelemetry for enhanced distributed tracing, better performance monitoring, and effortless troubleshooting.

Best Practices for Using OpenTelemetry with Flask

Instrument Everything

Ensure that all your major components—such as databases, external APIs, and background tasks—are instrumented. This provides a complete picture of your application’s performance.

Use Contextual Data

Add metadata to your spans (e.g., user ID, request ID) to make it easier to trace individual requests through your application.

Set Sampling Rates

OpenTelemetry provides sampling options. For production environments, it’s important to set a reasonable sampling rate to avoid overwhelming your observability backend with too much data.

Monitor Performance Regularly

Use the collected metrics and traces to regularly monitor your Flask app. Set up alerts to get notified of any performance degradation or unusual activity.

Optimize Your Backend

Depending on your observability backend (e.g., Jaeger, Prometheus), consider optimizing the setup for performance. For instance, make sure your tracing backend can handle a large volume of requests if you're scaling your Flask app.

Use the collected metrics and traces to monitor your Flask app regularly. Set up alerts to be notified of any performance degradation or unusual activity.

Kubernetes Observability with OpenTelemetry Operator | Last9
Learn how the OpenTelemetry Operator makes monitoring Kubernetes easier, so you can focus on what matters—keeping your apps running smoothly!

How to Send Traces from a Flask App to Last9 with OpenTelemetry

Prerequisites

Before you begin, make sure you have the following:

  • A Flask application set up and running.
  • A Last9 account with a created cluster and OTLP credentials (including:
    • endpoint
    • auth_header from the Integrations page).

Installing OpenTelemetry Packages

To get started, install the necessary OpenTelemetry packages by running the following command:

pip install python-dotenv opentelemetry-distro opentelemetry-exporter-otlp

Next, install the required instrumentation packages:

opentelemetry-bootstrap -a install

For more information on these packages, visit the OpenTelemetry Python Libraries.

Setting Up Environment Variables

After installing the packages, configure your environment variables by running:

export OTEL_SERVICE_NAME=flask-app
export OTEL_EXPORTER_OTLP_ENDPOINT=<ENDPOINT>
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=<BASIC_AUTH_HEADER>"
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp

Make sure to replace <BASIC_AUTH_HEADER> it with the URL-encoded version of your basic auth header.

Running the Application

With the environment variables set, start your Flask application by running:

opentelemetry-instrument flask run

Visualizing Your Data

Once your Flask app is running, you can view the trace data in the APM dashboard on Last9. This will allow you to gain insights into your application's performance, such as latency, errors, and overall system health.

Getting Started with OpenTelemetry in Rust | Last9
Learn how to implement OpenTelemetry in Rust for effective observability, including tracing, metrics, and debugging in your applications.

Troubleshooting Tips for Common Instrumentation Issues

When integrating OpenTelemetry with Flask or any other application, it's common to encounter issues during the instrumentation process. Here are some troubleshooting tips to help you resolve common problems:

1. Missing or Incomplete Traces

Issue: You notice that traces are missing or incomplete in your observability backend.

Solution:

  • Check if the OpenTelemetry SDK is initialized properly: Ensure that your tracing provider and exporters are set up correctly. If you missed any setup steps or environment variables, traces may not be sent.
  • Verify service name: Ensure the OTEL_SERVICE_NAME environment variable is set correctly. A missing or incorrect service name may cause traces to be recorded but not properly categorized in the backend.
  • Check your network connection: Make sure that the endpoint for your trace exporter (e.g., Jaeger, OTLP) is reachable. Network issues or incorrect endpoint URLs can block data transmission.

2. Environment Variables Not Set Properly

Issue: The application is not sending any traces despite the instrumentation code being in place.

Solution:

  • Double-check the environment variables: Any incorrect values, such as typos in the OTLP endpoint or missing authorization headers, can prevent OpenTelemetry from exporting the data.
  • If working locally: Ensure that the environment variables are exported in the shell session where you're running your Flask app.
  • Use printenv or echo $VAR_NAME: Verify the values of the environment variables at runtime to ensure they are correctly set.
Hot Reload for OpenTelemetry Collector: Step-by-Step Guide | Last9
Learn to enable hot reload for the OpenTelemetry Collector to update configurations on the fly, improving your observability system’s agility.

3. High Latency in Tracing Data

Issue: Traces are showing high latency or delay in the dashboard.

Solution:

  • Adjust sampling rates: In a production environment, you might be using a low sampling rate to avoid overloading your backend. If latency is a concern, try increasing the sample rate or optimizing trace capture logic.
  • Optimize export batch settings: In OpenTelemetry, traces are exported in batches. You can adjust the batch size and the flush interval to fine-tune how quickly traces are sent. For example, the default setting might be too slow for high-throughput systems.
  • Review exporter configuration: Ensure the exporter is properly configured to send traces promptly. Check for any errors or timeouts in the exporter logs.

4. Errors in OpenTelemetry Initialization

Issue: OpenTelemetry fails to start or throws errors on startup.

Solution:

  • Check the logs: Both OpenTelemetry and the Flask application should provide error messages if initialization fails. Look for missing dependencies or incorrect versions of libraries.
  • Verify compatibility: Ensure you’re using compatible versions of OpenTelemetry packages and the Flask integration library. An incompatible version might cause failures.
  • Reinstall dependencies: Sometimes, a clean install helps. Remove the venv folder and reinstall the packages to make sure everything is set up correctly.

Exporter Options in OpenTelemetry: Setup and Troubleshooting

OpenTelemetry supports various exporters to send trace and metric data to backends for analysis. Understanding how to configure and troubleshoot these exporters is crucial for ensuring smooth telemetry data flow. Here are some common exporter options and troubleshooting tips:

1. OTLP Exporter

The OpenTelemetry Protocol (OTLP) exporter is widely used to send telemetry data (traces, metrics, logs) to OpenTelemetry-compatible backends.

Troubleshooting OTLP Issues:

  • Check endpoint URL: If the OTLP endpoint is incorrect or unreachable, traces won’t be sent. Double-check the URL format and ensure the server is running.
  • Authorization header: If using a secured endpoint, ensure the Authorization header is correctly set in your environment variables. Incorrect or missing headers may result in authentication errors.
  • Timeouts: OTLP exporters can time out if the network is slow or the backend is not responsive. Consider increasing the timeout duration in the exporter settings and monitoring network performance.
Whitespace in OTLP headers and OpenTelemetry Python SDK | Last9
How to handle whitespaces in the OTLP Headers with Python Otel SDK

2. Jaeger Exporter

Jaeger is a popular open-source distributed tracing system. OpenTelemetry can send traces to Jaeger using the Jaeger exporter.

Troubleshooting Jaeger Exporter Issues:

  • Jaeger Agent Availability: Ensure the Jaeger agent is running and reachable. If using Jaeger in a containerized environment (e.g., Docker), make sure the container is exposed correctly to the Flask application.
  • Check the Agent Port: By default, Jaeger’s agent runs on port 5775. Verify that the port is open and the Flask application can reach it. Adjust the agent_host_name and agent_port if necessary.
  • Jaeger Sampling: Jaeger supports sampling, which might cause some traces to be dropped. If you’re not seeing all traces, ensure your sampling configuration is aligned with your needs.

3. Prometheus Exporter

Prometheus is a widely used tool for metrics monitoring, and OpenTelemetry provides an exporter to send metrics to Prometheus.

Troubleshooting Prometheus Exporter Issues:

  • Ensure Prometheus Scrapes Your Metrics: Prometheus scrapes metrics from exporters periodically. Ensure your Flask app is correctly exposing the /metrics endpoint for Prometheus to scrape. You can test this by visiting the /metrics URL manually to check the output.
  • Verify Prometheus Configuration: In the Prometheus server configuration, ensure your application’s scrape endpoint is correctly added to the scrape_configs section.
  • Check for Metric Name Conflicts: If Prometheus scrapes too many metrics or conflicts arise with existing names, it can hinder data analysis. Keep track of your metric names and avoid conflicts with other Prometheus metrics.

4. Zipkin Exporter

Zipkin is another distributed tracing backend compatible with OpenTelemetry.

Troubleshooting Zipkin Exporter Issues:

  • Zipkin Server: Ensure the Zipkin server is running and reachable. If using Zipkin in a containerized setup (e.g., Docker), verify that the container is exposed correctly.
  • Exporter Configuration: Double-check your Zipkin exporter settings, including endpoint and port configurations. Incorrect URLs or ports may prevent trace data from being sent.
  • Sample Rate: Zipkin uses a sample rate to determine which traces to keep. If your sample rate is too low, some traces might be omitted. Adjust the sample rate to ensure you capture the necessary traces.
Instrumenting Golang Apps with OpenTelemetry | Last9
A comprehensive guide to instrument Golang applications using OpenTelemetry libraries for metrics and traces.

Conclusion

Integrating OpenTelemetry with Flask significantly boosts the observability of your web application. It allows you to trace, measure, and monitor performance across your system, making it easier to identify and resolve issues efficiently.

For a managed observability solution, Last9 offers support for OpenTelemetry and Prometheus, providing a unified view of metrics, logs, and traces.

It’s especially beneficial for teams managing distributed systems and microservices, giving you a comprehensive insight into your infrastructure and services.

Schedule a demo to learn more!

FAQs

1. How do I install OpenTelemetry in my Flask application?
To install OpenTelemetry in your Flask application, run the following commands to set up the necessary packages:

pip install python-dotenv opentelemetry-distro opentelemetry-exporter-otlp opentelemetry-bootstrap -a install

These packages will help instrument your Flask app and send traces to your chosen exporter, such as Last9.

2. What are the environment variables needed for OpenTelemetry with Flask?
To properly configure OpenTelemetry, set the following environment variables:

export OTEL_SERVICE_NAME=flask-app
export OTEL_EXPORTER_OTLP_ENDPOINT=<ENDPOINT>
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=<BASIC_AUTH_HEADER>"
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp

Replace <ENDPOINT> with your Last9 OTLP endpoint and <BASIC_AUTH_HEADER> with your encoded authorization header.

3. What should I do if traces are missing or not appearing in Last9?
If you’re not seeing traces in Last9, try the following troubleshooting steps:

  • Double-check your environment variables, especially the OTLP endpoint and authorization header.
  • Ensure that your Flask app is running with OpenTelemetry instrumentation by using the command opentelemetry-instrument flask run.
  • Verify that your backend is accessible and configured correctly to receive data.

4. Can I use a different exporter with OpenTelemetry in Flask?
Yes, OpenTelemetry supports multiple exporters, including Jaeger, Zipkin, and Prometheus. You can configure your Flask app to export traces and metrics to any of these backends by:

  • Installing the relevant exporter packages.
  • Adjusting your environment variables to match the exporter’s endpoint and authorization settings.

5. How do I troubleshoot if OpenTelemetry is not sending traces to my exporter?
If OpenTelemetry is not sending traces to your exporter, consider these steps:

  • Verify that the exporter configuration (endpoint, headers) is correct.
  • Ensure your network connection allows the application to communicate with the backend.
  • Check for any error messages or logs that might indicate network issues or misconfiguration.
  • Confirm that the OpenTelemetry SDK is initialized properly and that all necessary libraries are installed.

Contents


Newsletter

Stay updated on the latest from Last9.

Authors

Sahil Khan

Product Marketing Manager