Documentation / Python

Integrate a Python app with Logister.

The best path for Python projects is the published PyPI package logister-python. It is designed for the places Python teams usually need observability first: API requests, worker jobs, scheduled tasks, and standard-library logging, with first-party integrations for FastAPI, Django, Flask, and Celery.

Before you start

Create the project with the Python integration type.

What you needWhy it matters
Project API tokenAuthenticates your app when sending events
Logister instance base URLUsed to build the ingest, check-in, and deployment endpoints
Python 3.11+ appLets you install and run logister-python
Optional GitHub App installationLets Logister use repository, commit_sha, branch, and deployment records for source excerpts and deploy links

What you get

Use the Python integration across APIs, workers, scheduled tasks, and deploys.

NeedWhat appears in Logister
Catch web request failuresInbox issues from FastAPI, Django, or Flask with structured traceback frames, request metadata, route context, and runtime details.
Keep existing logs usefulStandard logging records in the activity feed, with logger.exception(...) and exc_info records reported as errors.
Understand request loadOptional FastAPI, Django, and Flask request spans that feed request load waterfall charts on the performance page.
Understand worker behaviorCelery task runtime, failures, retries, queue metadata, worker hostnames, and optional check-ins.
Debug with Python contextChained exceptions, runtime metadata, logger metadata, optional frame locals, and source/deployment context when configured.
Resolve source and deploy historyrepository, commit_sha, branch, release, and deployment records that let Logister show source excerpts, GitHub links, and "started after deploy" context when a GitHub repository is connected to the project.
Monitor custom operationsMetrics, transactions, spans, logs, and check-ins from the shared client.

Setup flow

Recommended installation path

  1. Create the project and generate an API key.
  2. Install logister-python in the Python app.
  3. Configure the client with environment variables or direct initialization, including environment, release, repository, commit SHA, and branch when available.
  4. Add the framework integration you need first: FastAPI, Django, Flask, or Celery.
  5. Attach instrument_logging() if you want standard Python logging records to flow into Logister too.
  6. Use the shared client for metrics, logs, transactions, spans, and check-ins across the rest of the app.
  7. From CI/CD, call record_deployment() after a successful deploy so releases map to exact commits.

Tip

Python teams usually get the most value by starting with uncaught exceptions plus request or task timing, then layering in logging, request spans, source context, deployment records, custom metrics, and check-ins once the main API and worker paths are visible.

Install

Install logister-python from PyPI.

Use the published PyPI package when you want a Python API, worker, scheduler, or internal service to send errors, logs, metrics, transactions, spans, check-ins, and deployment records into Logister.

shell
pip install logister-python
uv add logister-python
pip install 'logister-python[fastapi]'
pip install 'logister-python[django]'
pip install 'logister-python[celery]'
pip install 'logister-python[flask]'

Tip

Set LOGISTER_CAPTURE_LOCALS=true if you want frame locals attached to captured Python exceptions in the Logister UI. Keep that setting off for sensitive workloads unless you have reviewed what local variables may contain.

shell
export LOGISTER_API_KEY="your-project-api-token"
export LOGISTER_BASE_URL="https://your-logister-host.example"
export LOGISTER_ENVIRONMENT="production"
export LOGISTER_RELEASE="checkout@2026.06.18"
export LOGISTER_REPOSITORY="acme/checkout"
export LOGISTER_COMMIT_SHA="$(git rev-parse HEAD)"
export LOGISTER_BRANCH="$(git branch --show-current)"
python
from logister import LogisterClient

client = LogisterClient.from_env(default_context={"service": "api"})

client.capture_message("Application booted")
client.capture_metric(
    "cache.hit_rate",
    0.98,
    unit="ratio",
    level="info",
    fingerprint="metric:cache.hit_rate",
    context={"cache": "primary"},
)

LogisterClient.from_env() reads LOGISTER_REPOSITORY, LOGISTER_COMMIT_SHA, and LOGISTER_BRANCH. In GitHub Actions it falls back to GITHUB_REPOSITORY, GITHUB_SHA, and GITHUB_REF_NAME when the Logister-specific variables are not set.

Package links: PyPI and GitHub. Self-hosted backend: Logister app on GitHub.

Source and deployments

Record the deployed commit when CI/CD knows it.

If the project is connected to the GitHub App, source context lets Logister resolve traceback frames to repository files. Deployment records tell Logister which commit was deployed for a release and environment.

python
from datetime import datetime, timezone

client.record_deployment(
    release="checkout@2026.06.18",
    environment="production",
    repository="acme/checkout",
    commit_sha="4f8c2d1a9b7e6c5d4a3b2c1d0e9f8a7b6c5d4e3f",
    branch="main",
    deployed_at=datetime.now(timezone.utc),
    release_tag="v2026.06.18",
    workflow_run_url="https://github.com/acme/checkout/actions/runs/123",
)
FieldSet it fromUsed for
repositoryLOGISTER_REPOSITORY or GITHUB_REPOSITORYFinds the GitHub repository connected to the project.
commit_shaLOGISTER_COMMIT_SHA or GITHUB_SHAResolves stack frames and deployment context to the exact commit.
branchLOGISTER_BRANCH or GITHUB_REF_NAMEFalls back when an event has no commit or deployment record yet.
releaseYour app version, build ID, tag, or package versionConnects event filters, release health, and deployments.

Verify it

After a deploy, send one test exception with the same release. Open the event detail and check for source lookup status, deployment context, and GitHub links. If source is missing, confirm the GitHub App is installed, linked to the project, and the repository is connected; then check that the event has repository plus either commit_sha or a matching deployment record.

Python logging

Forward standard logging records without changing every call site.

python
import logging
from logister import LogisterClient, instrument_logging

client = LogisterClient.from_env(default_context={"service": "api"})
logger = logging.getLogger("checkout")

instrument_logging(client, logger=logger)

logger.warning("Inventory cache miss", extra={"request_id": "req_123", "sku": "sku_42"})

This is usually the easiest adoption path for existing Python services. The logging integration sends standard log records as log events and records with exc_info, including logger.exception(...), as error events. It also forwards logger metadata and extra record fields like request IDs and trace IDs.

FastAPI

Capture request timings and uncaught exceptions with middleware.

python
from fastapi import FastAPI
from logister import LogisterClient, instrument_fastapi

app = FastAPI()
logister = LogisterClient.from_env(default_context={"service": "api"})
instrument_fastapi(app, logister, capture_spans=True)

The FastAPI integration records each request as a transaction, optionally records a root server span when capture_spans=True, and captures uncaught request exceptions as error events, including route, full URL, selected headers, path params, status code, and common correlation headers.

Django

Use middleware for request timing and uncaught view errors.

python
MIDDLEWARE = [
    # ...
    "logister.django.LogisterMiddleware",
]
python
from logister import LogisterClient, build_django_middleware

logister = LogisterClient.from_env(default_context={"service": "django-web"})
ConfiguredLogisterMiddleware = build_django_middleware(logister, capture_spans=True)

The Django middleware captures request duration as a transaction, can emit root request spans with capture_spans=True, and uses process_exception() to report uncaught exceptions as error events.

Flask

Instrument request timing and uncaught request exceptions with app hooks.

python
from flask import Flask
from logister import LogisterClient, instrument_flask

app = Flask(__name__)
logister = LogisterClient.from_env(default_context={"service": "flask-web"})
instrument_flask(app, logister, capture_spans=True)

The Flask integration records each request as a transaction, can emit root request spans with capture_spans=True, and captures uncaught request exceptions as error events, including full URL, endpoint, blueprint, selected headers, status code, and common correlation headers.

Celery

Instrument task runtime, failures, retries, and optional check-ins.

python
from celery import Celery
from logister import LogisterClient, instrument_celery

celery_app = Celery("billing")
logister = LogisterClient.from_env(default_context={"service": "worker"})

instrument_celery(
    celery_app,
    logister,
    monitor_slug_factory=lambda task: getattr(task, "name", None),
)

The Celery integration captures task runtime as transaction events, failures as error events, retries as warning log events, and optional monitor heartbeats as check_in events, plus task metadata like queue, module, retries, ETA, and worker hostname when Celery exposes them.

Custom events

Use the same client for direct metrics, logs, spans, and check-ins.

python
client.capture_transaction("POST /checkout", 182.4, request_id="req_123")

client.capture_span(
    "render checkout",
    82.1,
    kind="render",
    status="ok",
    trace_id="trace-123",
    parent_span_id="span-root",
    request_id="req-123",
    context={"route": "POST /checkout"},
)

client.capture_exception(
    exc,
    fingerprint="checkout-failed",
    context={"component": "checkout", "order_id": 1234},
)

client.check_in(
    "nightly-import",
    "ok",
    release="worker@2026.05.21",
    expected_interval_seconds=3600,
    duration_ms=842.7,
    trace_id="trace-123",
    request_id="req-123",
)

Captured Python exceptions include structured traceback frames, chained exceptions from raise ... from ..., and runtime metadata like Python version, platform, hostname, and process ID. Metric captures accept value, unit, level, fingerprint, environment, release, trace ID, request ID, session ID, and user ID fields. Span captures accept span ID, parent span ID, kind, status, start/end timestamps, trace ID, request ID, and custom context for request load charts.

Verification
Activity page checklist
transactions visible
request spans visible
uncaught framework errors visible
Celery task events visible
Python logging events visible
custom metrics, spans, and check-ins present
source context visible on events when configured
deployment context visible after record_deployment runs