@openclaw/diagnostics-prometheus 2026.5.24-beta.1 → 2026.5.25-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +2 -1
- package/dist/index.js +96 -4
- package/npm-shrinkwrap.json +2 -2
- package/package.json +4 -4
package/dist/api.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
|
+
import { isInternalDiagnosticEventMetadata } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
2
3
|
import { redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
|
|
3
|
-
export { emptyPluginConfigSchema, redactSensitiveText };
|
|
4
|
+
export { emptyPluginConfigSchema, isInternalDiagnosticEventMetadata, redactSensitiveText };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { redactSensitiveText } from "./api.js";
|
|
1
|
+
import { isInternalDiagnosticEventMetadata, redactSensitiveText } from "./api.js";
|
|
2
2
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
3
3
|
//#region extensions/diagnostics-prometheus/src/service.ts
|
|
4
4
|
const DURATION_BUCKETS_SECONDS = [
|
|
@@ -47,6 +47,19 @@ const BYTE_BUCKETS = [
|
|
|
47
47
|
4294967296,
|
|
48
48
|
17179869184
|
|
49
49
|
];
|
|
50
|
+
const RATIO_BUCKETS = [
|
|
51
|
+
.01,
|
|
52
|
+
.05,
|
|
53
|
+
.1,
|
|
54
|
+
.25,
|
|
55
|
+
.5,
|
|
56
|
+
.75,
|
|
57
|
+
1,
|
|
58
|
+
2,
|
|
59
|
+
4,
|
|
60
|
+
8,
|
|
61
|
+
16
|
|
62
|
+
];
|
|
50
63
|
const LOW_CARDINALITY_VALUE_RE = /^[A-Za-z0-9_.:-]{1,120}$/u;
|
|
51
64
|
const MAX_PROMETHEUS_SERIES = 2048;
|
|
52
65
|
const DROPPED_SERIES_COUNTER_NAME = "openclaw_prometheus_series_dropped_total";
|
|
@@ -183,6 +196,9 @@ function createPrometheusMetricStore() {
|
|
|
183
196
|
function safeErrorMessage(err) {
|
|
184
197
|
return redactSensitiveText(err instanceof Error ? err.message ?? err.name : String(err)).replaceAll("\0", " ").replace(/[\r\n\t\u2028\u2029]/gu, " ").slice(0, 500);
|
|
185
198
|
}
|
|
199
|
+
function shouldRecordDiagnosticEvent(metadata) {
|
|
200
|
+
return metadata.trusted || isInternalDiagnosticEventMetadata(metadata);
|
|
201
|
+
}
|
|
186
202
|
function renderPrometheusMetrics(store) {
|
|
187
203
|
const snapshot = store.snapshot();
|
|
188
204
|
const lines = [];
|
|
@@ -247,6 +263,17 @@ function modelCallLabels(evt) {
|
|
|
247
263
|
transport: lowCardinalityLabel(evt.transport)
|
|
248
264
|
};
|
|
249
265
|
}
|
|
266
|
+
function modelFailoverLabels(evt) {
|
|
267
|
+
return {
|
|
268
|
+
from_model: lowCardinalityLabel(evt.fromModel),
|
|
269
|
+
from_provider: lowCardinalityLabel(evt.fromProvider),
|
|
270
|
+
lane: lowCardinalityQueueLaneLabel(evt.lane),
|
|
271
|
+
reason: lowCardinalityLabel(evt.reason, "other"),
|
|
272
|
+
suspended: evt.suspended === void 0 ? "unknown" : String(evt.suspended),
|
|
273
|
+
to_model: lowCardinalityLabel(evt.toModel),
|
|
274
|
+
to_provider: lowCardinalityLabel(evt.toProvider)
|
|
275
|
+
};
|
|
276
|
+
}
|
|
250
277
|
function toolExecutionLabels(evt) {
|
|
251
278
|
return {
|
|
252
279
|
error_category: evt.type === "tool.execution.error" ? lowCardinalityLabel(evt.errorCategory, "other") : "none",
|
|
@@ -257,6 +284,15 @@ function toolExecutionLabels(evt) {
|
|
|
257
284
|
tool_source: lowCardinalityLabel(evt.toolSource, "core")
|
|
258
285
|
};
|
|
259
286
|
}
|
|
287
|
+
function toolExecutionBlockedLabels(evt) {
|
|
288
|
+
return {
|
|
289
|
+
denied_reason: lowCardinalityLabel(evt.deniedReason, "other"),
|
|
290
|
+
params_kind: lowCardinalityLabel(evt.paramsSummary?.kind),
|
|
291
|
+
tool: lowCardinalityLabel(evt.toolName, "tool"),
|
|
292
|
+
tool_owner: lowCardinalityLabel(evt.toolOwner, "none"),
|
|
293
|
+
tool_source: lowCardinalityLabel(evt.toolSource, "core")
|
|
294
|
+
};
|
|
295
|
+
}
|
|
260
296
|
function skillLabels(evt) {
|
|
261
297
|
return {
|
|
262
298
|
activation: lowCardinalityLabel(evt.activation, "unknown"),
|
|
@@ -277,6 +313,18 @@ function harnessLabels(evt) {
|
|
|
277
313
|
provider: lowCardinalityLabel(evt.provider)
|
|
278
314
|
};
|
|
279
315
|
}
|
|
316
|
+
function webhookLabels(evt) {
|
|
317
|
+
return {
|
|
318
|
+
channel: lowCardinalityLabel(evt.channel),
|
|
319
|
+
webhook: lowCardinalityLabel(evt.updateType)
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
function sessionStuckLabels(evt) {
|
|
323
|
+
return {
|
|
324
|
+
reason: lowCardinalityLabel(evt.reason, "none"),
|
|
325
|
+
state: evt.state
|
|
326
|
+
};
|
|
327
|
+
}
|
|
280
328
|
function sessionRecoveryLabels(evt) {
|
|
281
329
|
return {
|
|
282
330
|
action: evt.type === "session.recovery.completed" ? lowCardinalityLabel(evt.action, "unknown") : evt.allowActiveAbort ? "abort" : "recover",
|
|
@@ -285,6 +333,18 @@ function sessionRecoveryLabels(evt) {
|
|
|
285
333
|
status: evt.type === "session.recovery.completed" ? evt.status : "requested"
|
|
286
334
|
};
|
|
287
335
|
}
|
|
336
|
+
function livenessLabels(evt) {
|
|
337
|
+
return { reason: lowCardinalityLabel(evt.reasons.join(":"), "unknown") };
|
|
338
|
+
}
|
|
339
|
+
function payloadLargeLabels(evt) {
|
|
340
|
+
return {
|
|
341
|
+
action: evt.action,
|
|
342
|
+
channel: lowCardinalityLabel(evt.channel, "none"),
|
|
343
|
+
plugin: lowCardinalityLabel(evt.pluginId, "none"),
|
|
344
|
+
reason: lowCardinalityLabel(evt.reason, "none"),
|
|
345
|
+
surface: lowCardinalityLabel(evt.surface, "unknown")
|
|
346
|
+
};
|
|
347
|
+
}
|
|
288
348
|
function talkLabels(evt) {
|
|
289
349
|
return {
|
|
290
350
|
brain: lowCardinalityLabel(evt.brain),
|
|
@@ -325,7 +385,7 @@ function recordModelUsage(store, evt) {
|
|
|
325
385
|
store.histogram("openclaw_model_usage_duration_seconds", "Model usage event duration in seconds.", labels, seconds(evt.durationMs));
|
|
326
386
|
}
|
|
327
387
|
function recordDiagnosticEvent(store, evt, metadata) {
|
|
328
|
-
if (!metadata
|
|
388
|
+
if (!shouldRecordDiagnosticEvent(metadata)) return;
|
|
329
389
|
switch (evt.type) {
|
|
330
390
|
case "model.usage":
|
|
331
391
|
recordModelUsage(store, evt);
|
|
@@ -339,11 +399,17 @@ function recordDiagnosticEvent(store, evt, metadata) {
|
|
|
339
399
|
store.histogram("openclaw_model_call_duration_seconds", "Provider model call duration in seconds.", modelCallLabels(evt), seconds(evt.durationMs));
|
|
340
400
|
store.counter("openclaw_model_call_total", "Provider model calls completed by outcome.", modelCallLabels(evt));
|
|
341
401
|
return;
|
|
402
|
+
case "model.failover":
|
|
403
|
+
store.counter("openclaw_model_failover_total", "Model failovers by source, destination, lane, and reason.", modelFailoverLabels(evt));
|
|
404
|
+
return;
|
|
342
405
|
case "tool.execution.completed":
|
|
343
406
|
case "tool.execution.error":
|
|
344
407
|
store.histogram("openclaw_tool_execution_duration_seconds", "Tool execution duration in seconds.", toolExecutionLabels(evt), seconds(evt.durationMs));
|
|
345
408
|
store.counter("openclaw_tool_execution_total", "Tool executions completed by outcome.", toolExecutionLabels(evt));
|
|
346
409
|
return;
|
|
410
|
+
case "tool.execution.blocked":
|
|
411
|
+
store.counter("openclaw_tool_execution_blocked_total", "Tool executions blocked by policy or sandbox diagnostics.", toolExecutionBlockedLabels(evt));
|
|
412
|
+
return;
|
|
347
413
|
case "skill.used":
|
|
348
414
|
store.counter("openclaw_skill_used_total", "Skills used by agent runs.", skillLabels(evt));
|
|
349
415
|
return;
|
|
@@ -364,6 +430,15 @@ function recordDiagnosticEvent(store, evt, metadata) {
|
|
|
364
430
|
reason: lowCardinalityLabel(evt.reason, "none")
|
|
365
431
|
}, seconds(evt.durationMs));
|
|
366
432
|
return;
|
|
433
|
+
case "webhook.received":
|
|
434
|
+
store.counter("openclaw_webhook_received_total", "Webhook requests received by channel and update type.", webhookLabels(evt));
|
|
435
|
+
return;
|
|
436
|
+
case "webhook.processed":
|
|
437
|
+
store.histogram("openclaw_webhook_duration_seconds", "Webhook processing duration in seconds.", webhookLabels(evt), seconds(evt.durationMs));
|
|
438
|
+
return;
|
|
439
|
+
case "webhook.error":
|
|
440
|
+
store.counter("openclaw_webhook_error_total", "Webhook processing errors by channel and update type.", webhookLabels(evt));
|
|
441
|
+
return;
|
|
367
442
|
case "message.delivery.started":
|
|
368
443
|
store.counter("openclaw_message_delivery_started_total", "Outbound message delivery attempts started.", {
|
|
369
444
|
channel: lowCardinalityLabel(evt.channel),
|
|
@@ -433,6 +508,10 @@ function recordDiagnosticEvent(store, evt, metadata) {
|
|
|
433
508
|
});
|
|
434
509
|
if (evt.queueDepth !== void 0) store.gauge("openclaw_session_queue_depth", "Latest observed session queue depth.", { state: evt.state }, numericValue(evt.queueDepth));
|
|
435
510
|
return;
|
|
511
|
+
case "session.stuck":
|
|
512
|
+
store.counter("openclaw_session_stuck_total", "Stale session bookkeeping observations with no active work.", sessionStuckLabels(evt));
|
|
513
|
+
store.histogram("openclaw_session_stuck_age_seconds", "Age of stale session bookkeeping observations in seconds.", sessionStuckLabels(evt), seconds(evt.ageMs));
|
|
514
|
+
return;
|
|
436
515
|
case "session.turn.created":
|
|
437
516
|
store.counter("openclaw_session_turn_created_total", "Agent session turns created.", {
|
|
438
517
|
agent: lowCardinalityLabel(evt.agentId),
|
|
@@ -452,6 +531,16 @@ function recordDiagnosticEvent(store, evt, metadata) {
|
|
|
452
531
|
reason: evt.reason
|
|
453
532
|
});
|
|
454
533
|
return;
|
|
534
|
+
case "diagnostic.liveness.warning":
|
|
535
|
+
store.counter("openclaw_liveness_warning_total", "Diagnostic liveness warning events.", livenessLabels(evt));
|
|
536
|
+
store.gauge("openclaw_liveness_sessions", "Latest session counts reported with diagnostic liveness warnings.", { state: "active" }, numericValue(evt.active));
|
|
537
|
+
store.gauge("openclaw_liveness_sessions", "Latest session counts reported with diagnostic liveness warnings.", { state: "waiting" }, numericValue(evt.waiting));
|
|
538
|
+
store.gauge("openclaw_liveness_sessions", "Latest session counts reported with diagnostic liveness warnings.", { state: "queued" }, numericValue(evt.queued));
|
|
539
|
+
store.histogram("openclaw_liveness_event_loop_delay_p99_seconds", "P99 event-loop delay reported by diagnostic liveness warnings in seconds.", livenessLabels(evt), seconds(evt.eventLoopDelayP99Ms));
|
|
540
|
+
store.histogram("openclaw_liveness_event_loop_delay_max_seconds", "Maximum event-loop delay reported by diagnostic liveness warnings in seconds.", livenessLabels(evt), seconds(evt.eventLoopDelayMaxMs));
|
|
541
|
+
store.histogram("openclaw_liveness_event_loop_utilization_ratio", "Event-loop utilization reported by diagnostic liveness warnings.", livenessLabels(evt), numericValue(evt.eventLoopUtilization), RATIO_BUCKETS);
|
|
542
|
+
store.histogram("openclaw_liveness_cpu_core_ratio", "CPU core ratio reported by diagnostic liveness warnings.", livenessLabels(evt), numericValue(evt.cpuCoreRatio), RATIO_BUCKETS);
|
|
543
|
+
return;
|
|
455
544
|
case "diagnostic.async_queue.dropped":
|
|
456
545
|
store.counter("openclaw_diagnostic_async_queue_dropped_total", "Async diagnostic queue drops by dropped event class.", { drop_class: "total" }, numericValue(evt.droppedEvents));
|
|
457
546
|
if (evt.droppedTrustedEvents !== void 0) store.counter("openclaw_diagnostic_async_queue_dropped_total", "Async diagnostic queue drops by dropped event class.", { drop_class: "trusted" }, numericValue(evt.droppedTrustedEvents));
|
|
@@ -459,8 +548,7 @@ function recordDiagnosticEvent(store, evt, metadata) {
|
|
|
459
548
|
if (evt.droppedPriorityEvents !== void 0) store.counter("openclaw_diagnostic_async_queue_dropped_total", "Async diagnostic queue drops by dropped event class.", { drop_class: "priority" }, numericValue(evt.droppedPriorityEvents));
|
|
460
549
|
store.gauge("openclaw_diagnostic_async_queue_length", "Latest async diagnostic queue length after a drop summary.", {}, numericValue(evt.queueLength));
|
|
461
550
|
return;
|
|
462
|
-
case "diagnostic.heartbeat":
|
|
463
|
-
case "diagnostic.liveness.warning": return;
|
|
551
|
+
case "diagnostic.heartbeat": return;
|
|
464
552
|
case "telemetry.exporter":
|
|
465
553
|
store.counter("openclaw_telemetry_exporter_total", "Telemetry exporter lifecycle events.", {
|
|
466
554
|
exporter: lowCardinalityLabel(evt.exporter),
|
|
@@ -469,6 +557,10 @@ function recordDiagnosticEvent(store, evt, metadata) {
|
|
|
469
557
|
status: evt.status
|
|
470
558
|
});
|
|
471
559
|
return;
|
|
560
|
+
case "payload.large":
|
|
561
|
+
store.counter("openclaw_payload_large_total", "Oversized payload diagnostics by surface and action.", payloadLargeLabels(evt));
|
|
562
|
+
store.histogram("openclaw_payload_large_bytes", "Oversized payload byte sizes by surface and action.", payloadLargeLabels(evt), numericValue(evt.bytes), BYTE_BUCKETS);
|
|
563
|
+
return;
|
|
472
564
|
default: return;
|
|
473
565
|
}
|
|
474
566
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/diagnostics-prometheus",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.25-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/diagnostics-prometheus",
|
|
9
|
-
"version": "2026.5.
|
|
9
|
+
"version": "2026.5.25-beta.1"
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/diagnostics-prometheus",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.25-beta.1",
|
|
4
4
|
"description": "OpenClaw diagnostics Prometheus exporter",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"minHostVersion": ">=2026.4.25"
|
|
19
19
|
},
|
|
20
20
|
"compat": {
|
|
21
|
-
"pluginApi": ">=2026.5.
|
|
21
|
+
"pluginApi": ">=2026.5.25-beta.1"
|
|
22
22
|
},
|
|
23
23
|
"build": {
|
|
24
|
-
"openclawVersion": "2026.5.
|
|
24
|
+
"openclawVersion": "2026.5.25-beta.1"
|
|
25
25
|
},
|
|
26
26
|
"release": {
|
|
27
27
|
"publishToClawHub": true,
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"npm-shrinkwrap.json"
|
|
38
38
|
],
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"openclaw": ">=2026.5.
|
|
40
|
+
"openclaw": ">=2026.5.25-beta.1"
|
|
41
41
|
},
|
|
42
42
|
"peerDependenciesMeta": {
|
|
43
43
|
"openclaw": {
|