Trace Tree UI#
The Trace Tree UI renders a hierarchical, interactive view of OpenTelemetry spans within a trace. It lives in app/src/components/trace/ and is primarily surfaced on the TraceDetails page (app/src/pages/trace/TraceDetails.tsx), where it occupies the left panel of a split-panel layout alongside the SpanDetails view.
Key Components#
TraceTree (TraceTree.tsx)#
The root component. Accepts a flat spans: ISpanItem[] array, the selectedSpanNodeId string, and an optional onSpanClick callback . On mount it converts the flat list into a tree via createSpanTree, wraps everything in a TraceTreeProvider, and renders:
TraceTreeToolbar— header with two toggle buttons: collapse/expand all spans, and show/hide per-span metrics (latency + token count). Collapse state is managed throughTraceTreeContext; metric visibility is persisted inPreferencesContext.SpanTreeItem— recursive component that renders one span node and its children .
Compact mode: when the container width drops below 200px, CSS container queries zero out nesting indentation and hide edge connectors, latency text, token counts, and collapse buttons .
SpanTreeItem (TraceTree.tsx:224)#
Renders a single span as a clickable row inside a SpanNodeWrap. Each row shows:
SpanKindIcon— visual indicator of span kind- Span name (truncated with
text-overflow: ellipsis) SpanStatusCodeIcon— shown only forERRORstatusSpanTokenCount— shown whentokenCountTotal > 0and metrics are enabledLatencyText— shown whenlatencyMs != nulland metrics are enabled
Child spans are rendered recursively in a <ul>, with visual connectors drawn by SpanTreeEdge and SpanTreeEdgeConnector. Both connectors color themselves danger-red for ERROR-status spans . The selected item scrolls into view automatically via scrollIntoView .
A CollapseToggleButton appears on nodes that have children, allowing per-node collapse independent of the global state .
LatencyText (LatencyText.tsx)#
Displays span latency with color-coded severity and an optional clock icon :
| Threshold | Color |
|---|---|
< 3 000 ms | success (green) |
3 000–8 000 ms | warning (yellow) |
≥ 8 000 ms | danger (red) |
Values are auto-scaled: under 10 ms → displayed in ms; 10 ms and above → converted to s . Formatting is delegated to formatFloat from numberFormatUtils.
Supporting Utilities#
createSpanTree / SpanTreeNode (utils.ts)#
createSpanTree<TSpan> converts a flat TSpan[] (constrained to ISpanItem) into SpanTreeNode<TSpan>[]. The node type is:
type SpanTreeNode<TSpan> = { span: TSpan; children: SpanTreeNode<TSpan>[] }
It uses a Map keyed by span ID to link children to parents via parentId, then sorts siblings by startTime.
ISpanItem / SpanStatusCodeType (types.ts)#
ISpanItem is the minimum interface any span object must satisfy to be rendered in the tree:
interface ISpanItem {
id: string; name: string; spanKind: string;
statusCode: SpanStatusCodeType; latencyMs: number | null;
startTime: string; parentId: string | null; spanId: string;
tokenCountTotal?: number | null;
[otherKeys: string]: unknown;
}
SpanStatusCodeType is "OK" | "ERROR" | "UNSET".
numberFormatUtils.ts (numberFormatUtils.ts)#
General-purpose numeric formatting helpers built on d3-format :
| Export | Purpose |
|---|---|
formatFloat | Range-aware float formatting (scientific for < 0.01, 2dp for < 1000, SI suffix above) |
formatInt | Comma-separated integers; SI suffix for ≥ 1 000 000 |
formatNumber | Dispatches to formatInt or formatFloat |
formatCost | Dollar-formatted cost with < $0.01 floor |
createNumberFormatter | Factory that wraps any format fn to return "--" for null/undefined |
| Pre-built formatters | intFormatter, floatFormatter, numberFormatter, percentFormatter, costFormatter |
State Management#
TraceTreeContext provides a single boolean (isCollapsed) scoped to the tree. TraceTreeProvider wraps the tree and exposes setIsCollapsed (wrapped in startTransition for non-urgent updates) . Individual SpanTreeItem nodes sync with this global state via a useEffect, but can also be collapsed independently .
Metric visibility (showMetricsInTraceTree) is persisted in the app-wide PreferencesContext, not in TraceTreeContext .
File Map#
| File | Role |
|---|---|
app/src/components/trace/TraceTree.tsx | Root component + all sub-components |
app/src/components/trace/LatencyText.tsx | Latency display with severity coloring |
app/src/components/trace/TraceTreeContext.tsx | Collapse state context |
app/src/components/trace/types.ts | ISpanItem, SpanStatusCodeType |
app/src/components/trace/utils.ts | createSpanTree, SpanTreeNode |
app/src/utils/numberFormatUtils.ts | Numeric & cost formatting helpers |
app/src/pages/trace/TraceDetails.tsx | Primary consumer of TraceTree |