Skip to main content

vigilon

Vigilon OpenTelemetry bootstrap for Python apps: one register() call — or the zero-code opentelemetry-instrument launcher — wires OTLP trace export to Vigilon and auto-instruments FastAPI, Flask, and Django plus the common HTTP/database clients.

The distribution and import package are both named vigilon.

Install

pip install vigilon

Quick start

Call register() as the first statement of your entrypoint, before application modules import the frameworks being instrumented:

import vigilon

vigilon.register(
    api_key="your-api-key",
    service_name="your-service-name",
    environment="production",
    service_version="1.2.3",  # optional, recommended for deploy tracking
)

from app import create_app  # import your app AFTER register()

app = create_app()

Optional environment variables:

  • VIGILON_OTEL_ENDPOINT — override the OTLP HTTP base endpoint (traces go to <endpoint>/v1/traces); useful for local collectors and tests.
  • VIGILON_EXCLUDED_URLS — extra excluded-URL regexes, comma-separated (see below).

Zero-code bootstrap

If you cannot (or would rather not) touch the entrypoint, launch the app under opentelemetry-instrument — the SDK registers itself through OpenTelemetry's distro/configurator hooks, driven entirely by environment variables:

VIGILON_API_KEY=your-api-key \
VIGILON_SERVICE_NAME=your-service-name \
VIGILON_ENVIRONMENT=production \
VIGILON_SERVICE_VERSION=1.2.3 \
opentelemetry-instrument python app.py
Variable Meaning
VIGILON_API_KEY Required. Your Vigilon API key.
VIGILON_SERVICE_NAME Required. Service name shown in Vigilon.
VIGILON_ENVIRONMENT Required. Deployment environment (production, staging, …).
VIGILON_SERVICE_VERSION Recommended — enables deploy tracking; the SDK warns when missing.
VIGILON_OTEL_ENDPOINT Optional OTLP endpoint override.
VIGILON_EXCLUDED_URLS Optional extra excluded-URL regexes, comma-separated.

Notes:

  • Pre-fork servers (gunicorn, uWSGI, Celery prefork) must not use this path — the SDK would start before the fork and lose its exporter thread in the workers. Use the per-worker register() recipes below instead.
  • Django: export DJANGO_SETTINGS_MODULE in the environment (not inside manage.py) — it must be set before opentelemetry-instrument initializes, or Django is deliberately left uninstrumented.
  • If another OpenTelemetry distro package is installed in the same environment, pin ours explicitly with OTEL_PYTHON_DISTRO=vigilon OTEL_PYTHON_CONFIGURATOR=vigilon.
  • A later in-process register() call is safely ignored (one warning), so code that also runs outside opentelemetry-instrument keeps working.

Instrumented libraries

register() (and the zero-code path) instruments whichever of these are installed — no configuration needed:

  • Web frameworks: FastAPI, Flask, Django (Django only when DJANGO_SETTINGS_MODULE is set — instrumenting without resolvable settings would break apps that configure Django later)
  • HTTP clients: requests, httpx, urllib3, aiohttp
  • PostgreSQL: psycopg, psycopg2
  • MySQL: mysql-connector-python, PyMySQL, mysqlclient
  • Other datastores: Redis, PyMongo, SQLAlchemy (any driver, including async engines)
  • AWS: Lambda flush handling (see below)

MySQL through SQLAlchemy is traced at both layers (an engine span with the driver span nested inside); async MySQL drivers (aiomysql, asyncmy) are traced via the SQLAlchemy async engine only.

App objects created before register()

FastAPI and Flask are instrumented by swapping the framework's app class, so an app object built before register() ran (usually an import-order problem you can't fix, e.g. inside a framework CLI) is left untouched. The escape hatch is the per-app instrumentor — pass your excluded URLs, since the merged defaults don't apply on this path:

from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor

FastAPIInstrumentor.instrument_app(app, excluded_urls="/health$,/ready$,/favicon\\.ico$")

(Flask: FlaskInstrumentor().instrument_app(app, excluded_urls=...).)

Pre-fork servers (gunicorn, uWSGI, Celery)

The SDK's exporter runs a background thread that does not survive fork(). Call register() once per worker, in the worker-startup hook — not at master/module import time:

# gunicorn.conf.py
def post_fork(server, worker):
    import vigilon

    vigilon.register(api_key=..., service_name=..., environment=...)
# uWSGI (run with --enable-threads)
from uwsgidecorators import postfork


@postfork
def start_vigilon():
    import vigilon

    vigilon.register(api_key=..., service_name=..., environment=...)
# Celery worker
from celery.signals import worker_process_init


@worker_process_init.connect
def start_vigilon(**kwargs):
    import vigilon

    vigilon.register(api_key=..., service_name=..., environment=...)

Excluded URLs

Health checks (/health, /ready, /favicon.ico) are excluded from instrumentation by default. Add your own patterns for uncovered health endpoints or long-lived SSE routes that would otherwise dirty service-level metrics:

vigilon.register(
    ...,
    excluded_urls=["/internal/health$", "/events/stream$"],
)

Patterns are regexes matched against the full request URL and are merged with the defaults. Excluded routes produce no server span at all — they disappear from tracing and from request metrics, which is exactly what you want for SSE.

Recording errors

Unhandled exceptions are recorded automatically. For errors your code catches and converts into an error response itself — invisible to instrumentation — call record_error:

from vigilon import record_error


@app.get("/data")
async def get_data():
    try:
        return await load_data()
    except Exception as error:
        record_error(error)
        return JSONResponse({"message": "failed"}, status_code=500)

If there is no active span, record_error is a no-op.

Background jobs

Wrap one execution of a background job — a cron tick, a queue processor, an interval loop — in with_job_monitor to report it as a Job Run. Each run starts its own trace, so database queries and outgoing requests made inside the job are attached to that run instead of being orphaned:

from vigilon import with_job_monitor


@with_job_monitor(name="sync-users", schedule="0 3 * * *")
async def sync_users(): ...


# Or as a context manager for inline blocks:
with with_job_monitor(name="refresh-cache"):
    refresh_cache()

name is a required, stable identifier — never interpolate per-item values (sync-user-42 fragments one job into unbounded identities). schedule is an optional cron expression enabling last-run and stale-job detection. Sync and async functions are both supported; errors are recorded on the run and re-raised.

with_job_monitor must run after register() has started the SDK. If it runs earlier, the job itself still executes normally, but the run is not reported.

AWS Lambda

Vigilon detects the Lambda runtime via AWS_LAMBDA_FUNCTION_NAME and adds the AWS Lambda instrumentation automatically, which flushes traces at the end of each invocation. No extra configuration is needed.

Development

uv sync
uv run pytest
uv run ruff check .
uv run mypy

Releasing

Releases go to PyPI from GitHub Actions via Trusted Publishing — no API tokens.

  • Main releases: every push to main runs release-main.yml, which bumps the patch version in lockstep (pyproject.toml + uv.lock), runs the tests, builds the wheel, smoke-tests it in a clean venv against a fake collector (scripts/smoke_test.py), publishes it to PyPI, then pushes the chore(release): X.Y.Z commit and the vX.Y.Z tag. A hand-set, not-yet-tagged version releases as-is instead of being bumped. Reruns are idempotent: a version counts as released once its tag exists, and files already on PyPI are skipped.
  • PR betas: pr-beta.yml builds every PR at a unique PEP 440 pre-release (X.Y.(Z+1)b<PR>.dev<run>), runs tests + smoke, and attaches the wheel to the workflow run. Betas never go to PyPI; to try a PR's code, install its git ref: pip install "vigilon @ git+https://github.com/vigilonio/python@<sha>".
  • vigilon-sdk is a reserved, unused name on PyPI (scripts/pypi-stub/vigilon-sdk) that points users to vigilon.

Release files for vigilon 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vigilon 0.1.5
File Size Uploaded
vigilon-0.1.5.tar.gz 20.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for vigilon 0.1.5
File Interpreter ABI Platform
vigilon-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 36.8 kB

Release files / vigilon-0.1.5.tar.gz

Download URL vigilon-0.1.5.tar.gz
Size 20.9 kB
Tags Source
SHA-256 checksum
How to use checksums
367e8bc5dd4b2bd608ff89ab303b607cab576332f7cea88b7c039c91937d1519
BLAKE2b-256 checksum
How to use checksums
d641dd1290c7958a213713ad5e404aeccc475c9d9f3ff192ace5aea6a2527994
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / vigilon-0.1.5-py3-none-any.whl

Download URL vigilon-0.1.5-py3-none-any.whl
Size 15.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab82a26046bafb3a0a14b8e06246724d6e2eee17750cdb52cf231d78bd6e5cad
BLAKE2b-256 checksum
How to use checksums
c66fbee1626d03543dd06701111b0b605da79035b84afd1467aa532183fa1002
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.1.6

2 release files

This release

0.1.5 This release

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page