Telemetry Reference ¶
Stario has built-in, trace-based observability. Every request is a "trace" that can contain multiple "spans" (steps).
Quick Start ¶
Choose your tracer based on the environment:
from stario import Stario, RichTracer, JsonTracer
# Dev: Pretty console output
tracer = RichTracer()
# Prod: Structured JSON logs
tracer = JsonTracer()
app = Stario(tracer)
Trace Steps (c.step) ¶
Use c.step to time specific blocks of code. These appear as nested entries in your logs.
async def handler(c: Context, w: Writer):
# 1. Add attributes to the main request span
c["user_id"] = 42
# 2. Create a child step
with c.step("db.fetch", {"table": "users"}) as s:
users = await db.get_users()
s["count"] = len(users) # Attributes on the child span
Events ¶
Record a single point in time without a duration:
c("cache.hit")
c("email.sent", {"to": "user@example.com"})
Tracer Types ¶
RichTracer ¶
Optimized for development. Groups spans by request and uses colors/tables for readability. Shows exactly what happened in a single request without interweaving other concurrent logs.
JsonTracer ¶
Optimized for production. Outputs one JSON line per event/span. Compatible with Datadog, ELK, and CloudWatch.
Trace IDs ¶
Every request has a unique trace_id. Access it via c.span.trace_id. Use this to correlate logs across your microservices or pass it to the frontend for debugging.
