Skip to main content

Zipkin integration for ASGI frameworks.

Project description

AioZipkin middleware for Starlette/FastApi

Test Coverage Package version

Features

  • Using sentry-asgi as a boilerplate
  • Client - based on aiozipkin - async compatible zipkin library
  • Server (any zipkin 2.0 compatible server will work) - Jaeger examples
  • Middleware tracing http traffic
  • Injecting tracing headers to responses
  • Extracting tracing headers from requests
  • Context variable with the span for every incoming request - possible to instrument tracing of lower level operations

Quick start

Run tracing server

Jaeger all-in-one

Follow instructions at https://www.jaegertracing.io/docs/latest/getting-started/

$ docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

Trace queries at http://localhost:16686/

Add middleware

import uvicorn
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

from starlette_zipkin import ZipkinMiddleware

routes = [
    Route("/", JSONResponse({"status": "OK"})),
]

app = Starlette(debug=True, routes=routes)

app.add_middleware(ZipkinMiddleware)

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000, log_level="info", reload=True)

By default the client emits to http://localhost:9411.

All traffic is captured and available at http://localhost:16686/

Advanced Tutorial

To instrument tracing at lower levels, two helper functions are available:

  • get_root_span - returns the span instance corresponding to current request
  • get_tracer - returns the tracer instance corresponding to current request
  • trace - create span in the trace
import json
import asyncio
import uvicorn
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

from starlette_zipkin import (
    ZipkinMiddleware,
    ZipkinConfig,
    trace,
    B3Headers,
    UberHeaders
)


async def homepage(request):

    with trace("NewParent") as child_span:
        # ! if headers not explicitly provided,\
        # root span from middleware injects headers
        # and becomes the parent for subsequet services
        headers = child_span.context.make_headers()
        child_span.kind("SERVER")
        # possible span kinds
        # CLIENT = "CLIENT"
        # SERVER = "SERVER"
        # PRODUCER = "PRODUCER"
        # CONSUMER = "CONSUMER"
        child_span.annotate(
            "Child, sleeps for 1, injects headers and becomes parent"
        )
        await asyncio.sleep(1)
        return JSONResponse({"hello": "world"}, headers=headers)


routes = [
    Route("/", JSONResponse({"status": "OK"})),
    Route("/homepage", homepage),
]

app = Starlette(debug=True, routes=routes)

config = ZipkinConfig(
    host="localhost",
    port=9411,
    service_name="service_name",
    sample_rate=1.0,
    inject_response_headers=True,
    force_new_trace=False,
    json_encoder=json.dumps,
    header_formatter=B3Headers
)
app.add_middleware(ZipkinMiddleware, config=config)

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000, log_level="info", reload=True)

This way we are able to followup at the call from a different service. Here we use the same server, but pass the tracing headers to subsequent calls to demonstrate future spans:

Configuration

To change the middleware configuration, provide a config object (here with default values being as shown)

import json
from starlette_zipkin import ZipkinMiddleware, ZipkinConfig, B3Headers

config = ZipkinConfig(
    host="localhost",
    port=9411,
    service_name="service_name",
    sample_rate=1.0,
    inject_response_headers=True,
    force_new_trace=False,
    json_encoder=json.dumps,
    header_formatter=B3Headers
)

app = Starlette()

app.add_middleware(ZipkinMiddleware, config=config)

where:

  • host = "localhost"
    • default local host, needs to be set to point at the agent that collects traces (e.g. jaeger-agent)
  • port = 9411
    • default port, needs to be set to point at the agent that collects traces (e.g. jaeger-agent)
    • 9411 is default for zipkin client/agent (and jaeger-agent)
    • make sure to make accessible
  • service_name = "service_name"
    • name of the service
  • sample_rate = 1.0
    • zipkin sampling rate, default samples every call
  • inject_response_headers = True
    • automatically inject response headers
  • force_new_trace = False
    • if True, does not create child traces if incoming request contains tracing headers
  • json_encoder=json.dumps
    • json encoder can be provided, defaults to json dumps. It is used to format dictionaries for Jaeger UI.
  • header_formatter=B3Headers
    • defaults to b3 headers format. Can be switched to UberHeaders, which imply the uber-trace-id format.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

starlette-zipkin-0.3.0.tar.gz (10.4 kB view details)

Uploaded Source

Built Distribution

starlette_zipkin-0.3.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file starlette-zipkin-0.3.0.tar.gz.

File metadata

  • Download URL: starlette-zipkin-0.3.0.tar.gz
  • Upload date:
  • Size: 10.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.8.3 requests/2.28.1 setuptools/65.3.0 requests-toolbelt/0.9.1 tqdm/4.64.1 CPython/3.8.10

File hashes

Hashes for starlette-zipkin-0.3.0.tar.gz
Algorithm Hash digest
SHA256 3c8270d2de79fb07e97b7ab1649550e3dfa9fd27c63a62f971cbe0cf24f4c1cc
MD5 829f90d74339a650aa29112d24421fa7
BLAKE2b-256 820248cb903e2ee36b3eb5e78c0a5c8589a6150bf6656f096335c5addd149999

See more details on using hashes here.

File details

Details for the file starlette_zipkin-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: starlette_zipkin-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.8.3 requests/2.28.1 setuptools/65.3.0 requests-toolbelt/0.9.1 tqdm/4.64.1 CPython/3.8.10

File hashes

Hashes for starlette_zipkin-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 36144dbb6e358961861f2e9f2dc6d27a94f6d9980ad22a04fb7ea82f584a25b1
MD5 fc571be63f6b49148d11be48a754887a
BLAKE2b-256 6ea5329f1e88c69494451a4f8305767518a6160536db83beae294f4b0f94cb0f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page