mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 12:30:44 +00:00
fix(diagnostics-otel): stabilize genai token metric model attr
This commit is contained in:
@@ -42,6 +42,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Diagnostics/OTEL: add GenAI usage token attributes to model-usage spans, including cache read/write input token counts without session identifiers or prompt/response content. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: include bounded GenAI operation, provider, and request-model attributes on model-usage spans so token usage remains self-describing without diagnostic identifiers. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: keep model-usage span GenAI provider attributes aligned with the existing semantic-convention opt-in policy, using legacy `gen_ai.system` unless latest experimental GenAI conventions are enabled. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: keep `gen_ai.request.model` present on GenAI token usage metrics with a bounded `unknown` fallback when model usage events do not include a model. Thanks @vincentkoc.
|
||||
- Diagnostics/OTEL: add bounded outbound message delivery lifecycle diagnostics and export them as low-cardinality delivery spans/metrics without message body, recipient, room, or media-path data. (#71471) Thanks @vincentkoc and @jlapenna.
|
||||
- Diagnostics/OTEL: emit bounded exec-process diagnostics and export them as `openclaw.exec` spans without exposing command text, working directories, or container identifiers. (#71451) Thanks @vincentkoc and @jlapenna.
|
||||
- Diagnostics/OTEL: support `OPENCLAW_OTEL_PRELOADED=1` so the plugin can reuse an already-registered OpenTelemetry SDK while keeping OpenClaw diagnostic listeners wired. (#71450) Thanks @vincentkoc and @jlapenna.
|
||||
|
||||
@@ -740,6 +740,30 @@ describe("diagnostics-otel service", () => {
|
||||
await service.stop?.(ctx);
|
||||
});
|
||||
|
||||
test("keeps GenAI token usage metric model attribute present when model is unavailable", async () => {
|
||||
const service = createDiagnosticsOtelService();
|
||||
const ctx = createOtelContext(OTEL_TEST_ENDPOINT, { metrics: true });
|
||||
await service.start(ctx);
|
||||
|
||||
emitDiagnosticEvent({
|
||||
type: "model.usage",
|
||||
provider: "openai",
|
||||
usage: { input: 2 },
|
||||
});
|
||||
await flushDiagnosticEvents();
|
||||
|
||||
expect(telemetryState.histograms.get("gen_ai.client.token.usage")?.record).toHaveBeenCalledWith(
|
||||
2,
|
||||
{
|
||||
"gen_ai.operation.name": "chat",
|
||||
"gen_ai.provider.name": "openai",
|
||||
"gen_ai.request.model": "unknown",
|
||||
"gen_ai.token.type": "input",
|
||||
},
|
||||
);
|
||||
await service.stop?.(ctx);
|
||||
});
|
||||
|
||||
test("exports GenAI usage attributes on model usage spans without diagnostic identifiers", async () => {
|
||||
const service = createDiagnosticsOtelService();
|
||||
const ctx = createOtelContext(OTEL_TEST_ENDPOINT, { traces: true });
|
||||
|
||||
@@ -904,7 +904,7 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
|
||||
const genAiAttrs: Record<string, string> = {
|
||||
"gen_ai.operation.name": "chat",
|
||||
"gen_ai.provider.name": lowCardinalityAttr(evt.provider),
|
||||
...(evt.model ? { "gen_ai.request.model": lowCardinalityAttr(evt.model) } : {}),
|
||||
"gen_ai.request.model": lowCardinalityAttr(evt.model),
|
||||
};
|
||||
|
||||
const usage = evt.usage;
|
||||
|
||||
Reference in New Issue
Block a user