Python SDK for sending errors, logs, metrics, transactions, spans, and check-ins to Logister.
Install it from PyPI as logister-python.
This package is aimed at Python teams running APIs, workers, schedulers, and internal services. The current focus is the set of places Python teams usually need first:
- a shared
LogisterClient - native Python
loggingintegration FastAPIrequest instrumentationDjangorequest middlewareCelerytask instrumentationFlaskrequest instrumentation
Supports Python 3.11 and newer.
- Main Logister app: https://github.com/taimoorq/logister
- Product docs: https://docs.logister.org/
- Insights beta guide: https://docs.logister.org/product/#insights-beta
- Python integration docs: https://docs.logister.org/integrations/python/
- PyPI package: https://pypi.org/project/logister-python/
- What This Package Is For
- Package Links
- Install From PyPI
- Environment Variables
- Core Client
- Python Logging
- Error Capture
- FastAPI
- Celery
- Django
- Flask
- Check-ins
- Using project Insights beta
- Event Mapping
- Publishing
- Release Flow
Use logister-python when you want a Python service to send operational telemetry into Logister through the published PyPI package instead of wiring raw HTTP calls by hand.
- API and web apps: FastAPI, Django, Flask
- Worker and scheduler processes: Celery, cron-style jobs, CLI tasks
- Standard-library logging pipelines:
loggingto Logister events - Shared custom instrumentation: errors, logs, metrics, transactions, spans, and check-ins
- PyPI package: https://pypi.org/project/logister-python/
- GitHub releases: https://github.com/taimoorq/logister-python/releases
- Source repository: https://github.com/taimoorq/logister-python
- Integration docs: https://docs.logister.org/integrations/python/
Core client:
pip install logister-pythonWith uv:
uv add logister-pythonFastAPI support:
pip install 'logister-python[fastapi]'Celery support:
pip install 'logister-python[celery]'Django support:
pip install 'logister-python[django]'Flask support:
pip install 'logister-python[flask]'Package index: https://pypi.org/project/logister-python/
LogisterClient.from_env() reads:
LOGISTER_API_KEYLOGISTER_BASE_URL(defaults tohttps://logister.org)LOGISTER_TIMEOUT(defaults to5.0)LOGISTER_ENVIRONMENTLOGISTER_RELEASELOGISTER_CAPTURE_LOCALS(true/false, defaults tofalse)
Use the shared client when you are wiring a script, worker, CLI task, or framework hook and want one place to send custom events.
from logister import LogisterClient
client = LogisterClient.from_env(default_context={"service": "api"})
client.capture_message("Application booted", level="info")
client.capture_metric(
"cache.hit_rate",
0.98,
unit="ratio",
level="info",
fingerprint="metric:cache.hit_rate",
context={"cache": "primary"},
)
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",
context={"route": "POST /checkout"},
)If your app already uses the standard library logging module, this is usually the easiest way to start sending application logs into Logister without rewriting call sites.
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"})What this records:
- standard Python log records as
logevents logger.exception(...)and other records withexc_infoaserrorevents- logger metadata like logger name, module, file, function, line number, process, and thread
- extra record fields passed through
extra={...}so request IDs, trace IDs, and app-specific details show up in Logister
You can also manage the underlying HTTP client explicitly:
from logister import LogisterClient
with LogisterClient.from_env() as client:
client.capture_message("Worker online")Python error reports are most useful when you include the service or component name and let the SDK send the traceback structure for you.
from logister import LogisterClient
client = LogisterClient.from_env(default_context={"service": "checkout"})
try:
run_checkout()
except Exception as exc:
client.capture_exception(
exc,
fingerprint="checkout-failed",
context={
"component": "checkout",
"order_id": 1234,
},
)Captured Python exceptions include structured traceback frames, backtrace text, exception module and qualified class name, chained exceptions from raise ... from ..., and runtime metadata like Python version, platform, hostname, and process ID.
Set LOGISTER_CAPTURE_LOCALS=true if you want frame locals included in error events for the Logister UI.
This is the cleanest path for modern Python API services.
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)What this records:
- request duration as a
transaction - optional root
serverspans for request load waterfall charts whencapture_spans=True - uncaught request exceptions as an
error - request metadata like method, path, route, full URL, selected headers, client IP, path params, query string,
x-request-id, andx-trace-id
You can customize transaction naming:
instrument_fastapi(
app,
logister,
transaction_namer=lambda request: f"{request.method} {request.url.path}",
)This is the worker-side path when your Python app does meaningful work outside the request cycle.
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),
)What this records:
- task runtime as a
transaction - task failures as an
error - task retries as a warning
log - optional task-level
check_inevents when you providemonitor_slug_factory - task metadata like queue, module, retry count, ETA, and worker hostname when Celery exposes it
Use middleware when you want a Django app to report request timing and uncaught view exceptions with very little setup.
Use the built-in middleware directly when env-based configuration is enough:
MIDDLEWARE = [
# ...
"logister.django.LogisterMiddleware",
]LogisterMiddleware reads the same LOGISTER_* environment variables as LogisterClient.from_env().
If you want to build the client yourself, bind it with build_django_middleware():
from logister import LogisterClient, build_django_middleware
logister = LogisterClient.from_env(default_context={"service": "django-web"})
ConfiguredLogisterMiddleware = build_django_middleware(logister)
ConfiguredLogisterMiddlewareWithSpans = build_django_middleware(logister, capture_spans=True)What Django middleware records:
- request duration as a
transaction - optional root
serverspans for request load waterfall charts whencapture_spans=True - uncaught view exceptions via
process_exception()as anerror - request metadata like method, path, route, full URL, selected headers, status code, client IP, query string,
X-Request-ID, andX-Trace-ID
Use the Flask hooks when you want lightweight request instrumentation without changing your route code.
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)What Flask instrumentation records:
- request duration as a
transaction - optional root
serverspans for request load waterfall charts whencapture_spans=True - uncaught request exceptions as an
error - request metadata like method, path, full URL, endpoint, blueprint, selected headers, status code, client IP, query string,
X-Request-ID, andX-Trace-ID
Check-ins are a good fit for scheduled jobs, cron-style imports, and the “did this worker actually run?” questions Python teams usually end up debugging.
from logister import LogisterClient
client = LogisterClient.from_env(default_context={"service": "scheduler"})
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",
)The Logister project Insights tab combines Inbox, Activity, and Performance data into live dashboard views. Python services get the most useful Insights view when they send consistent LOGISTER_ENVIRONMENT, LOGISTER_RELEASE, and stable top-level context attributes.
Use default_context for attributes that should be present on most events, and pass per-event context for route, queue, worker, or feature dimensions:
from logister import LogisterClient
client = LogisterClient.from_env(
default_context={
"service": "billing-api",
"region": "us-east-1",
}
)
client.capture_metric(
"queue.depth",
42,
unit="jobs",
context={
"service": "billing-worker",
"queue": "billing",
"tenant_tier": "enterprise",
},
)
client.capture_transaction(
"POST /checkout",
182.4,
context={
"route": "POST /checkout",
"feature_flag": "new_checkout",
"tenant_tier": "enterprise",
},
request_id="req_123",
)
client.capture_span(
"render checkout",
82.1,
kind="render",
status="ok",
trace_id="trace_123",
parent_span_id="span_root",
context={
"route": "POST /checkout",
"tenant_tier": "enterprise",
},
)
client.capture_message(
"payment provider retry",
level="warn",
context={
"service": "billing-worker",
"provider": "stripe",
"queue": "billing",
},
)
client.check_in(
"nightly-reconcile",
"ok",
expected_interval_seconds=3600,
duration_ms=842.7,
context={
"service": "billing-worker",
"queue": "reconcile",
},
)Practical Insights recipes:
- Release validation: set
LOGISTER_RELEASE, then filter Insights to the new release and compare error count, transaction P95, and custom metrics. - Worker monitoring: report metrics such as
queue.depth,queue.latency,task.retry_count, orcelery.active_taskswith stablequeueandservicecontext keys. - Performance triage: enable
capture_spans=Truefor FastAPI, Django, or Flask instrumentation to feed request load waterfall charts, then add route-level logs and metrics with matchingroutevalues. - Instrumentation audit: open Insights after deploy and confirm errors, logs, metrics, transactions, spans, and check-ins all appear in the recent stream.
Keep custom attributes stable and low-cardinality. Good top-level context keys include service, region, queue, route, tenant_tier, provider, and feature_flag. Avoid raw IDs, emails, request bodies, SQL text, and per-user values as Insights dimensions.
- web request duration ->
transaction - uncaught exception ->
error - app log / warning ->
log - custom counters / measurements ->
metric - scheduled job heartbeat ->
check_in
This package is intended to publish to PyPI with Trusted Publishing from GitHub Actions. A commit or merge to main runs CI only; publishing requires a version tag.
- Push a tag like
v0.2.3 - GitHub Actions builds the distributions
- PyPI Trusted Publishing handles the upload with OIDC
CHANGELOG.mdtracks package releases- Git tags trigger PyPI publish and GitHub releases
- This package keeps its own versioning separate from the main Logister app