One Observability Timeline for Requests, Traces, Errors, and Revenue
See how Temps merges requests, OpenTelemetry traces, errors, and revenue events into one correlated, time-ordered observability timeline.
Temps Team
May 17, 2026 · 2mo ago
See how Temps merges requests, OpenTelemetry traces, errors, and revenue events into one correlated, time-ordered observability timeline.
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.
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:
temps-observability crate runs four parallel queries against proxy_logs, error_events, revenue_events, and the otel_spans TimescaleDB hypertable, k-way merges them by ts DESC, and trims to a single page. Every row is a discriminated ObservabilityEvent union that carries all the data the side panel needs — no follow-up fetch in the common case.trace_id — migration m20260502_000001_add_observe_correlation added proxy_logs.trace_id, proxy_logs.error_group_id, revenue_events.trace_id, and error_events.trace_id_indexed (denormalized from JSONB for index speed). W3C traceparent headers are parsed by the proxy and stamped onto proxy_logs.trace_id at write time. Lets you jump from any request to the trace it produced, or from an error to the request that triggered it.| 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 | ~$6/mo Cloud or free self-host | See datadog.com/pricing | Three separate subscriptions |
The top of the Observe page is a row of four sparklines, one per event kind:
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:
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.
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.
A new crate called temps-observability backs the page. It runs four parallel queries:
proxy_logs for requestserror_events for errorsrevenue_events for revenueotel_spans (TimescaleDB hypertable, raw SQL via FromQueryResult) for tracesThen 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:
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.
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_id and proxy_logs.error_group_id (with indexes)revenue_events.deployment_id, environment_id, and trace_iderror_events.trace_id_indexed (denormalized from data.trace.trace_id JSONB for index speed)All nullable. Old rows just render without correlation links — no backfill required.
Two ingest paths populate the new columns:
traceparent extraction in proxy. temps-proxy parses inbound traceparent headers, validates the 32-hex trace_id (length, hex chars, rejects all-zero), and stamps it onto proxy_logs.trace_id at write time.data.sentry.contexts.trace.trace_id, top-level data.contexts.trace.trace_id, and data.trace.trace_id, and promotes the first valid 32-hex value to error_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.
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.
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:
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.
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.
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.
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.
Not in v0.1.0. The four kinds are hardcoded into the merge service. Future releases may add a generic event-kind extension API.
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.
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.
Yes. Temps is Apache 2.0 and free to self-host. Temps Cloud runs on Hetzner at cost + 30% margin — approximately $6/mo for a standard instance — with no per-seat fees and no bandwidth billing.
Related: Read the full v0.1.0 release notes