One Timeline for Requests, Traces and Errors
How Temps merges requests, OpenTelemetry traces, errors and revenue events into a single correlated, time-ordered timeline you can read without switching.
Temps Team · May 17, 2026 · 2mo ago
If you're debugging a production incident across separate request logs, trace viewers, error dashboards, and revenue metrics, the fastest way to correlate everything is a single merged timeline — not four browser tabs. The Unified Observe page, shipped in Temps v0.1.0, merges all four signal types into one time-ordered stream so you can trace a user action from HTTP request through OTel span to error event to missing revenue in seconds.
How Do You Get a Unified Observability Timeline Without Multiple Tools?
Most teams answer this question by subscribing to Datadog (or paying for Sentry + Plausible + a separate request logger). Temps takes a different approach: because it already stores requests, traces, errors, and revenue events natively, it can merge them in a single backend query and display them in one view — no exporter glue, no separate SaaS accounts.
Three verified claims about the Temps Unified Observe page:
- Four signal types, one query — the
temps-observabilitycrate runs four parallel queries againstproxy_logs,error_events,revenue_events, and theotel_spansTimescaleDB hypertable, k-way merges them byts DESC, and trims to a single page. Every row is a discriminatedObservabilityEventunion that carries all the data the side panel needs — no follow-up fetch in the common case. - Cross-source correlation via
trace_id— migrationm20260502_000001_add_observe_correlationaddedproxy_logs.trace_id,proxy_logs.error_group_id,revenue_events.trace_id, anderror_events.trace_id_indexed(denormalized from JSONB for index speed). W3Ctraceparentheaders are parsed by the proxy and stamped ontoproxy_logs.trace_idat write time. Lets you jump from any request to the trace it produced, or from an error to the request that triggered it. - Free to self-host, Temps Cloud coming soon — Temps is Apache 2.0, runs as a single Rust binary, and the Observe page ships with every instance. Temps Cloud, a managed add-on for telemetry retention, offsite backups, and AI credits, has not shipped yet and is unpriced here.
Temps Unified Observe vs. Alternatives
| Temps Unified Observe | Datadog APM | Sentry + Plausible + Logger | |
|---|---|---|---|
| Request logs | Built in (Pingora proxy) | Agent-based | Separate tool |
| OTel traces | Built in (OTLP ingest) | Built in | Sentry only (no request logs) |
| Error tracking | Built in (Sentry-compatible DSN) | Built in | Sentry |
| Revenue events | Built in | Not included | Not included |
| Merged timeline | Yes — single view | No (separate APM / Log Analytics tabs) | No |
| Cross-signal correlation | Yes — trace_id across all four | Yes (requires full agent) | Manual |
| Self-hostable | Yes, free | No | Sentry OSS only |
| Cost | Free self-host; Cloud add-on coming soon (unpriced) | See datadog.com/pricing | Three separate subscriptions |
The cockpit: sparklines as filter toggles
The top of the Observe page is a row of four sparklines, one per event kind:
- Requests (proxy logs) — sky gutter
- Traces (OTel spans) — violet gutter
- Errors (error events) — rose gutter
- Revenue (revenue events) — emerald gutter
Each sparkline shows the count over your selected time range. Click one to toggle that kind on or off. The colors carry through to the timeline below — every row's left gutter matches its sparkline.
Two reasons this works better than a checkbox bar:
- You see relative volume at a glance. If errors spiked at 14:32, the rose sparkline shows it. You don't have to filter to errors first to find the spike.
- Filtering is one click, not three. The sparkline is the filter. There's no separate "kinds" panel to open.
Citation Capsule: The Unified Observe page in Temps v0.1.0 uses per-kind sparklines (sky for requests, violet for traces, rose for errors, emerald for revenue) that double as filter toggles. Clicking a sparkline toggles that kind on or off in the timeline below, with matching gutter colors carrying through to every row.
The stream: console-style monospace
Below the cockpit is the timeline. Monospace font, HH:mm:ss timestamps, color-coded gutters per kind, one-line summaries. It looks like tail -f for your business signal.
Why monospace? Because the dominant pattern in observability tooling is dense rows of structured data, and proportional fonts waste horizontal space. Monospace gives you predictable column widths, which makes scanning fast.
Why one-line summaries? Because the side panel is one click away. Putting full payloads inline turns the timeline into a wall of JSON. Putting them behind a click keeps the timeline scannable.
Click a row and the side panel opens. The panel renders entirely from the row payload — no follow-up fetch in the common case. That's a deliberate choice. Network round-trips are the difference between "feels instant" and "feels laggy," and the merge service ships everything the panel needs in the initial response.
What the merge service actually does
A new crate called temps-observability backs the page. It runs four parallel queries:
proxy_logsfor requestserror_eventsfor errorsrevenue_eventsfor revenueotel_spans(TimescaleDB hypertable, raw SQL viaFromQueryResult) for traces
Then it k-way merges them by ts DESC and trims to a single page. Each row carries a type discriminator and all the data the panel needs.
Heavy fields get truncated server-side:
- Stack frames → first 5
- Span attributes → first 20 keys, alphabetized
- Headers → whitelist of ~10 keys
Each truncation sets a *_truncated flag, so the panel can offer a "Show full" button that triggers an un-truncate fetch when you actually need everything. The default is fast; the deep-dive is opt-in.
Cross-source correlation: the trace_id story
The Observe view's most useful feature isn't the merge — it's that you can jump from a request to the trace it produced, or from an error to the request that triggered it. That requires trace_id columns everywhere.
v0.1.0 adds them via migration m20260502_000001_add_observe_correlation:
proxy_logs.trace_idandproxy_logs.error_group_id(with indexes)revenue_events.deployment_id,environment_id, andtrace_iderror_events.trace_id_indexed(denormalized fromdata.trace.trace_idJSONB for index speed)
All nullable. Old rows just render without correlation links — no backfill required.
Two ingest paths populate the new columns:
- W3C
traceparentextraction in proxy. temps-proxy parses inboundtraceparentheaders, validates the 32-hex trace_id (length, hex chars, rejects all-zero), and stamps it ontoproxy_logs.trace_idat write time. - OTel trace_id promotion in error tracking. Sentry-compatible ingest probes
data.sentry.contexts.trace.trace_id, top-leveldata.contexts.trace.trace_id, anddata.trace.trace_id, and promotes the first valid 32-hex value toerror_events.trace_id_indexed.
Both paths have unit tests for the happy path, missing/malformed inputs, case-folding, and the all-zero invalid trace_id reserved by the W3C spec.
Three deliberate choices worth defending
Traces default OFF. OTel spans are a high-volume hypertable. If we forced them on by default, anyone with non-trivial OTel ingest would see a timeline dominated by trace rows and miss the business signal. You opt in via the cockpit card. We'd rather you find errors than drown in spans.
Runtime logs are not in this view. Container stdout/stderr volume would absolutely dominate everything else. They live on the dedicated Logs page, where the viewer is designed for high-volume streaming with batching and pause/resume.
Filter state lives in URL search params. Send a teammate a link to "errors + revenue, last 6 hours, trace abc123" and they see exactly what you see. Permalinks for incidents. Browser back/forward navigation also works — you can drill into a trace, hit back, and the cockpit returns to the previous filter state without a re-fetch.
What this is not
Honest scope: the Observe page is for apps deployed on Temps, by teams who want the request → trace → error → revenue loop in one tool.
It's not a replacement for:
- Datadog APM — no continuous profiler, no flame graphs at code level
- Datadog log analytics — searchable by level + timeframe + free text, no DSL
- Splunk / Elastic — same caveat, plus no anomaly detection or ML
- PagerDuty / Opsgenie — no on-call rotation, no alert routing
- k8s metrics platforms — Temps assumes Docker, not Kubernetes
If you're a 1,000-engineer org running thousands of services across multiple clouds, you probably already have Datadog and a dedicated observability team. Don't switch.
If you're a 1–50 person team and currently piecing together Sentry + Plausible + Pingdom + a request-logger you wrote yourself, the Observe page is the kind of tool that replaces the duct tape with a single coherent surface.
How to try it
The Observe page is live in v0.1.0 for every project. Run the migration, deploy v0.1.0, and visit /projects/:slug/observe.
If you want correlated trace IDs in your request logs and error events, your client SDKs need to send a W3C traceparent header. Most OTel SDKs do this automatically. For frontend apps, @temps-sdk/react-analytics handles propagation.
FAQ
How do you get a unified observability view without multiple SaaS tools?
Run Temps — it stores requests (via its Pingora proxy), OTel traces (OTLP ingest endpoint), errors (Sentry-compatible DSN), and revenue events natively. The built-in Observe page merges all four into a single timeline using the temps-observability crate. No exporters to configure, no per-signal SaaS subscriptions required.
Does the Observe page work without OTel?
Yes. Requests, errors, and revenue events show up regardless of whether you've instrumented OTel. Traces only appear if you've configured OTel ingest. The cross-source correlation links work whenever a trace_id is present.
Can I add custom event kinds?
Not in v0.1.0. The four kinds are hardcoded into the merge service. Future releases may add a generic event-kind extension API.
What's the performance overhead on the database?
The four parallel queries each hit indexed columns (ts DESC with kind-specific predicates). Server-side truncation keeps payloads small. Tested against 7 days of data on a busy project (~1M requests, ~50k traces, ~5k errors, ~2k revenue events), p99 page load is under 600ms.
Why not include runtime logs?
Volume. A chatty container can produce 1,500 lines per second. Mixing that with business signal would make the timeline unusable. The dedicated Logs page handles container logs with proper batching, pause/resume, and an interval mode that closes the WebSocket while you read.
Is Temps free to self-host?
Yes. Temps is Apache 2.0 and free to self-host — you only pay for the server you already run it on. Temps Cloud is a managed add-on for telemetry retention, offsite backups, and AI credits; it hasn't shipped yet, and pricing hasn't been announced.
Related: Read the full v0.1.0 release notes