mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:50:43 +00:00
feat(diagnostics-otel): add context assembly spans
This commit is contained in:
@@ -989,6 +989,67 @@ describe("diagnostics-otel service", () => {
|
||||
await service.stop?.(ctx);
|
||||
});
|
||||
|
||||
test("exports trusted context assembly spans without prompt content", async () => {
|
||||
const service = createDiagnosticsOtelService();
|
||||
const ctx = createOtelContext(OTEL_TEST_ENDPOINT, { traces: true, metrics: true });
|
||||
await service.start(ctx);
|
||||
|
||||
emitTrustedDiagnosticEvent({
|
||||
type: "context.assembled",
|
||||
runId: "run-1",
|
||||
sessionKey: "session-key",
|
||||
sessionId: "session-id",
|
||||
provider: "openai",
|
||||
model: "gpt-5.4",
|
||||
channel: "webchat",
|
||||
trigger: "message",
|
||||
messageCount: 12,
|
||||
historyTextChars: 1234,
|
||||
historyImageBlocks: 2,
|
||||
maxMessageTextChars: 456,
|
||||
systemPromptChars: 789,
|
||||
promptChars: 42,
|
||||
promptImages: 1,
|
||||
contextTokenBudget: 128_000,
|
||||
reserveTokens: 4096,
|
||||
trace: {
|
||||
traceId: TRACE_ID,
|
||||
spanId: GRANDCHILD_SPAN_ID,
|
||||
parentSpanId: SPAN_ID,
|
||||
traceFlags: "01",
|
||||
},
|
||||
});
|
||||
await flushDiagnosticEvents();
|
||||
|
||||
const contextCall = telemetryState.tracer.startSpan.mock.calls.find(
|
||||
(call) => call[0] === "openclaw.context.assembled",
|
||||
);
|
||||
expect(contextCall?.[1]).toMatchObject({
|
||||
attributes: {
|
||||
"openclaw.provider": "openai",
|
||||
"openclaw.model": "gpt-5.4",
|
||||
"openclaw.channel": "webchat",
|
||||
"openclaw.trigger": "message",
|
||||
"openclaw.context.message_count": 12,
|
||||
"openclaw.context.history_text_chars": 1234,
|
||||
"openclaw.context.history_image_blocks": 2,
|
||||
"openclaw.context.max_message_text_chars": 456,
|
||||
"openclaw.context.system_prompt_chars": 789,
|
||||
"openclaw.context.prompt_chars": 42,
|
||||
"openclaw.context.prompt_images": 1,
|
||||
"openclaw.context.token_budget": 128_000,
|
||||
"openclaw.context.reserve_tokens": 4096,
|
||||
},
|
||||
});
|
||||
expect(JSON.stringify(contextCall)).not.toContain("session-key");
|
||||
expect(JSON.stringify(contextCall)).not.toContain("prompt text");
|
||||
expect(telemetryState.tracer.setSpanContext).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
expect.objectContaining({ traceId: TRACE_ID, spanId: SPAN_ID }),
|
||||
);
|
||||
await service.stop?.(ctx);
|
||||
});
|
||||
|
||||
test("parents trusted diagnostic lifecycle spans from explicit parent ids", async () => {
|
||||
const service = createDiagnosticsOtelService();
|
||||
const ctx = createOtelContext(OTEL_TEST_ENDPOINT, { traces: true, metrics: true });
|
||||
|
||||
@@ -1129,6 +1129,36 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
|
||||
span.end(evt.ts);
|
||||
};
|
||||
|
||||
const recordContextAssembled = (
|
||||
evt: Extract<DiagnosticEventPayload, { type: "context.assembled" }>,
|
||||
metadata: DiagnosticEventMetadata,
|
||||
) => {
|
||||
if (!tracesEnabled) {
|
||||
return;
|
||||
}
|
||||
const spanAttrs: Record<string, string | number | boolean> = {
|
||||
"openclaw.context.message_count": evt.messageCount,
|
||||
"openclaw.context.history_text_chars": evt.historyTextChars,
|
||||
"openclaw.context.history_image_blocks": evt.historyImageBlocks,
|
||||
"openclaw.context.max_message_text_chars": evt.maxMessageTextChars,
|
||||
"openclaw.context.system_prompt_chars": evt.systemPromptChars,
|
||||
"openclaw.context.prompt_chars": evt.promptChars,
|
||||
"openclaw.context.prompt_images": evt.promptImages,
|
||||
};
|
||||
addRunAttrs(spanAttrs, evt);
|
||||
if (evt.contextTokenBudget !== undefined) {
|
||||
spanAttrs["openclaw.context.token_budget"] = evt.contextTokenBudget;
|
||||
}
|
||||
if (evt.reserveTokens !== undefined) {
|
||||
spanAttrs["openclaw.context.reserve_tokens"] = evt.reserveTokens;
|
||||
}
|
||||
const span = spanWithDuration("openclaw.context.assembled", spanAttrs, 0, {
|
||||
parentContext: contextForTrustedDiagnosticSpanParent(evt, metadata),
|
||||
endTimeMs: evt.ts,
|
||||
});
|
||||
span.end(evt.ts);
|
||||
};
|
||||
|
||||
const modelCallMetricAttrs = (evt: ModelCallLifecycleDiagnosticEvent) => ({
|
||||
"openclaw.provider": evt.provider,
|
||||
"openclaw.model": evt.model,
|
||||
@@ -1383,6 +1413,9 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
|
||||
case "run.completed":
|
||||
recordRunCompleted(evt, metadata);
|
||||
return;
|
||||
case "context.assembled":
|
||||
recordContextAssembled(evt, metadata);
|
||||
return;
|
||||
case "model.call.completed":
|
||||
recordModelCallCompleted(evt, metadata);
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user