概述
add-telemetry 是一个用于在 Warp 代码库中添加遥测事件、追踪用户行为或系统事件的技能。它适用于为新功能埋点、调试问题或衡量产品使用情况。
Warp 使用基于 trait 的遥测系统,其中各功能专属的枚举实现 TelemetryEvent trait。这种方式使遥测事件按领域组织,而不是集中在一个庞大的枚举中。
重要:在实现遥测之前,应先与用户协作完成以下事项:
- 定义需要追踪哪些事件以及何时追踪;
- 确定每个事件应包含哪些数据;
- 明确遥测的目的与预期用法。
添加遥测代码本身很简单,但设计有意义的埋点需要仔细思考。
主要步骤
1. 识别或创建遥测模块
查找现有的功能专属遥测文件(例如 app/src/antivirus/telemetry.rs),或为你的功能领域新建一个。
2. 定义遥测事件枚举
在实现了 TelemetryEvent 的枚举中新增变体,或新建一个枚举:
use serde_json::{json, Value};
use strum_macros::{EnumDiscriminants, EnumIter};
use warp_core::telemetry::{EnablementState, TelemetryEvent, TelemetryEventDesc};
#[derive(Debug, EnumDiscriminants)]
#[strum_discriminants(derive(EnumIter))]
pub enum YourFeatureTelemetryEvent {
ActionStarted {
duration_ms: u64,
},
ActionCompleted {
success: bool,
error: Option<String>,
},
}
3. 实现 TelemetryEvent trait
EnablementState 用于控制事件何时发送:
- EnablementState::Always - 始终发送事件
- EnablementState::Flag(FeatureFlag::YourFeature) - 仅在功能标志启用时发送
- EnablementState::Channel(Channel::Dev) - 仅在特定构建通道中发送
impl TelemetryEvent for YourFeatureTelemetryEvent {
fn name(&self) -> &'static str {
YourFeatureTelemetryEventDiscriminants::from(self).name()
}
fn payload(&self) -> Option<Value> {
match self {
Self::ActionStarted { duration_ms } => Some(json!({
"duration_ms": duration_ms,
})),
Self::ActionCompleted { success, error } => Some(json!({
"success": success,
"error": error,
})),
}
}
fn description(&self) -> &'static str {
YourFeatureTelemetryEventDiscriminants::from(self).description()
}
fn enablement_state(&self) -> EnablementState {
YourFeatureTelemetryEventDiscriminants::from(self).enablement_state()
}
fn contains_ugc(&self) -> bool {
match self {
Self::ActionStarted { .. } => false,
Self::ActionCompleted { .. } => false,
}
}
fn event_descs() -> impl Iterator<Item = Box<dyn TelemetryEventDesc>> {
warp_core::telemetry::enum_events::<Self>()
}
}
4. 为判别项实现 TelemetryEventDesc
impl TelemetryEventDesc for YourFeatureTelemetryEventDiscriminants {
fn name(&self) -> &'static str {
match self {
Self::ActionStarted => "YourFeature.Action.Started",
Self::ActionCompleted => "YourFeature.Action.Completed",
}
}
fn description(&self) -> &'static str {
match self {
Self::ActionStarted => "User started the action",
Self::ActionCompleted => "User completed the action",
}
}
fn enablement_state(&self) -> EnablementState {
match self {
Self::ActionStarted | Self::ActionCompleted => EnablementState::Always,
// Or gate behind a feature flag:
// EnablementState::Flag(FeatureFlag::YourFeature)
}
}
}
5. 注册遥测事件
在遥测模块末尾注册事件:
warp_core::register_telemetry_event!(YourFeatureTelemetryEvent);
6. 从代码中发送遥测事件
在带有 ViewContext 或 ModelContext 的视图或模型中使用 send_telemetry_from_ctx!:
use warp_core::send_telemetry_from_ctx;
// In a view update or model method
send_telemetry_from_ctx!(
YourFeatureTelemetryEvent::ActionStarted {
duration_ms: 150,
},
ctx
);
对于只有 AppContext 的代码,改用 send_telemetry_from_app_ctx!。
7. 本地测试
使用 log_named_telemetry_events 功能标志运行 Warp,以在控制台查看遥测事件日志:
cargo run --features log_named_telemetry_events
最佳实践
- 保持遥测枚举按功能划分,而不是添加到全局枚举中;
- 如果载荷包含用户生成内容,将 contains_ugc() 设为 true;
- 使用描述性事件名称,遵循 Feature.Action.Result 模式;
- 载荷中只包含必要数据,以最小化带宽与存储占用;
- 在决定包含哪些数据时考虑隐私影响;
- 避免使用通配符进行穷尽匹配;显式处理所有变体。
示例参考
完整的、功能专属遥测实现示例见 app/src/antivirus/telemetry.rs。