@ agentium/可观察性
瞄准式追踪、计量和结构化伐木。 默认抓取政策保留了有限度的生命周期元数据和用法;在保留或交付前,排除了提示、工具参数/结果、输出文本和出错机构.
import { instrument, OTelExporter } from "@agentium/observability";
const observation = instrument(agent, {
exporters: [new OTelExporter({ endpoint: "http://127.0.0.1:4318" })],
metrics: true,
onDiagnostic: ({ code }) => telemetryHealth.increment(code),
});
await agent.run("Hello");
await observation.shutdown();
instrumentBus(eventBus, options) 支持共享巴士. detach() 删除此观察者的订阅; shutdown() 此外,在规定的期限内还排出所有的工作。 附件是每辆公交车的一等能,拆卸一等能保存一等能保存一等能. 关闭的观察者不能再被附着.
观察和捕获
核心 EventBus 订阅仅限观察:命名和 onAny 听众们按照他们现有的顺序,不等待承诺而奔跑。 放弃的例外或拒绝的承诺不会跳过以后的观察者或改变代理人/工具的结果. once, (中文(简体) ), off 并始终支持听众身份。 控制钩,执行政策和批准仍然是明确的控制API,并保留其有意的失败行为.
new EventBus({ onObserverError, maxObserverDiagnostics: 100 }) 报告有限度的、非重复性的观察失败。 诊断回调为主机所有,可能看到原出错误,并且从未隐含地记录. getObserverDiagnostics() 报告全部、报告和压制了失败。 遥测是分开的 onDiagnostic 获得无有效载荷代码;诊断回调失败也被隔离.
移徙: 前一个自动内容抓取被删除。 选择出口者不是内容许可 。 为了保留内容,在追踪器和每个明确建造的目的地选择:
const capture = {
mode: "content" as const,
redact(path: string, value: unknown) {
if (path === "userId" || path.endsWith(".email")) return undefined;
return value;
},
maxAttributeBytes: 2048,
maxTotalBytes: 16384,
};
const observation = instrument(agent, {
capture,
exporters: [new JsonFileExporter({ path: "traces.jsonl", capture })],
});
短手出口商继承了工具抓取选项. 直接回调,控制台,文件,OTel和Langfuse出口商独立应用抓取,因此不安全的外部提供追踪是不默示信任的. 内容模式在明确界限内保留了原来的有效载荷能力;它从未包括出错堆. 已知的证书键场总是被去除,包括被巢地. 文本本身可能包含敏感数据,因此在获取内容时提供应用程序重排器. 编辑器是同步的;意外承诺随着拒绝处理而放弃. 循环、 二进制值、 深对象和超大小值的处理没有任意性 toJSON 打电话.
元数据包括代理/工具/型号名称、运行/会话/用户/租户和母/根/试标识、使用、费用和结果。 这些标识符也可以是个人数据:根据需要对其进行编辑. 任意自定义属性在元数据模式中被排除在外. 模拟生命周期事件包含身份和用途,而不是完整的请求/答复机构;内容选入不会编造生产者无法提供的数据.
边界和生命周期
| 约束 | 默认 | 配置 |
|---|---|---|
| 导出队列,包括飞行中的工作 | 128个记录、4个小B、2个并行记录 | maxQueuedExports, (中文(简体) ), maxQueuedBytes, (中文(简体) ), maxInFlight |
| 浮出水面/下沉等待 | 5秒钟 | flushTimeoutMs |
| 跟踪保留 | 1 000个痕迹,8个米B,1小时 | TracerOptions.maxTraces, (中文(简体) ), maxRetainedBytes, (中文(简体) ), retentionMs |
| 每个痕数/ 间距 | 256个跨度/64个事件 | maxSpansPerTrace, (中文(简体) ), maxEventsPerSpan |
| 属性抓取 | 64个田地,每地2个基B,16个基B合计 | capture.maxAttributes, (中文(简体) ), maxAttributeBytes, (中文(简体) ), maxTotalBytes |
| 直接出口追踪捕捉 | 1个米B,最多256个跨度,每跨度64个活动 | capture.maxTraceBytes 加固定结构盖 |
| 保全量 | 1 000个记录/活性运行、10 000个活性工具/图像条目、256个代理标签 | AccountingOptions |
| 盘盘流 | 32个订户,128个记录/每个订户256公斤 | MetricsExporterOptions |
| 诊断性召回 | 每个组成部分寿命100个 | maxDiagnostics |
导出队列在完整时会降下最新记录 。 追踪保留会驱逐最老的条目;超限跨度/活动被删除。 订阅者缓冲器放下最古老的事件 . getDiagnostics() 显示追踪器、记录器和仪表板上的队列状态/投放计数;出口商通过可选回调来显示诊断。 通过观察/阅读而不是背景计时器检查保留年龄.
慢出口者从来不阻止代理完成. 超时不合作回调人员保留其飞行时段和自有资源;替换工作不能无限制地增长. 关闭中止合作请求并丢弃剩余的队列记录 。 资源关闭被推迟,直到已经启动的出口/溢出工作真正解决,援引一次,并且不能强迫永久停顿的回调进行合作. flush() 是一种有限度的最佳等待,而不是交付保证。 东道方管理的OTel供应商仍然是东道方.
关联性和衡量标准
核心运行/流模式引用 model.start, (中文(简体) ), model.result 或者说 model.error 具有独特性 modelCallId;复议有单独的引用跨度. 工具生产商包括: toolCallId, (中文(简体) ), status 财务报告和审定财务报表 cached 已经知道的地方 同时对同一种工具的调用都配有ID. 只有在一名候选人毫不含糊的情况下,才对缺乏身份证的遗留事件进行匹配。 被拒绝的工具可以在没有调用事件的情况下产生结果,因为授权先于执行;这种拒绝不会发明执行工具跨度.
两种衡量标准都采用相同的会计方法。 终端结果计算一次;取消、停止和等待输入产出不计算成功。 终端运行清晰的活性工具条目,追踪器标记未完成的孩子跨度被中断. 遗产 total_cost_usd 公吨包含按键的每个运行的完整替换总数 runId,包括完成前的活动. known_attempt_cost_usd 从每个选定的数值中分别添加已知的美元价格小计 cost.assessed 尝试修订,包括部分尝试. unpriced_attempts 财务报告和审定财务报表 provisional_attempts 报告覆盖不完整和开立账单的状况;零遗留总额不能证明零成本。 犬科的分科也不消耗 cost.tracked,因此这些衡量标准不能合并。 不包括计费组费用和非美元数额 CostTracker.queryCosts() 对权威总数和分类帐单。 这些事件预测的范围是: getDiagnostics().dropped 报告能力丧失。 费用更新较晚的改动保留了计量标准;已经出口的成品期没有重新使用。 Token 总计使用终端运行用量;无法推断提供者- 内部重试或未报告用量的呼叫失败。 直接自定义 H2 控制器/模型调用 Agent 环外需要主机事件适配器; 核心不依赖于取用运行时间 .
MetricsCollector 计数器/总数自重置后相加;直方图阵列为边框样本. MetricsExporter.getMetrics() 更正/标准合计数为累计数。 普罗米修斯 _total 序列是累积的,而持续时间/速度表则描述保留运行。 标签被取出,多余的代理标签主要归为 __other__计量是过程-局部遥测,不是持久的计费记录.
OTLP 和主机 SDK 集成
OTelExporter 执行 OTLP/HTTP JSON(英语:。 。 。 . protocol: "http/protobuf" 或者不支持的协议环境设置在构造时拒绝。 将主机SDK桥及其所选择的出口商用于原生取出. endpoint 是一个基础 URL 和附件 /v1/traces· ; tracesEndpoint 是一个完整的信号 URL. OTEL_EXPORTER_OTLP_TRACES_ENDPOINT 在未配置时先于通用端点。 信头和服务名接受相应的标准环境设置或明确选项. 端点拒绝嵌入式证书,查询字符串和片段;通过信头传递证书.
Trace/span ID是有效的十六进制,时间戳使用整数纳秒字符串,主机提供的上游上下文通过保存 new Tracer(exporters, { parentContext })。 。 。 . parentContext 可能是经过验证的上下文或主机的回调读取运行的元数据. 任意输入不解释为追踪权威。 选中的映射用途 语义公约 1.3.7.0,包括模型/提供者/使用和工具调用属性; GenAI公约仍在发展之中,现在正在形成一个单独的存储库。 模型跨度是客户端跨度;工具跨度是内部的.
HTTP 200 部分接受报告 otlp_partial_success 和它被拒绝的计数 而不重试接受的跨度。 只有连接故障和HTTP 429/502/503/504被重审,并有后退/Retry-After,共享请求截止日期,以及请求/答复字节限制。 默认:10秒2回,4个米B请求,64个KiB响应. 每个出口都有计时器 接下来是 OTLP 规格;在模糊不清的连接损失之后进行的复述并非完全一交货.
import { ROOT_CONTEXT, trace, createTraceState } from "@opentelemetry/api";
import { OTelBridgeExporter } from "@agentium/observability";
const bridge = new OTelBridgeExporter({
provider: myExistingProvider, // alternatively tracer: myExistingTracer
contextFor(parent) {
return parent ? trace.setSpanContext(ROOT_CONTEXT, {
...parent,
traceFlags: parent.traceFlags ?? 1,
traceState: parent.traceState ? createTraceState(parent.traceState) : undefined,
}) : ROOT_CONTEXT;
},
});
该桥使用供应的SDK,从不注册全球供应商,从不冲出/冲出主机供应商. 主机选择采样,处理器,二进制输出和关闭. 导出完成的跨度使用其原始时间; SDK 生成的本地ID 由 agentium.source.span_id上游的痕量身份证明和儿童关系幸存下来 没有上游家长,SDK拥有新的痕量ID. 没有OTel SDK是强制性的活性剂依赖.
Langfuse 和文件
| 导出者/ 缩写 | 使用 |
|---|---|
LangfuseOTLPExporter 编号 : "langfuse-otlp" | 目前OTLP的终点,基本项目证书, x-langfuse-ingestion-version: 4 |
LangfuseExporter 编号 : "langfuse" | 明确的遗产 /api/public/ingestion 兼容性; 构造时释放的诊断 |
OTelExporter 编号 : "otel" | OTLP/HTTP JSON收集器 |
JsonFileExporter 编号 : "json-file" | 添加默认值到压缩 JSONL; 覆盖默认值到漂亮的 JSON |
ConsoleExporter 编号 : "console" | 被捆绑的微量树 |
CallbackExporter | 主机选中的已消毒回调 |
朗福斯的使用 LANGFUSE_PUBLIC_KEY, (中文(简体) ), LANGFUSE_SECRET_KEY 和可选 LANGFUSE_BASE_URL,或清晰的构造字段。 OTLP绘图输出完成的观测结果,将稀释的痕量/会话/用户元数据复制到每一段,并绘制模型使用图。 没有创建模型/提供者文本 . Langfuse 兼容文档 云痕/观测摄入量 2026年11月16日 (中文(简体) ); 自行托管 v4 events_only 已经拒绝了它。 用它来 v4 移徙指导在一个项目中,不要通过新老摄入路径双向发送同一段;使用单独的金丝雀目的地。 直播账户摄入量和自备版兼容性仍然是部署检查.
JSONL 附录每行写一个独立的可解析对象 。 明确 pretty: true 与附件保存多行后遗症行为,而不是JSONL. mode: "overwrite" 写一个 JSON 文件。 写作失败拒绝直接拨打并发出无有效载荷诊断;仪器输出者将这些失败与执行隔离开来.
核查装置
普通测试包括公共代理效应、观察器故障、捕获/重排、同时呼叫ID、保留/订阅/出口界限、终端结果、重试/部分成功、当地HTTP交付和JSONL。 可选的 SDK/官方解码门需要孤立的固定依赖;没有涉及账户或模型调用:
npm install --prefix /tmp/agentium-otel-fixture --ignore-scripts --no-audit --no-fund \
@opentelemetry/[email protected] @opentelemetry/[email protected] @opentelemetry/[email protected]
python3 -m venv /tmp/agentium-otel-proto-fixture
/tmp/agentium-otel-proto-fixture/bin/pip install opentelemetry-proto==1.38.0 protobuf==6.33.6
AGENTIUM_OTEL_SDK_FIXTURE=/tmp/agentium-otel-fixture \
AGENTIUM_OTEL_PROTO_PYTHON=/tmp/agentium-otel-proto-fixture/bin/python \
npx vitest run packages/observability/src/__tests__/otel-sdk.integration.test.ts
SDK门检查一个真正的提供者/出口者,静态的TypeScript兼容性,母上下文和没有全局突变. 环回接收器在OTLP规定的六字节到字节转换后,以正式的原生自定义发布了请求. 这验证了电线合同,而不是主机采集器的保留,取样或供应商UI行为.
调用控制器和自定义模型调用
通过一个专用 EventBus 作为 HarnessRuntime({ telemetry }),然后调用 instrumentBus(telemetry)自定义执行-服务模式的调用和控制者决定产生相关跨度,即使没有代理循环。 控制器使用 internal 与引用ID、操作、决定、示范角色和主动工具计数相跨;它们不递增模型/工具计数。 运行时遥测省略了提示和响应内容.
从任何包裹的Agent仪器中单独使用一个收集器:Agent和取带层可以共享运行的ID并描述相同的模型引用. 见 远程测量示例现有的出口商调整、保留限额和有限度的停产仍然有效.