@openclaw/diagnostics-prometheus 2026.9.7 → 2026.10.1-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.
Files changed (2) hide show
  1. package/dist/index.js +42 -18
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -106,7 +106,7 @@ function createPrometheusMetricStore() {
106
106
  for (const key of gauges.keys()) if (key.startsWith(`${name}|`)) gauges.delete(key);
107
107
  };
108
108
  const histogram = (name, help, labels, value, buckets = DURATION_BUCKETS_SECONDS) => {
109
- if (value === void 0 || !Number.isFinite(value) || value < 0) return;
109
+ if (value === void 0 || !Number.isFinite(value)) return;
110
110
  const key = metricKey(name, labels);
111
111
  if (!canCreateSeries(histograms, key)) return;
112
112
  let sample = histograms.get(key);
@@ -158,7 +158,22 @@ function createPrometheusMetricStore() {
158
158
  };
159
159
  }
160
160
  //#endregion
161
+ //#region extensions/diagnostics-prometheus/src/service-child-process.ts
162
+ /** Git launches carry a bounded owner label; every other executable family reports `none`. */
163
+ function recordChildProcessSpawn(store, evt) {
164
+ store.counter("openclaw_child_process_spawn_total", "Successful child launches through the shared spawn and exec owners.", {
165
+ family: normalizeDiagnosticValue(evt.family),
166
+ operation: normalizeDiagnosticValue(evt.operation ?? (evt.family === "git" ? "unknown" : "none"))
167
+ }, asNonNegativeFiniteNumber(evt.count) ?? 0);
168
+ }
169
+ //#endregion
161
170
  //#region extensions/diagnostics-prometheus/src/service-gateway-rpc.ts
171
+ const RESPONSE_BYTE_BUCKETS = Array.from({ length: 17 }, (_, index) => 1024 * 2 ** index);
172
+ const HEAP_DELTA_BYTE_BUCKETS = [
173
+ ...RESPONSE_BYTE_BUCKETS.toReversed().map((bytes) => -bytes),
174
+ 0,
175
+ ...RESPONSE_BYTE_BUCKETS
176
+ ];
162
177
  const CATALOG_LIST_METHOD = "sessions.catalog.list";
163
178
  const CATALOG_LIST_PHASE_PREFIX = `${CATALOG_LIST_METHOD}.`;
164
179
  const CATALOG_LIST_PHASES = /* @__PURE__ */ new Set([
@@ -191,12 +206,18 @@ function recordGatewayRpcEvent(store, evt, metadata) {
191
206
  store.counter("openclaw_gateway_rpc_requests_total", "Authenticated Gateway WebSocket requests received.", labels);
192
207
  return;
193
208
  }
209
+ if (evt.phase === "response" && (evt.outcome === "ok" || evt.outcome === "error")) {
210
+ store.histogram("openclaw_gateway_rpc_response_bytes", "Encoded Gateway RPC response frame size in bytes, including later frames.", labels, evt.responseBytes, RESPONSE_BYTE_BUCKETS);
211
+ if (evt.firstResponse === false) return;
212
+ }
194
213
  store.counter("openclaw_gateway_rpc_outcomes_total", "Gateway RPC observations by phase and outcome.", {
195
214
  phase: evt.phase,
196
215
  outcome: evt.outcome
197
216
  });
198
217
  if (evt.phase === "response" && (evt.outcome === "ok" || evt.outcome === "error")) store.histogram("openclaw_gateway_rpc_first_response_seconds", "Elapsed time until the first Gateway RPC response is sent.", labels, seconds(evt.durationMs));
199
218
  else if (evt.phase === "handler") {
219
+ if (evt.heapDeltaBytes !== void 0) store.counter("openclaw_gateway_rpc_handler_heap_delta_exclusive_total", "Gateway RPC handlers with an exclusive main-thread heap-change sample.", labels);
220
+ store.histogram("openclaw_gateway_rpc_handler_heap_delta_bytes", "Exclusive RPC handler heap change; background work and GC can affect signed samples.", labels, evt.heapDeltaBytes, HEAP_DELTA_BYTE_BUCKETS);
200
221
  store.histogram("openclaw_gateway_rpc_handler_seconds", "Gateway RPC handler duration until return or throw.", labels, seconds(evt.durationMs));
201
222
  store.histogram("openclaw_gateway_rpc_admission_seconds", "Elapsed time from Gateway RPC receipt until handler invocation.", labels, seconds(evt.admissionMs));
202
223
  } else if (evt.phase === "dispatch") store.histogram("openclaw_gateway_rpc_queue_wait_seconds", "Gateway operator request start queue wait.", labels, seconds(evt.queueWaitMs));
@@ -223,6 +244,16 @@ function recordMemorySample(store, memory, byteBuckets) {
223
244
  ["worker_heap_used", "workerHeapUsedBytes"]
224
245
  ]) store.gauge("openclaw_memory_bytes", "Latest process memory usage by memory kind.", { kind }, asNonNegativeFiniteNumber(memory[field]));
225
246
  for (const [name, field] of [["openclaw_worker_count", "workerCount"], ["openclaw_worker_heap_sampled_count", "workerHeapSampledCount"]]) store.gauge(name, "Worker isolate counts.", {}, asNonNegativeFiniteNumber(memory[field]));
247
+ store.clearGauges("openclaw_heap_space_bytes");
248
+ for (const space of memory.heapSpaces ?? []) for (const [stat, field] of [
249
+ ["used", "space_used_size"],
250
+ ["size", "space_size"],
251
+ ["available", "space_available_size"],
252
+ ["physical", "physical_space_size"]
253
+ ]) store.gauge("openclaw_heap_space_bytes", "Latest main-isolate V8 heap space usage in bytes.", {
254
+ space: space.space_name,
255
+ stat
256
+ }, space[field]);
226
257
  const workerHeaps = /* @__PURE__ */ new Map();
227
258
  for (const worker of memory.workerHeaps ?? []) {
228
259
  const heapUsed = asNonNegativeFiniteNumber(worker.heapUsed);
@@ -581,7 +612,7 @@ function recordDiagnosticEvent(store, evt, metadata) {
581
612
  });
582
613
  return;
583
614
  case "diagnostic.child_process.spawn":
584
- store.counter("openclaw_child_process_spawn_total", "Successful child launches through the shared spawn and exec owners.", { family: normalizeDiagnosticValue(evt.family) }, asNonNegativeFiniteNumber(evt.count) ?? 0);
615
+ recordChildProcessSpawn(store, evt);
585
616
  return;
586
617
  case "diagnostic.memory.sample":
587
618
  recordMemorySample(store, evt.memory, BYTE_BUCKETS);
@@ -683,10 +714,16 @@ function createDiagnosticsPrometheusExporter() {
683
714
  const store = createPrometheusMetricStore();
684
715
  let unsubscribe;
685
716
  let internalDiagnostics;
686
- const reportExporterHealth = (update) => {
717
+ const reportExporterStatus = (update) => {
687
718
  try {
688
719
  internalDiagnostics?.reportExporterHealth?.(update);
689
720
  } catch {}
721
+ const { transport: _transport, ...event } = update;
722
+ internalDiagnostics?.emit({
723
+ type: "telemetry.exporter",
724
+ exporter: "diagnostics-prometheus",
725
+ ...event
726
+ });
690
727
  };
691
728
  return {
692
729
  handler: createMetricsHandler(store),
@@ -712,34 +749,21 @@ function createDiagnosticsPrometheusExporter() {
712
749
  }
713
750
  }, { exclude: ["log.record"] }, { includePrivateData: false });
714
751
  internalDiagnostics = ctx.internalDiagnostics;
715
- reportExporterHealth({
752
+ reportExporterStatus({
716
753
  signal: "metrics",
717
754
  transport: "prometheus-scrape",
718
755
  status: "started",
719
756
  reason: "configured"
720
757
  });
721
- internalDiagnostics.emit({
722
- type: "telemetry.exporter",
723
- exporter: "diagnostics-prometheus",
724
- signal: "metrics",
725
- status: "started",
726
- reason: "configured"
727
- });
728
758
  },
729
759
  stop() {
730
760
  unsubscribe?.();
731
761
  unsubscribe = void 0;
732
- reportExporterHealth({
762
+ reportExporterStatus({
733
763
  signal: "metrics",
734
764
  transport: "prometheus-scrape",
735
765
  status: "dropped"
736
766
  });
737
- internalDiagnostics?.emit({
738
- type: "telemetry.exporter",
739
- exporter: "diagnostics-prometheus",
740
- signal: "metrics",
741
- status: "dropped"
742
- });
743
767
  internalDiagnostics = void 0;
744
768
  store.reset();
745
769
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/diagnostics-prometheus",
3
- "version": "2026.9.7",
3
+ "version": "2026.10.1-beta.1",
4
4
  "description": "OpenClaw diagnostics Prometheus exporter for runtime metrics.",
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.9.7"
21
+ "pluginApi": ">=2026.10.1-beta.1"
22
22
  },
23
23
  "build": {
24
- "openclawVersion": "2026.9.7"
24
+ "openclawVersion": "2026.10.1-beta.1"
25
25
  },
26
26
  "release": {
27
27
  "publishToClawHub": true,
@@ -39,7 +39,7 @@
39
39
  "assets/activity.svg"
40
40
  ],
41
41
  "peerDependencies": {
42
- "openclaw": ">=2026.9.7"
42
+ "openclaw": ">=2026.10.1-beta.1"
43
43
  },
44
44
  "peerDependenciesMeta": {
45
45
  "openclaw": {