@openclaw/diagnostics-otel 2026.5.20-beta.1 → 2026.5.20
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/index.js +52 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
|
10
10
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
11
11
|
import { ParentBasedSampler, TraceIdRatioBasedSampler } from "@opentelemetry/sdk-trace-base";
|
|
12
12
|
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
13
|
+
import { registerUnhandledRejectionHandler } from "openclaw/plugin-sdk/runtime-env";
|
|
13
14
|
//#region extensions/diagnostics-otel/src/service.ts
|
|
14
15
|
const DEFAULT_SERVICE_NAME = "openclaw";
|
|
15
16
|
const DROPPED_OTEL_ATTRIBUTE_KEYS = new Set([
|
|
@@ -119,6 +120,46 @@ function errorCategory(err) {
|
|
|
119
120
|
return "unknown";
|
|
120
121
|
}
|
|
121
122
|
}
|
|
123
|
+
function collectNestedErrorCandidates(err) {
|
|
124
|
+
const queue = [err];
|
|
125
|
+
const seen = /* @__PURE__ */ new Set();
|
|
126
|
+
const candidates = [];
|
|
127
|
+
while (queue.length > 0) {
|
|
128
|
+
const current = queue.shift();
|
|
129
|
+
if (current == null || seen.has(current)) continue;
|
|
130
|
+
seen.add(current);
|
|
131
|
+
candidates.push(current);
|
|
132
|
+
if (Array.isArray(current)) {
|
|
133
|
+
for (const item of current) if (item != null && !seen.has(item)) queue.push(item);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
if (typeof current !== "object") continue;
|
|
137
|
+
const record = current;
|
|
138
|
+
for (const nested of [
|
|
139
|
+
record.cause,
|
|
140
|
+
record.reason,
|
|
141
|
+
record.original,
|
|
142
|
+
record.error
|
|
143
|
+
]) if (nested != null && !seen.has(nested)) queue.push(nested);
|
|
144
|
+
if (Array.isArray(record.errors)) {
|
|
145
|
+
for (const nested of record.errors) if (nested != null && !seen.has(nested)) queue.push(nested);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return candidates;
|
|
149
|
+
}
|
|
150
|
+
function readErrorName(err) {
|
|
151
|
+
if (!err || typeof err !== "object") return;
|
|
152
|
+
const name = err.name;
|
|
153
|
+
return typeof name === "string" && name.trim() ? name : void 0;
|
|
154
|
+
}
|
|
155
|
+
function readErrorCode(err) {
|
|
156
|
+
if (!err || typeof err !== "object") return;
|
|
157
|
+
const code = err.code;
|
|
158
|
+
return typeof code === "string" || typeof code === "number" ? code : void 0;
|
|
159
|
+
}
|
|
160
|
+
function findOtlpExporterError(reason) {
|
|
161
|
+
for (const candidate of collectNestedErrorCandidates(reason)) if (readErrorName(candidate) === "OTLPExporterError" && candidate && typeof candidate === "object") return candidate;
|
|
162
|
+
}
|
|
122
163
|
function redactOtelAttributes(attributes) {
|
|
123
164
|
const redactedAttributes = {};
|
|
124
165
|
for (const [key, value] of Object.entries(attributes)) {
|
|
@@ -291,15 +332,19 @@ function createDiagnosticsOtelService() {
|
|
|
291
332
|
let logProvider = null;
|
|
292
333
|
let unsubscribe = null;
|
|
293
334
|
let stopActiveTrustedSpans = null;
|
|
335
|
+
let unregisterUnhandledRejectionHandler = null;
|
|
294
336
|
const stopStarted = async () => {
|
|
295
337
|
const currentUnsubscribe = unsubscribe;
|
|
296
338
|
const currentLogProvider = logProvider;
|
|
297
339
|
const currentSdk = sdk;
|
|
298
340
|
const currentStopActiveTrustedSpans = stopActiveTrustedSpans;
|
|
341
|
+
const currentUnregisterUnhandledRejectionHandler = unregisterUnhandledRejectionHandler;
|
|
299
342
|
unsubscribe = null;
|
|
300
343
|
logProvider = null;
|
|
301
344
|
sdk = null;
|
|
302
345
|
stopActiveTrustedSpans = null;
|
|
346
|
+
unregisterUnhandledRejectionHandler = null;
|
|
347
|
+
currentUnregisterUnhandledRejectionHandler?.();
|
|
303
348
|
currentUnsubscribe?.();
|
|
304
349
|
currentStopActiveTrustedSpans?.();
|
|
305
350
|
if (currentLogProvider) await currentLogProvider.shutdown().catch(() => void 0);
|
|
@@ -1533,6 +1578,13 @@ function createDiagnosticsOtelService() {
|
|
|
1533
1578
|
ctx.logger.error(`diagnostics-otel: event handler failed (${evt.type}): ${formatError(err)}`);
|
|
1534
1579
|
}
|
|
1535
1580
|
});
|
|
1581
|
+
unregisterUnhandledRejectionHandler = registerUnhandledRejectionHandler((reason) => {
|
|
1582
|
+
const otlpError = findOtlpExporterError(reason);
|
|
1583
|
+
if (!otlpError) return false;
|
|
1584
|
+
const code = readErrorCode(otlpError) ?? "unknown";
|
|
1585
|
+
ctx.logger.warn(`diagnostics-otel: suppressed OTLP exporter unhandled rejection (code=${String(code)})`);
|
|
1586
|
+
return true;
|
|
1587
|
+
});
|
|
1536
1588
|
emitForSignals(enabledSignals, {
|
|
1537
1589
|
exporter: "diagnostics-otel",
|
|
1538
1590
|
status: "started",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/diagnostics-otel",
|
|
3
|
-
"version": "2026.5.20
|
|
3
|
+
"version": "2026.5.20",
|
|
4
4
|
"description": "OpenClaw diagnostics OpenTelemetry exporter",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"minHostVersion": ">=2026.4.25"
|
|
35
35
|
},
|
|
36
36
|
"compat": {
|
|
37
|
-
"pluginApi": ">=2026.5.20
|
|
37
|
+
"pluginApi": ">=2026.5.20"
|
|
38
38
|
},
|
|
39
39
|
"build": {
|
|
40
|
-
"openclawVersion": "2026.5.20
|
|
40
|
+
"openclawVersion": "2026.5.20"
|
|
41
41
|
},
|
|
42
42
|
"release": {
|
|
43
43
|
"publishToClawHub": true,
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"openclaw.plugin.json"
|
|
53
53
|
],
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"openclaw": ">=2026.5.20
|
|
55
|
+
"openclaw": ">=2026.5.20"
|
|
56
56
|
},
|
|
57
57
|
"peerDependenciesMeta": {
|
|
58
58
|
"openclaw": {
|