OpenTelemetry ASGI Instrumentation

pypi

This library provides a ASGI middleware that can be used on any ASGI framework (such as Django, Starlette, FastAPI or Quart) to track requests timing through OpenTelemetry.

Installation

pip install opentelemetry-instrumentation-asgi

Usage (Quart)

from quart import Quart
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware

app = Quart(__name__)
app.asgi_app = OpenTelemetryMiddleware(app.asgi_app)

@app.route("/")
async def hello():
    return "Hello!"

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

Usage (Django 3.0)

Modify the application’s asgi.py file as shown below.

import os
from django.core.asgi import get_asgi_application
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'asgi_example.settings')

application = get_asgi_application()
application = OpenTelemetryMiddleware(application)

Usage (Raw ASGI)

from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware

app = ...  # An ASGI application.
app = OpenTelemetryMiddleware(app)

API

The opentelemetry-instrumentation-asgi package provides an ASGI middleware that can be used on any ASGI framework (such as Django-channels / Quart) to track requests timing through OpenTelemetry.

class opentelemetry.instrumentation.asgi.ASGIGetter[source]

Bases: opentelemetry.propagators.textmap.Getter

get(carrier, key)[source]

Getter implementation to retrieve a HTTP header value from the ASGI scope.

Parameters
  • carrier (dict) – ASGI scope object

  • key (str) – header name in scope

Return type

Optional[List[str]]

Returns

A list with a single string with the header value if it exists,

else None.

keys(carrier)[source]

Function that can retrieve all the keys in a carrier object.

Parameters

carrier (dict) – An object which contains values that are used to construct a Context.

Return type

List[str]

Returns

list of keys from the carrier.

opentelemetry.instrumentation.asgi.collect_request_attributes(scope)[source]

Collects HTTP request attributes from the ASGI scope and returns a dictionary to be used as span creation attributes.

opentelemetry.instrumentation.asgi.get_host_port_url_tuple(scope)[source]

Returns (host, port, full_url) tuple.

opentelemetry.instrumentation.asgi.set_status_code(span, status_code)[source]

Adds HTTP response attributes to span using the status_code argument.

opentelemetry.instrumentation.asgi.get_default_span_details(scope)[source]

Default implementation for get_default_span_details :type scope: dict :param scope: the asgi scope dictionary

Return type

Tuple[str, dict]

Returns

a tuple of the span name, and any attributes to attach to the span.

class opentelemetry.instrumentation.asgi.OpenTelemetryMiddleware(app, excluded_urls=None, default_span_details=None, server_request_hook=None, client_request_hook=None, client_response_hook=None, tracer_provider=None)[source]

Bases: object

The ASGI application middleware.

This class is an ASGI middleware that starts and annotates spans for any requests it is invoked with.

Parameters
  • app – The ASGI application callable to forward requests to.

  • default_span_details – Callback which should return a string and a tuple, representing the desired default span name and a dictionary with any additional span attributes to set. Optional: Defaults to get_default_span_details.

  • server_request_hook (Optional[Callable[[Span, dict], None]]) – Optional callback which is called with the server span and ASGI scope object for every incoming request.

  • client_request_hook (Optional[Callable[[Span, dict], None]]) – Optional callback which is called with the internal span and an ASGI scope which is sent as a dictionary for when the method recieve is called.

  • client_response_hook (Optional[Callable[[Span, dict], None]]) – Optional callback which is called with the internal span and an ASGI event which is sent as a dictionary for when the method send is called.

  • tracer_provider – The optional tracer provider to use. If omitted the current globally configured one is used.