




















@@ -55,6 +55,9 @@ const GEN_AI_LATEST_EXPERIMENTAL_OPT_IN = "gen_ai_latest_experimental";
5555const GEN_AI_TOKEN_USAGE_BUCKETS = [
56561, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864,
5757];
58+const GEN_AI_OPERATION_DURATION_BUCKETS = [
59+0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, 20.48, 40.96, 81.92,
60+];
58615962type OtelContentCapturePolicy = {
6063inputMessages: boolean;
@@ -585,6 +588,16 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
585588explicitBucketBoundaries: GEN_AI_TOKEN_USAGE_BUCKETS,
586589},
587590});
591+const genAiOperationDurationHistogram = meter.createHistogram(
592+"gen_ai.client.operation.duration",
593+{
594+unit: "s",
595+description: "GenAI client operation duration",
596+advice: {
597+explicitBucketBoundaries: GEN_AI_OPERATION_DURATION_BUCKETS,
598+},
599+},
600+);
588601const costCounter = meter.createCounter("openclaw.cost.usd", {
589602unit: "1",
590603description: "Estimated model cost (USD)",
@@ -1307,12 +1320,25 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
13071320"openclaw.api": lowCardinalityAttr(evt.api),
13081321"openclaw.transport": lowCardinalityAttr(evt.transport),
13091322});
1323+const genAiModelCallMetricAttrs = (
1324+evt: ModelCallLifecycleDiagnosticEvent,
1325+errorType?: string,
1326+) => ({
1327+"gen_ai.operation.name": genAiOperationName(evt.api),
1328+"gen_ai.provider.name": lowCardinalityAttr(evt.provider),
1329+"gen_ai.request.model": lowCardinalityAttr(evt.model),
1330+ ...(errorType ? { "error.type": errorType } : {}),
1331+});
1310133213111333const recordModelCallCompleted = (
13121334evt: Extract<DiagnosticEventPayload, { type: "model.call.completed" }>,
13131335metadata: DiagnosticEventMetadata,
13141336) => {
13151337modelCallDurationHistogram.record(evt.durationMs, modelCallMetricAttrs(evt));
1338+genAiOperationDurationHistogram.record(
1339+evt.durationMs / 1000,
1340+genAiModelCallMetricAttrs(evt),
1341+);
13161342if (!tracesEnabled) {
13171343return;
13181344}
@@ -1344,18 +1370,23 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
13441370evt: Extract<DiagnosticEventPayload, { type: "model.call.error" }>,
13451371metadata: DiagnosticEventMetadata,
13461372) => {
1373+const errorType = lowCardinalityAttr(evt.errorCategory, "other");
13471374modelCallDurationHistogram.record(evt.durationMs, {
13481375 ...modelCallMetricAttrs(evt),
1349-"openclaw.errorCategory": lowCardinalityAttr(evt.errorCategory, "other"),
1376+"openclaw.errorCategory": errorType,
13501377});
1378+genAiOperationDurationHistogram.record(
1379+evt.durationMs / 1000,
1380+genAiModelCallMetricAttrs(evt, errorType),
1381+);
13511382if (!tracesEnabled) {
13521383return;
13531384}
13541385const spanAttrs: Record<string, string | number | boolean> = {
13551386"openclaw.provider": evt.provider,
13561387"openclaw.model": evt.model,
1357-"openclaw.errorCategory": lowCardinalityAttr(evt.errorCategory, "other"),
1358-"error.type": lowCardinalityAttr(evt.errorCategory, "other"),
1388+"openclaw.errorCategory": errorType,
1389+"error.type": errorType,
13591390};
13601391assignGenAiModelCallAttrs(spanAttrs, evt);
13611392if (evt.api) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。