Skip to main content

sigil-telemetry

Plug-and-play telemetry for AI agents. Install it, call init(), and every LLM call your agent makes is automatically tracked.

Quick Start

pip install sigil-telemetry[all]
from sigil_telemetry import init
init()
# Set your agent's ID and collector endpoint
SIGIL_AGENT_ID=your-agent-slug
SIGIL_COLLECTOR_URL=https://your-collector-endpoint/

That's it. Every LLM API call is now captured — tokens, model, latency, errors — and sent to your collector.


What's New in v0.3.0

  • Automatic user identity capture — Extracts the calling user from Azure AD / SSO headers or JWT Bearer tokens on every request. No code changes needed — works out of the box with init(). Disable with SIGIL_CAPTURE_USER=false.
  • Worker agent support — Set SIGIL_USER_ID env var for scheduled jobs and queue workers that don't have HTTP requests.

What's New in v0.2.0

  • Web framework auto-instrumentation — FastAPI, Flask, and Django are auto-detected and instrumented. All LLM calls within one HTTP request share a single trace_id (operation_Id), so you can count agent "runs" with COUNT(DISTINCT trace_id).
  • Noise span filtering — http send / http send body spans from web frameworks are silently dropped before they leave the process. They never reach your collector.
  • Health check exclusion — Routes like /health, /healthz, /ready, /alive, /ping are excluded from tracing entirely.
  • Graceful shutdown — atexit handler flushes all pending spans when the process exits, so you never lose the last batch.
  • Lighter install — Removed unnecessary dependencies from the core install.

Full Example

Here's a real agent that summarizes documents using Claude:

1. The Agent Code

# document_summarizer.py
import anthropic
from sigil_telemetry import init

# Initialize telemetry — call this ONCE at startup
init()

# Your normal agent code — no changes needed
client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Summarize this document: ..."}
    ]
)
print(response.content[0].text)

2. What Gets Captured (Per LLM Call)

Every time client.messages.create() runs, a span is automatically created with:

Field Example Value Description
operation_Id a1b2c3d4e5f6... Trace ID — groups all LLM calls in a single agent run
sigil.agent.id doc-summarizer Which agent made the call
sigil.agent.version 0.1.0 Agent version
sigil.agent.frameworks Anthropic,FastAPI Which SDKs and frameworks were detected
sigil.user.id z.mohammed@company.com Who triggered this run (auto-captured)
gen_ai.system anthropic LLM provider
gen_ai.request.model claude-sonnet-4-20250514 Model used
gen_ai.usage.input_tokens 1250 Tokens sent
gen_ai.usage.output_tokens 340 Tokens received
duration 2.3s How long the call took
status OK or ERROR Whether the call succeeded
sigil.environment production Environment
sigil.agent.division Sales Business division (if set)
sigil.agent.risk_classification low Risk level (if set)

If the agent makes multiple LLM calls in one run (e.g., calls Claude then GPT-4), all calls share the same operation_Id so you can see the full trace.

3. How Trace Grouping Works

API agents (FastAPI/Flask/Django): The web framework instrumentor creates a root span per HTTP request. All LLM calls within that request automatically become child spans sharing the same trace_id. You don't need to do anything — init() handles it.

Worker agents (scheduled jobs, listeners): Wrap your main() function in a custom span. All LLM calls within one job share the same trace_id.

In both cases: COUNT(DISTINCT trace_id) = number of agent runs.

4. Where the Data Goes

Agent makes LLM call
        │
        ▼
sigil-telemetry auto-captures it as an OpenTelemetry span
(noise spans like "http send" are filtered out here)
        │
        ▼
Span is batched and sent via OTLP to:
  → Your configured collector endpoint
        │
        ▼
Collector forwards to:
  → Your observability backend (Jaeger, Zipkin, Datadog, etc.)

User Identity Capture

v0.3.0 automatically captures who triggered each agent run. No code changes needed.

How it works:

Auth Method How Identity Is Captured
Azure AD / SSO (Easy Auth) Reads X-MS-CLIENT-PRINCIPAL-NAME header automatically
Azure AD / SSO (in-app JWT) Decodes Bearer token, extracts preferred_username → upn → email → name → oid
Worker agents (no HTTP) Reads SIGIL_USER_ID env var

The captured user ID is attached as sigil.user.id on every request span. All LLM calls within that request inherit the user context through the shared trace.

Disable user capture:

SIGIL_CAPTURE_USER=false

Or in code:

init(SigilConfig(capture_user=False))

Supported SDKs

Use [all] to install everything. Only the SDKs your agent actually uses get activated.

SDK Install Extra What It Covers
Anthropic [anthropic] Anthropic API
OpenAI [openai] OpenAI API (including compatible endpoints)
LangChain [langchain] LangChain, LangGraph, any LangChain-wrapped model
CrewAI [crewai] CrewAI multi-agent framework
LlamaIndex [llamaindex] LlamaIndex agents and pipelines
Vertex AI [vertexai] Google Vertex AI, Gemini models
Mistral AI [mistral] Mistral API
AWS Bedrock [bedrock] Claude, Llama, Titan via AWS
LiteLLM [litellm] Unified proxy across 100+ LLM providers

Web Framework Auto-Instrumentation

These are included in [all] and auto-detected by init():

Framework Install Extra What It Does
FastAPI [fastapi] Creates root span per HTTP request — all LLM calls in that request share one trace_id
Flask [flask] Same trace grouping for Flask apps
Django [django] Same trace grouping for Django apps

Health check routes (/health, /healthz, /ready, /alive, /ping, /startup, /liveness, /readiness) are automatically excluded from tracing.

Configuration

Env Variable Default Description
SIGIL_AGENT_ID — Required. Your agent's unique ID
SIGIL_AGENT_VERSION 0.1.0 Track deployments
SIGIL_COLLECTOR_URL — Required. Your collector endpoint URL
SIGIL_ENVIRONMENT production production, staging, development
SIGIL_CONSOLE_EXPORT false Print spans to console for debugging
SIGIL_DIVISION — Business division (e.g., Sales, Engineering)
SIGIL_RISK_CLASSIFICATION — Agent risk level (low, medium, high)
SIGIL_HOURS_SAVED — Estimated hours saved per run
SIGIL_CAPTURE_USER true Set false to disable automatic user identity capture
SIGIL_USER_ID — Static user ID for worker agents with no HTTP context

Or pass config in code:

from sigil_telemetry import init, SigilConfig

init(SigilConfig(
    agent_id="my-agent",
    environment="development",
    console_export=True,
    capture_user=True
))

Custom Spans

Track things beyond LLM calls (document parsing, tool use, etc.):

from sigil_telemetry import get_tracer, record_error

tracer = get_tracer()

with tracer.start_as_current_span("parse-contract") as span:
    span.set_attribute("document.pages", 42)
    try:
        result = parse_pdf(file)
    except Exception as e:
        record_error(span, e)
        raise

Metadata

Release files for sigil-telemetry 0.3.0

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

Source distribution (sdist)

Source distribution for sigil-telemetry 0.3.0
File Size Uploaded Provenance
sigil_telemetry-0.3.0.tar.gz 15.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sigil-telemetry 0.3.0
File Interpreter ABI Platform
sigil_telemetry-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 27.6 kB

Release files / sigil_telemetry-0.3.0.tar.gz

Download URL sigil_telemetry-0.3.0.tar.gz
Size 15.2 kB
Tags Source
SHA-256 checksum
How to use checksums
bec6d3d739695c297f41c0b28360dd9bd8f752f541c69e0a6ae936f35f9878ed
BLAKE2b-256 checksum
How to use checksums
9c758265936616038d158fa807d889680305d68479c978eb583e705cc36b7ab9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.0

Release files / sigil_telemetry-0.3.0-py3-none-any.whl

Download URL sigil_telemetry-0.3.0-py3-none-any.whl
Size 12.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
28a2459c84eb8a37eaa2bb97520706685f8241b1496c35ec26607ae966656298
BLAKE2b-256 checksum
How to use checksums
73501e7523574e5dc4b1cc3aab8b0ccc0e476bbab0721bda218368cf703f85b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.0

Security for sigil-telemetry 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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