






















@@ -81,6 +81,10 @@ type ModelCallLifecycleDiagnosticEvent = Extract<
8181DiagnosticEventPayload,
8282{ type: "model.call.completed" | "model.call.error" }
8383>;
84+type HarnessRunLifecycleDiagnosticEvent = Extract<
85+DiagnosticEventPayload,
86+{ type: "harness.run.completed" | "harness.run.error" }
87+>;
8488type TelemetryExporterDiagnosticEvent = Extract<
8589DiagnosticEventPayload,
8690{ type: "telemetry.exporter" }
@@ -720,6 +724,10 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
720724unit: "ms",
721725description: "Agent run duration",
722726});
727+const harnessDurationHistogram = meter.createHistogram("openclaw.harness.duration_ms", {
728+unit: "ms",
729+description: "Agent harness lifecycle duration",
730+});
723731const contextHistogram = meter.createHistogram("openclaw.context.tokens", {
724732unit: "1",
725733description: "Context window size and usage",
@@ -1426,6 +1434,82 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
14261434span.end(evt.ts);
14271435};
142814361437+const harnessRunMetricAttrs = (evt: HarnessRunLifecycleDiagnosticEvent) => ({
1438+"openclaw.harness.id": lowCardinalityAttr(evt.harnessId, "unknown"),
1439+"openclaw.harness.plugin": lowCardinalityAttr(evt.pluginId),
1440+"openclaw.outcome": evt.type === "harness.run.error" ? "error" : evt.outcome,
1441+"openclaw.provider": lowCardinalityAttr(evt.provider, "unknown"),
1442+"openclaw.model": lowCardinalityAttr(evt.model, "unknown"),
1443+ ...(evt.channel ? { "openclaw.channel": lowCardinalityAttr(evt.channel) } : {}),
1444+});
1445+1446+const recordHarnessRunCompleted = (
1447+evt: Extract<DiagnosticEventPayload, { type: "harness.run.completed" }>,
1448+metadata: DiagnosticEventMetadata,
1449+) => {
1450+harnessDurationHistogram.record(evt.durationMs, harnessRunMetricAttrs(evt));
1451+if (!tracesEnabled) {
1452+return;
1453+}
1454+const spanAttrs: Record<string, string | number | boolean> = {
1455+ ...harnessRunMetricAttrs(evt),
1456+};
1457+if (evt.resultClassification) {
1458+spanAttrs["openclaw.harness.result_classification"] = lowCardinalityAttr(
1459+evt.resultClassification,
1460+);
1461+}
1462+if (typeof evt.yieldDetected === "boolean") {
1463+spanAttrs["openclaw.harness.yield_detected"] = evt.yieldDetected;
1464+}
1465+if (evt.itemLifecycle) {
1466+spanAttrs["openclaw.harness.items.started"] = evt.itemLifecycle.startedCount;
1467+spanAttrs["openclaw.harness.items.completed"] = evt.itemLifecycle.completedCount;
1468+spanAttrs["openclaw.harness.items.active"] = evt.itemLifecycle.activeCount;
1469+}
1470+const span = spanWithDuration("openclaw.harness.run", spanAttrs, evt.durationMs, {
1471+parentContext: contextForTrustedDiagnosticSpanParent(evt, metadata),
1472+endTimeMs: evt.ts,
1473+});
1474+if (evt.outcome === "error") {
1475+span.setStatus({
1476+code: SpanStatusCode.ERROR,
1477+message: "error",
1478+});
1479+}
1480+span.end(evt.ts);
1481+};
1482+1483+const recordHarnessRunError = (
1484+evt: Extract<DiagnosticEventPayload, { type: "harness.run.error" }>,
1485+metadata: DiagnosticEventMetadata,
1486+) => {
1487+const errorType = lowCardinalityAttr(evt.errorCategory, "other");
1488+const attrs = {
1489+ ...harnessRunMetricAttrs(evt),
1490+"openclaw.harness.phase": evt.phase,
1491+"openclaw.errorCategory": errorType,
1492+};
1493+harnessDurationHistogram.record(evt.durationMs, attrs);
1494+if (!tracesEnabled) {
1495+return;
1496+}
1497+const spanAttrs: Record<string, string | number | boolean> = {
1498+ ...attrs,
1499+"error.type": errorType,
1500+ ...(evt.cleanupFailed ? { "openclaw.harness.cleanup_failed": true } : {}),
1501+};
1502+const span = spanWithDuration("openclaw.harness.run", spanAttrs, evt.durationMs, {
1503+parentContext: contextForTrustedDiagnosticSpanParent(evt, metadata),
1504+endTimeMs: evt.ts,
1505+});
1506+span.setStatus({
1507+code: SpanStatusCode.ERROR,
1508+message: errorType,
1509+});
1510+span.end(evt.ts);
1511+};
1512+14291513const recordContextAssembled = (
14301514evt: Extract<DiagnosticEventPayload, { type: "context.assembled" }>,
14311515metadata: DiagnosticEventMetadata,
@@ -1746,6 +1830,12 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
17461830case "run.completed":
17471831recordRunCompleted(evt, metadata);
17481832return;
1833+case "harness.run.completed":
1834+recordHarnessRunCompleted(evt, metadata);
1835+return;
1836+case "harness.run.error":
1837+recordHarnessRunError(evt, metadata);
1838+return;
17491839case "context.assembled":
17501840recordContextAssembled(evt, metadata);
17511841return;
@@ -1781,6 +1871,7 @@ export function createDiagnosticsOtelService(): OpenClawPluginService {
17811871return;
17821872case "tool.execution.started":
17831873case "run.started":
1874+case "harness.run.started":
17841875case "model.call.started":
17851876case "payload.large":
17861877return;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。