Back Original

11 UI improvements in otel-desktop-viewer

The hyperfocus gods have been generous to me lately, but switching activities is hard, so most of that energy has gone directly into otel-desktop-viewer, and very little none has gone into writing about it. I’m working on longer posts about agent support (that I shipped without telling anyone, sorry 🇨🇦) and upgrading to DuckDB 2 (a native VARIANT type y’all).

In the meantime, here’s a tour of UI improvements!

1. Look! A new theme!

I loved the previous colour scheme (Rosé Pine), but accessibility is one of my priorities for otel-desktop-viewer, and meeting WCAG’s text contrast requirements was a struggle.

The replacement, Madoromi, gets its colours from scans of Pilot Iroshizuku fountain pen inks. It’s gorgeous, and its consistent colour roles, palette generation and contrast checks make it easier to build the same UI for light and dark mode.

You can switch between four seasons, each with Day and Night variants, without changing your service or series colours.

The same agent trace in four themes, arranged in a two-by-two grid: Autumn Night and Summer Night above Winter Day and Spring Day. Each service keeps the same colour across all four waterfalls.

2. Read structured attributes

I started coming across span attributes as JSON strings (looking at you gen-ai semantic conventions) and reading them as raw strings felt gross. The details pane now shows their structure with indentation, syntax highlighting and folding. Below is the same JSON string in v0.5.0 (left) and v0.7.0 (right), with the retries array folded.

Side-by-side details-pane screenshots labelled Before and After underneath. In v0.5.0, gen_ai.tool.call.result appears as a dense JSON string with escaped quotes and backslashes. In v0.7.0, the same string is displayed with indentation, syntax highlighting and folding, with arguments and result expanded and the retries array folded.

The same view works for native OTLP arrays and maps, represented in OTLP JSON by arrayValue and kvlistValue, respectively. Below, agent.tool_calls on the left is an array of maps, while agent.context on the right is a map containing nested maps and an array.

Two details-pane close-ups side by side, labelled Array and Map below the images. On the left, agent.tool_calls is an array with one tool-call map expanded to show a nested error and three retries. On the right, agent.context is a map with the task and token usage expanded and the plan array folded.

2′ Search within maps and arrays

Okay so this isn’t entirely a UI feature, but I’m sneaking it in anyway because it’s neat. Let’s call it 2′.

You can now query individual values inside maps and arrays. Let’s say you wanted to find agent runs where the second tool call reported at least three retries:

span.attributes["agent.context"]["tool_calls"]
  [1]["result"]["retries"]::BIGINT >= 3
A nested-attribute query above a colourful, nine-service agent trace. In the details pane, agent.context has its tool_calls array expanded. The first call, search_traces, shows checkout in its service argument and 12 matches in its result. The beginning of the second call shows payment-service in its arguments.

3. Copy and download OTLP JSON

Ever wish you could see the raw OTLP payload behind a value? Now you can! The JSON tab shows the selected record as OTLP JSON, with its resource and scope context. You can fold the JSON, copy it or download it as a file.

A wide view of the JSON pane, showing the selected span’s name, IDs and timestamps inside an OTLP document. Resource, scope, attributes and events are folded. The Properties and JSON tabs, Copy and Download controls are visible.

You can now bring those OTLP files back into the viewer: drop JSON or JSONL files anywhere in the window. Send your colleague a weird trace and they can drag it right in to see what you see.

5. Compare metric series

The new series table lets you sort and compare series by their attributes, such as CPU core. Hover over a row to highlight its line on the chart, or click it to inspect the datapoints. You can select individual datapoints from either the chart or the table.

6. Explore heatmaps and histograms

You can highlight p50, p95 and p99 on the heatmaps while keeping the full distribution visible. This helps you see whether requests are getting slower across the board or just in the tail.

You can also hide the overlays to inspect the distribution on its own.

A dense exponential-histogram heatmap with a bright latency band that rises, dips and rises again. A sparse violet tail extends below the dip, giving it a funnel shape. The Percentiles checkbox is unchecked and no percentile curves are shown.

The histogram matches the heatmap’s colours for bucket counts. Selecting a datapoint shows how much it contributes to each bucket in the combined distribution. Texture marks the selected datapoint’s contribution.

7. See reporting gaps

Gauge charts now leave gaps when samples stop arriving, while keeping real zero readings on the chart.

Gauge chart with long-outage selected in pink. Its line has a gap from about 05:05 to 05:08 and a connected zero-valued interval from 05:11 to 05:12, marked min 0. A continuous blue series and a cyan series with several gaps remain visible. The details pane shows the selected long-outage row and its datapoints, with 205 in total.

8. Find logs and events in the trace timeline

Span events and correlated logs now appear together in the waterfall (both are invited to the Span Event API deprecation party). Hover over the circles to see span activity, with nearby markers sharing a popover. Choose an event to inspect its attributes, or follow a correlated log to its full record.

9. Add new columns to the trace waterfall view

Spans are full of good information! When you are looking at a trace you might want more info than just the span name and service. For example, add the agent’s phase and step number as columns to compare them across spans without opening each one.

10. Customize columns and inspect structured logs

Similar to the trace view, you can now also customize your columns in the log view! The table also has severity filters and error navigation. Select a log to inspect its body and expand nested data, such as the tool result and error details below. Use Collapse all and Expand all to fold or unfold the whole body at once.

11. Explore telemetry from the service map

If you’re running your own fleet of services during development, the service map on Home gives you a quick way to find the latest telemetry from a particular service. Click a service to browse the telemetry it emitted in the details pane. The results follow your current search and time range.

Other niceties

Home’s service map with api-gateway selected and its colour picker open. The picker shows a blue colour field, hue slider, hex value, shade swatches and a reset control, with connected services visible behind it.

Try it out

Install otel-desktop-viewer, point an OTLP exporter at it and your telemetry shows up in the browser. Everything shown here is in 0.7.0.

The agent-facing changes need a post of their own. That’s next.