DEV Community

Cover image for Monitoring Flask with OpenTelemetry and Uptrace
Vladimir Mihailenco for Uptrace

Posted on • Edited on

Monitoring Flask with OpenTelemetry and Uptrace

Still using Jaeger/Sentry? Uptrace is an open-source APM tool that supports distributed tracing, metrics, and logs. You can use it to monitor applications and set up automatic alerts to receive notifications via email, Slack, Telegram, and more.

Uptrace distributed tracing tool


What is tracing?

Distributed Tracing allows you to follow a request through multiple services and components, capturing the timing of each operation as well as any logs and errors that occur.

In a distributed environment, tracing further enhances your understanding of the relationships and interactions between distributed microservices and systems.

Distributed tracing

Tracing allows you to break down requests into spans. A span is an operation (unit of work) that your application performs when handling a request, such as a database query or a network call.

A trace is a tree of spans that shows the path a request takes through an application. The root span is the first span in a trace.

Spans and trace

What is OpenTelemetry?

OpenTelemetry is an open-source observability framework for OpenTelemetry tracing (including logs and errors) and OpenTelemetry metrics.

OpenTelemetry allows developers to instrument their applications to automatically generate telemetry data that can then be collected and analyzed to gain insight into the performance, behavior and health of the system. It supports multiple programming languages and integrates with multiple observability tools and platforms.

Otel allows developers to collect and export telemetry data in a vendor agnostic way. With OpenTelemetry, you can instrument your application once and then add or change vendors without changing the instrumentation, for example, here is a list of DataDog competitors that support OpenTelemetry.

Creating spans

To measure the performance of database queries or HTTP requests, you can create a span using the OpenTelemetry Python API:

from opentelemetry import trace

tracer = trace.get_tracer("app_or_package_name", "1.0.0")

def some_func(**kwargs):
    with tracer.start_as_current_span("some-func") as span:
        // the code you are measuring
Enter fullscreen mode Exit fullscreen mode

To record contextual information, you can annotate spans with attributes. For example, an HTTP endpoint may have such attributes as http.method = GET and http.route = /projects/:id.

# To avoid expensive computations, check that span is recording
# before setting any attributes.
if span.is_recording():
    span.set_attribute("http.method", "GET")
    span.set_attribute("http.route", "/projects/:id")
Enter fullscreen mode Exit fullscreen mode

You can also record exceptions and set the span status code to indicate an error:

except ValueError as exc:
    # Record the exception and update the span status.
    span.record_exception(exc)
    span.set_status(trace.Status(trace.StatusCode.ERROR, str(exc)))
Enter fullscreen mode Exit fullscreen mode

See OpenTelemetry Python tracing for details.

What is Uptrace?

OpenTelemetry relies on a backend system to store, process, analyze, and visualize the telemetry data collected from applications. As a critical component, the backend enables you to extract valuable insights and make informed decisions based on the collected telemetry data.

Uptrace is an open source APM for OpenTelemetry with an intuitive query builder, rich dashboards, automatic alerts, and integrations for most languages and frameworks.

You can get started with Uptrace by downloading a DEB/RPM package or a pre-compiled Go binary.

Example application

In this tutorial, you will be instrumenting a toy app that uses Flask and SQLAlchemy database client. You can retrieve the source code with the following command:

git clone git@github.com:uptrace/uptrace.git
cd example/flask
Enter fullscreen mode Exit fullscreen mode

The app comes with some dependencies that you can install with:

pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Configuring OpenTelemetry

Uptrace provides OpenTelemetry Python distro that configures OpenTelemetry SDK for you. To install the distro:

pip install uptrace
Enter fullscreen mode Exit fullscreen mode

Then you need to initialize the distro whenever you app is started, for example, in manage.py:

# manage.py

import uptrace

def main():
    uptrace.configure_opentelemetry(
        # Copy DSN here or use UPTRACE_DSN env var.
        # dsn="",
        service_name="myservice",
        service_version="v1.0.0",
    )

    # other code
Enter fullscreen mode Exit fullscreen mode

Instrumenting Flask app

To instrument Flask app, you need to install a corresponding
OpenTelemetry Flask instrumentation:

pip install opentelemetry-instrumentation-flask
Enter fullscreen mode Exit fullscreen mode

Then you can instrument the Flask app:

from opentelemetry.instrumentation.flask import FlaskInstrumentor

app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
Enter fullscreen mode Exit fullscreen mode

Instrumenting SQLAlchemy

To instrument SQLAlchemy database client, you need to install a corresponding OpenTelemetry SQLAlchemy:

pip install opentelemetry-instrumentation-sqlalchemy
Enter fullscreen mode Exit fullscreen mode

Then instrument the db engine:

from flask_sqlalchemy import SQLAlchemy
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor

app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
db = SQLAlchemy(app)
SQLAlchemyInstrumentor().instrument(engine=db.engine)
Enter fullscreen mode Exit fullscreen mode

Running the example

You can start Uptrace backend with a single command using
Docker example:

docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

And then start the app passing the Uptrace DSN as an env variable:

export UPTRACE_DSN=http://project2_secret_token@localhost:14317/2
python3 main.py
Enter fullscreen mode Exit fullscreen mode

The app should be serving requests on http://localhost:8000 and should render a link to Uptrace UI. After opening the link, you should see this:

OpenTelemetry Flask trace

What's next?

Next, instrument more operations to get a more detailed picture. Try to prioritize network calls, disk operations, database queries, error and logs.

You can also create your own instrumentations using
OpenTelemetry Python Tracing API.

Top comments (0)