用途
该技能用于在 trace 视图中添加、修改或调试 OTel span 时间线事件。trace 视图右侧面板会显示所选 span 的事件时间线,这些事件由 app/utils/timelineSpanEvents.ts 和 SpanTimeline 组件渲染。
主要能力
- 处理 OTel span 事件的结构与渲染。
- 处理 ClickHouse 存储约束与事件重组。
- 控制事件在时间线中的显示名称与可见性。
- 指导新增时间线事件的步骤。
工作原理
OTel 中的 span 事件附加到父 span。在 ClickHouse 中,它们以 kind: "SPAN_EVENT" 的独立行存储,与父 span 共享 span_id。#mergeRecordsIntoSpanDetail 方法在查询时将它们重新组装到 span 的 events 数组中。
时间线仅渲染名称以 trigger.dev/ 开头的事件,其他事件会被静默过滤掉。
显示名称来自 properties.event(而非 span 事件名称),并通过 getFriendlyNameForEvent() 映射。
事件显示在其所属的 span 上——一个 span 上的事件不会出现在另一个 span 的时间线中。
ClickHouse 存储约束
当事件写入 ClickHouse 时,spanEventsToTaskEventV1Input() 会过滤掉 start_time 不大于父 span startTime 的事件。等于或早于 span 开始时间的事件会被静默丢弃。这意味着 span 事件的时间戳必须严格晚于 span 自身的 startTimeUnixNano。
时间线渲染(SpanTimeline 组件)
app/components/run/RunTimeline.tsx 中的 SpanTimeline 组件渲染:
- 事件(1px 细线带空心点)——来自 createTimelineSpanEventsFromSpanEvents() 的所有事件
- "Started" 标记(粗端帽)——位于 span 的 startTime
- 时长条(7px 粗线)——从 "Started" 到 "Finished"
- "Finished" 标记(粗端帽)——位于 startTime + duration
"Started" 之前的细线仅在存在时间戳介于 span 开始与第一个子 span 之间的事件时出现。对于 Attempt span 效果良好(Dequeued -> Pod scheduled -> Launched -> 等均发生在执行开始之前)。所有事件获得 lineVariant: "light"(细线),而执行条获得 variant: "normal"(粗线)。
Trace 视图排序
同级 span(同一父级)按 ClickHouse 查询的 start_time ASC 排序。createTreeFromFlatItems 函数保留此顺序。事件时间戳不影响排序顺序——仅 span 自身的 start_time 影响。
事件结构
// OTel span event format
{
name: "trigger.dev/run", // Must start with "trigger.dev/" to render
timeUnixNano: "1711200000000000000",
attributes: [
{ key: "event", value: { stringValue: "dequeue" } }, // The actual event type
{ key: "duration", value: { intValue: 150 } }, // Optional: duration in ms
]
}
仅管理员可见的事件
getAdminOnlyForEvent() 控制可见性。事件默认仅管理员可见(true)。
| Event | Admin-only | Friendly name |
|---|---|---|
| dequeue | No | Dequeued |
| fork | No | Launched |
| import | No (if no fork event) | Importing task file |
| create_attempt | Yes | Attempt created |
| lazy_payload | Yes | Lazy attempt initialized |
| pod_scheduled | Yes | Pod scheduled |
| (default) | Yes | (raw event name) |
新增时间线事件
- 添加 OTLP span 事件,name: "trigger.dev/<scope>",properties.event: "<type>"
- 事件时间戳必须严格晚于父 span 的 startTimeUnixNano(ClickHouse 会丢弃更早的事件)
- 在 app/utils/timelineSpanEvents.ts 的 getFriendlyNameForEvent() 中添加友好名称
- 在 getAdminOnlyForEvent() 中设置管理员可见性
- 可选:在 getHelpTextForEvent() 中添加帮助文本
关键文件
- app/utils/timelineSpanEvents.ts —— 过滤、命名、管理员逻辑
- app/components/run/RunTimeline.tsx —— SpanTimeline 组件(细线 + 粗条渲染)
- app/presenters/v3/SpanPresenter.server.ts —— 加载 span 数据(含事件)
- app/v3/eventRepository/clickhouseEventRepository.server.ts —— spanEventsToTaskEventV1Input()(存储过滤)、#mergeRecordsIntoSpanDetail(重组)
适用场景
适用于在 trace 视图中处理 OTel span 时间线事件的开发与调试场景,尤其是涉及 trigger.dev 事件渲染、ClickHouse 存储过滤和事件可见性配置时。
限制
- 时间线仅渲染名称以 trigger.dev/ 开头的事件。
- 事件时间戳必须严格晚于父 span 的 startTimeUnixNano,否则会被 ClickHouse 静默丢弃。
- 事件默认仅管理员可见。
- 事件时间戳不影响同级 span 的排序顺序。