CMDC 标准 :telemetry 事件契约。
CMDC 核心库只广播事件,不内嵌任何 sink;用户可挂任意 handler 到 Langfuse / LangSmith / Grafana Tempo / Datadog / Splunk 等。
设计原则
- 零强制依赖:
:telemetry已是 BEAM 生态事实标准,CMDC 仅广播 - 事件命名稳定:锁定 schema,向后兼容
- metadata 白名单:明确列出 metadata 字段,避免泄露敏感数据
- 与现有 EventBus 互补:EventBus 走 PubSub 给业务订阅者, Telemetry 走 handler 给可观测性栈
事件清单
| 事件名 | 触发时机 | metadata |
|---|---|---|
[:cmdc, :agent, :turn, :start] | Agent 单 turn 开始 | session_id, turn |
[:cmdc, :agent, :turn, :stop] | Agent 单 turn 结束 | session_id, turn, duration_ms, outcome |
[:cmdc, :llm, :request, :start] | LLM 调用前 | session_id, turn, model |
[:cmdc, :llm, :request, :stop] | LLM 调用后 | session_id, turn, model, tokens_in, tokens_out, duration_ms |
[:cmdc, :tool, :exec, :start] | 工具开始执行 | session_id, tool, call_id |
[:cmdc, :tool, :exec, :stop] | 工具结束 | session_id, tool, call_id, duration_ms, error? |
与 :tool_execution_metrics 业务事件的关系
:tool_execution_metrics 通过 EventBus 广播业务事件(per-session 订阅)。
Telemetry 通过 :telemetry.execute/3 广播 [:cmdc, :tool, :exec, :*] 全局
事件(system-wide 监控)。两者数据字段一致,触发点合并在 Agent 工具执行器内。
实现说明
- emitter 桥接模式:Agent 内部广播器在广播 EventBus 事件的同时, 把 6 个核心事件映射到 telemetry(无需改 ToolRunner / Provider)
- schema 版本号:所有事件 metadata 含
schema_version: 1 - 用户用
:telemetry.attach/4或CMDC.Telemetry.attach_logger/0接入
Quick Start
# 1. attach 默认 logger(开发期)
CMDC.Telemetry.attach_logger()
# 2. attach 自定义 handler(接入 Langfuse)
:telemetry.attach_many(
"my-langfuse-handler",
CMDC.Telemetry.all_events(),
&MyApp.LangfuseHandler.handle/4,
nil
)
# 3. detach
:telemetry.detach("my-langfuse-handler")完整可观测性配方见 docs/recipes/observability/(v0.4.0 提供 Langfuse 示例)。
Summary
Functions
返回 CMDC.Telemetry 所有事件列表。
附加一个开发期 Logger handler,把所有 CMDC telemetry 事件打到 console。
从 EventBus 事件桥接到 telemetry。
Detach Logger handler。
执行 telemetry 事件 — 内部桥接使用。
返回 telemetry schema 版本号。
Functions
@spec all_events() :: [[atom()]]
返回 CMDC.Telemetry 所有事件列表。
附加一个开发期 Logger handler,把所有 CMDC telemetry 事件打到 console。
生产环境请用 :telemetry.attach_many/4 接入实际可观测性栈。
从 EventBus 事件桥接到 telemetry。
由 Agent.Emitter.broadcast/2 调用。映射规则:
| EventBus 事件 | Telemetry 事件 |
|---|---|
{:agent_start, session_id, turn} | [:cmdc, :agent, :turn, :start] |
{:agent_end, payload} (success) | [:cmdc, :agent, :turn, :stop] |
{:llm_request_start, ...} | [:cmdc, :llm, :request, :start] |
{:llm_response, payload} | [:cmdc, :llm, :request, :stop] |
{:tool_started, name, call_id, ...} | [:cmdc, :tool, :exec, :start] |
{:tool_ended, name, call_id, ...} | [:cmdc, :tool, :exec, :stop] |
{:tool_execution_metrics, ...} | [:cmdc, :tool, :exec, :stop](兼容路径) |
其他事件不映射(继续走 EventBus)。
@spec detach_logger(keyword()) :: :ok | {:error, :not_found}
Detach Logger handler。
执行 telemetry 事件 — 内部桥接使用。
自动加 schema_version: 1 到 metadata。
@spec schema_version() :: pos_integer()
返回 telemetry schema 版本号。