Monitor Django with OpenTelemetry

Django is a high-level Python web framework that enables rapid development of secure and maintainable websites.

In this article you will learn how to monitor and optimize Django performance using OpenTelemetry observability framework.

What is OpenTelemetry?

OpenTelemetryopen in new window is an open-source observability framework hosted by Cloud Native Computing Foundation. It is a merger of OpenCensus and OpenTracing projects.

OpenTelemetry aims to provide a single standard across all types of observability signals such as OpenTemetry tracingopen in new window, and OpenTelemetry metricsopen in new window.

OpenTelemetry specifies how to collect and send telemetry data to backend platforms. With OpenTelemetry, you can instrument your application once and then add or change vendors without changing the instrumentation.

OpenTelemetry is available for most programming languages and provides interoperability across different languages and environments.

Django instrumentation

To instrument Django app, you need a correspoding Django instrumentation:

pip install opentelemetry-instrumentation-django

Usage

Django instrumentation uses DJANGO_SETTINGS_MODULE env variable to find settings file. Django defines that variable in manage.py file so you should instrument Django app from that file:

# manage.py

from opentelemetry.instrumentation.django import DjangoInstrumentor

def main():
    # DjangoInstrumentor uses DJANGO_SETTINGS_MODULE to instrument the project.
    # Make sure the var is available before you call the DjangoInstrumentor.
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

    DjangoInstrumentor().instrument()

See exampleopen in new window for details.

uWSGI

If you are using Django with uWSGI, you should use the post-fork hook to initialize OpenTelemetry, for example, in your main.py:

from uwsgidecorators import postfork
import uptrace

@postfork
def init_tracing():
    uptrace.configure_opentelemetry(
        # Set dsn or use UPTRACE_DSN env var.
        #dsn="",
        service_name="app_or_service_name",
        service_version="1.0.0",
    )

Gunicorn

If you are using Django with Gunicorn, you should use the post-fork hook to initialize OpenTelemetry, for example, in gunicorn.config.py:

import uptrace

def post_fork(server, worker):
    server.log.info("Worker spawned (pid: %s)", worker.pid)

    uptrace.configure_opentelemetry(
        # Set dsn or use UPTRACE_DSN env var.
        #dsn="",
        service_name="app_or_service_name",
        service_version="1.0.0",
    )

Instrumenting PostgreSQL engine

You can configure Django to use PostgreSQL by changing settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

Internally, postgresql' engine uses psycopg2 library. To instrument psycopg2, you need a corresponding instrumentation:

pip install opentelemetry-instrumentation-psycopg2

Then actually instrument the library from the main function:

from opentelemetry.instrumentation.psycopg2 import Psycopg2Instrumentor

Psycopg2Instrumentor().instrument()

Instrumenting MySQL engine

You can configure Django to use MySQL by changing settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

Internally, mysql engine uses mysqlclientopen in new window library that implements Python Database API. To instrument any library that uses Python DB API, you need the opentelemetry-instrumentation-dbapi instrumentation:

pip install opentelemetry-instrumentation-dbapi

Then actually instrument the mysqlclient library from the main function:

import MySQLdb
from opentelemetry.instrumentation.dbapi import trace_integration

trace_integration(MySQLdb, "connect", "mysql")

Instrumenting SQLite engine

You can configure Django to use SQLite by changing settings.py:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}

Internally, sqlite3 Django engine uses sqlite3open in new window Python library. To instrument sqlite3, you need a corresponding instrumentation:

pip install opentelemetry-instrumentation-sqlite3

Then actually instrument the sqlite3 library from the main function:

from opentelemetry.instrumentation.sqlite3 import SQLite3Instrumentor

SQLite3Instrumentor().instrument()

What is Uptrace?

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

You can get startedopen in new window with Uptrace by downloading a DEB/RPM package or a pre-compiled Go binary.

What's next?

Next, instrumentopen in new window more operations, for example, database queries and network calls. You can also learn about OpenTelemetry Python Tracing APIopen in new window to create your own instrumentations.

Popular instrumentations:

See also:

Last Updated: