Otelio: OpenTelemetry + Loguru toolkit for Python services
Project description
otelio
Python OpenTelemetry + Loguru toolkit
A small, batteries-included OpenTelemetry + Loguru
toolkit for Python services. Call init_otelio(...) once at startup and you get traces
and logs that are automatically correlated by trace_id / span_id, exported over
OTLP/gRPC or OTLP/HTTP (SigNoz, Grafana, Jaeger, any OTLP collector) or to Azure
Application Insights — switchable with a single environment variable, no code changes.
Manual instrumentation, full control.
oteliois not an auto-instrumentation library. Nothing is monkey-patched and no spans are created behind your back — you decide exactly what gets traced and logged via explicit calls (init_otelio,otel_span,logger.*).
Features
- One call to wire everything —
init_otelio(...)sets up the tracer + logger providers, the Loguru bridge, and a clean-shutdown flush hook. - Logs correlate to spans automatically — keep using Loguru; every record is stamped
with the active
trace_id/span_idand exported. - Backend-agnostic — OTLP/gRPC, OTLP/HTTP, or Azure App Insights via the
OTELIO_TARGETenv var. Send traces and logs to the same backend, or split them across different backends (and OTLP collectors) per signal. Exporter SDKs are imported lazily, so you only install what you use. - Cross-service tracing built in — W3C
traceparent+baggagepropagation helpers so one request shows up as a single connected trace across service boundaries. - Tiny surface — eleven well-documented functions, nothing to configure in code.
Install
pip install python-otelio # core + OTLP/gRPC and OTLP/HTTP exporters
pip install "python-otelio[azure]" # also the Azure Application Insights exporter
Requires Python 3.10+. The distribution is named python-otelio on PyPI but imports
as otelio (from otelio import ...).
Quick start
from otelio import init_otelio, otel_span, otel_set_attributes
from loguru import logger
# 1. Bootstrap once, at process start (before anything emits telemetry).
init_otelio(service_name="my-service", service_version="1.0.0")
# 2. Log with Loguru as usual — records are stamped with the active span.
logger.info("service started")
# 3. Wrap units of work in spans; exceptions are recorded and re-raised.
with otel_span("handle_request", attributes={"route": "/search"}):
otel_set_attributes({"result.count": 12})
Configuration
All configuration is via environment variables.
| Variable | Default | Meaning |
|---|---|---|
OTELIO_TARGET |
otlp |
Global default for both signals: otlp (any OTLP/gRPC collector), otlp-http (any OTLP/HTTP-protobuf collector), azure (App Insights), or a custom registered target. |
OTELIO_TRACE_TARGET |
OTELIO_TARGET |
Override the target for traces only. Lets you send traces and logs to different backends. |
OTELIO_LOG_TARGET |
OTELIO_TARGET |
Override the target for logs only. |
OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:4317 (gRPC) / http://localhost:4318 (HTTP) |
Global OTLP collector endpoint. For target otlp-http the exporter appends /v1/traces and /v1/logs automatically; a per-signal endpoint (below) is used as-is. |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
OTEL_EXPORTER_OTLP_ENDPOINT |
Override the OTLP endpoint for traces only. |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT |
OTEL_EXPORTER_OTLP_ENDPOINT |
Override the OTLP endpoint for logs only. |
APPLICATIONINSIGHTS_CONNECTION_STRING |
— | App Insights connection string (target azure). |
OTEL_SERVICE_NAME |
the service_name arg |
Overrides the service name. |
OTELIO_ENVIRONMENT |
local |
Set as the deployment.environment resource attribute. |
OTELIO_CONSOLE |
— | Truthy (1/true) also prints spans to stdout for local debugging. |
OTEL_PYTHON_LOG_AUTO_INSTRUMENTATION |
true |
Required: set to false when using otelio to avoid a duplicate logging handler. |
# OTLP/gRPC collector (SigNoz, Grafana, Jaeger, ...)
export OTELIO_TARGET=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
# OTLP/HTTP-protobuf collector (path /v1/traces, /v1/logs appended automatically)
export OTELIO_TARGET=otlp-http
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
# Azure Application Insights
export OTELIO_TARGET=azure
export APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=...;IngestionEndpoint=..."
export OTELIO_ENVIRONMENT=production
# Split: traces to an OTLP collector, logs to Azure
export OTELIO_TRACE_TARGET=otlp
export OTELIO_LOG_TARGET=azure
# Split: traces and logs to two different OTLP collectors
export OTELIO_TARGET=otlp
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://tempo:4317
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://loki-otlp:4317
Required: set
OTEL_PYTHON_LOG_AUTO_INSTRUMENTATION=falsewhen usingotelio.export OTEL_PYTHON_LOG_AUTO_INSTRUMENTATION=false
Public API (from otelio import ...)
| Symbol | Purpose |
|---|---|
init_otelio(service_name, service_version, environment=None, resource_attributes=None, trace_exporters=None, log_exporters=None) |
Bootstrap tracing + logging once at startup. resource_attributes adds extra resource-level keys to every span + log. trace_exporters / log_exporters register custom exporters inline (lists of {"name", "factory"}). Returns the resolved Settings. |
otel_span(name, attributes=None, kind=SpanKind.INTERNAL, context=None) |
Context manager that starts a span, records exceptions, and re-raises. |
otel_current_span() |
The span active in the current context. |
otel_get_tracer() |
The shared otelio tracer. |
otel_inject_headers(headers=None) |
Inject the current trace context + baggage into an outbound header dict. |
otel_context_from_headers(headers) |
Extract a trace context (+ baggage) from inbound headers; pass to otel_span(context=...). |
otel_set_baggage(items) |
Put a mapping of key/values into baggage so they propagate downstream. Returns a detach token. |
otel_get_baggage(key) |
Read one baggage value from the current context (or None). |
otel_get_all_baggage() |
Read all baggage entries as a plain dict. |
otel_set_attributes(attributes, span=None) |
Set attributes on the current span, or span if given (guards is_recording()). |
otel_add_event(name, attributes=None, span=None) |
Add a timestamped event to the current span, or span if given. |
Settings |
The resolved config dataclass passed to exporter factories (see custom exporters). |
Context propagation across services
otelio carries the W3C traceparent + baggage headers automatically, so one request
shows up as a single connected trace across service boundaries:
import httpx
from opentelemetry.trace import SpanKind
from otelio import otel_inject_headers, otel_context_from_headers, otel_span
# Outbound — inject context into the request headers
with otel_span("call_downstream", kind=SpanKind.CLIENT):
headers = otel_inject_headers({"Authorization": token})
resp = httpx.post(url, headers=headers, json=payload)
# Inbound — continue the caller's trace
ctx = otel_context_from_headers(request.headers)
with otel_span("serve_request", kind=SpanKind.SERVER, context=ctx):
...
Documentation
See the full usage guide for bootstrapping, spans, correlated logging, context propagation, baggage, and a complete FastAPI example.
License
MIT © code4mk
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file python_otelio-0.0.4.tar.gz.
File metadata
- Download URL: python_otelio-0.0.4.tar.gz
- Upload date:
- Size: 13.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e751d450affc9105655ad865a815e0af33bff317276cd0fc5f22dbfd326de3f8
|
|
| MD5 |
cbd7de4e7595d1154ed38d7ad1dc06e2
|
|
| BLAKE2b-256 |
c482fae86d796cb54d04edc14eaee0d61b78e9aef87ee0ff3f734238b4af490d
|
File details
Details for the file python_otelio-0.0.4-py3-none-any.whl.
File metadata
- Download URL: python_otelio-0.0.4-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2512dfa7f5c43ac2fa7d5c8a8705ee55d806fde4f8490bca01cf8a27214e7f83
|
|
| MD5 |
c8bcf82d8857f332fd4b8849377b2f28
|
|
| BLAKE2b-256 |
c0a71aa4860e7e5e9b713ae6ed092eb2adb282307d4101b29e3c41dc31f6ade7
|