Telemetry Design

Most logging frameworks are built for production: aggregating millions of logs to find a needle in a haystack.

Stario's telemetry is built for the developer.

The Problem: Interleaved Logs

In traditional logging, concurrent requests look like this in your terminal:

INFO: /users started
INFO: /posts started
INFO: Querying DB
INFO: User 42 found
INFO: Post 10 found

Which DB query belongs to which request? You don't know without manual correlation.

The Solution: Trace-Based Grouping

Stario's RichTracer groups every log, event, and step by the request that triggered it. Even if 50 requests happen at once, the output stays coherent:

GET /users/42 [200] 45ms
├─ auth.check 2ms
├─ db.query 40ms
└─ render 3ms

Dev vs. Prod

We use the same underlying system for both, but change the output format based on the environment:

  • Development (RichTracer): Optimized for human readability. Tables, colors, and hierarchical grouping.
  • Production (JsonTracer): Optimized for machine readability. One JSON line per event. Works perfectly with Datadog, ELK, or CloudWatch.

Explicit Observability

We don't use "ambient" logging. Every piece of telemetry is tied to the Context (c).

  • Steps: with c.step("db") records duration automatically.
  • Attributes: c["id"] = 1 adds data to the current trace.
  • Events: c("hit") records a point in time.

By making telemetry explicit, we ensure that logs are actually useful, not just noise.