Menu
Grafana Cloud

Instrument a Python application

Follow this article to install the upstream OpenTelemetry distribution for Python and auto-instrument your application running on Linux for Grafana Cloud Application Observability.

Alternatively, if you need a instrumentation solution for Python supported by Grafana, use Grafana Beyla.

Before you begin

The is the first step to get telemetry data into Application Observability, you need:

  1. A Python development environment.
  2. A Python application to instrument using Python 3 or higher.

Install the SDK

Install OpenTelemetry SDK:

sh
pip install opentelemetry-distro[otlp]
opentelemetry-bootstrap -a install

Instrument your application

Export the following environment variables before running your application to configure auto-instrumentation:

sh
export OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
export OTEL_LOGS_EXPORTER=otlp

Global Interpreter Lock

OpenTelemetry Python uses a Global Interpreter Lock (GIL) that can cause performance issues when using a web server that spawns multiple processes to serve requests in parallel.

To avoid this, you have to register a post_fork hook that will be called after each worker process is forked.

Note

Other web servers, such as uWSGI, can be instrumented in the same way (@postfork instead of post_fork).

Use this gunicorn.conf.py file (gunicorn app -c gunicorn.conf.py) in addition to the Python production instrumentation guide.

python
import logging
from uuid import uuid4

from opentelemetry import metrics, trace
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import (
    OTLPLogExporter,
)
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import (
    OTLPMetricExporter,
)
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
    OTLPSpanExporter,
)
# support for logs is currently experimental
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.resources import SERVICE_INSTANCE_ID
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

# your gunicorn config here
# bind = "127.0.0.1:8000"

collector_endpoint = "http://localhost:4317"


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

    resource = Resource.create(
        attributes={
            # each worker needs a unique service.instance.id to distinguish the created metrics in prometheus
            SERVICE_INSTANCE_ID: str(uuid4()),
            "worker": worker.pid,
        }
    )

    tracer_provider = TracerProvider(resource=resource)
    tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint=collector_endpoint)))
    trace.set_tracer_provider(tracer_provider)

    metrics.set_meter_provider(
        MeterProvider(
            resource=resource,
            metric_readers=[(PeriodicExportingMetricReader(
                OTLPMetricExporter(endpoint=collector_endpoint)
            ))],
        )
    )

    logger_provider = LoggerProvider(resource=resource)
    logger_provider.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter(endpoint=collector_endpoint)))
    logging.getLogger().addHandler(LoggingHandler(level=logging.NOTSET, logger_provider=logger_provider))

Test your instrumentation

To test if you successfully instrumented your application and are producing telemetry data, run the application. The console output should print references to metrics and logs.

sh
opentelemetry-instrument flask run -p 8080

Example application

See the Rolldice service for a complete example setup.

Next steps

  1. Create a free Grafana Cloud account
  2. Configure your telemetry data destination:
    1. Grafana Cloud OTLP endpoint: for a quick local development and testing setup
    2. OpenTelemetry Collector: for a robust and scalable production setup
  3. Observe your services in Application Observability

Resources

  1. OpenTelemetry Distro OpenTelemetry documentation
  2. opentelemetry-distro on pypi
  3. opentelemetry-python-contrib on GitHub