CMDC.Telemetry (cmdc v0.4.0)

Copy Markdown View Source

CMDC 标准 :telemetry 事件契约 — Phase 12 12G.

对标 deepagents 的 OTel 集成模式 + LangSmith/Langfuse 同源消费协议。 CMDC 核心库只广播事件,不内嵌任何 sink;用户可挂任意 handler 到 Langfuse / LangSmith / Grafana Tempo / Datadog / Splunk 等。

设计原则

  1. 零强制依赖:telemetry 已是 BEAM 生态事实标准,CMDC 仅广播
  2. 事件命名稳定:v0.4 锁定 schema,向后兼容
  3. metadata 白名单:明确列出 metadata 字段,避免泄露敏感数据
  4. 与现有 EventBus 互补:EventBus 走 PubSub 给业务订阅者, Telemetry 走 handler 给可观测性栈

事件清单(v0.4.0)

事件名触发时机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?

与 11G.01 :tool_execution_metrics 的关系

11G.01 通过 EventBus 广播 :tool_execution_metrics 业务事件(per-session 订阅)。 12G.3 通过 :telemetry.execute/3 广播 [:cmdc, :tool, :exec, :*] 全局事件 (system-wide 监控)。两者数据字段一致,触发点合并在 Agent.ToolRunner 内。

v0.4.0 实现说明

  • emitter 桥接模式Agent.Emitter.broadcast/2 在广播 EventBus 事件的同时, 把 6 个核心事件映射到 telemetry(无需改 ToolRunner / Provider)
  • schema 版本号:所有事件 metadata 含 schema_version: 1
  • 用户用 :telemetry.attach/4CMDC.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

all_events()

@spec all_events() :: [[atom()]]

返回 CMDC.Telemetry 所有事件列表。

attach_logger(opts \\ [])

@spec attach_logger(keyword()) :: :ok | {:error, term()}

附加一个开发期 Logger handler,把所有 CMDC telemetry 事件打到 console。

生产环境请用 :telemetry.attach_many/4 接入实际可观测性栈。

bridge_event(session_id, event)

@spec bridge_event(String.t(), term()) :: :ok

从 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](11G.01 兼容路径)

其他事件不映射(继续走 EventBus)。

detach_logger(opts \\ [])

@spec detach_logger(keyword()) :: :ok | {:error, :not_found}

Detach Logger handler。

execute(event_name, measurements, metadata)

@spec execute([atom()], map(), map()) :: :ok

执行 telemetry 事件 — 内部桥接使用。

自动加 schema_version: 1 到 metadata。

schema_version()

@spec schema_version() :: pos_integer()

返回 telemetry schema 版本号。