@origintrail-official/dkg-node-ui 10.0.0 → 10.0.2

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 (39) hide show
  1. package/dist/index.d.ts +4 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/otlp-log-worker.d.ts +127 -0
  6. package/dist/otlp-log-worker.d.ts.map +1 -0
  7. package/dist/otlp-log-worker.js +268 -0
  8. package/dist/otlp-log-worker.js.map +1 -0
  9. package/dist/telemetry-resource.d.ts +41 -0
  10. package/dist/telemetry-resource.d.ts.map +1 -0
  11. package/dist/telemetry-resource.js +31 -0
  12. package/dist/telemetry-resource.js.map +1 -0
  13. package/dist/telemetry.d.ts +75 -16
  14. package/dist/telemetry.d.ts.map +1 -1
  15. package/dist/telemetry.js +152 -29
  16. package/dist/telemetry.js.map +1 -1
  17. package/dist-ui/assets/{3d-force-graph-CJApDMaR.js → 3d-force-graph-CcVMtgO4.js} +1 -1
  18. package/dist-ui/assets/Admin-DNNaF7rz.js +45 -0
  19. package/dist-ui/assets/{AgentHub-B2hxc5jq.js → AgentHub-eWb_Tns6.js} +1 -1
  20. package/dist-ui/assets/AgentProfilePage-D2T_V6PG.js +1 -0
  21. package/dist-ui/assets/Network-C6MDsv2e.js +1 -0
  22. package/dist-ui/assets/OnChainProvenanceCard-BbrU7jzL.js +1 -0
  23. package/dist-ui/assets/{Operations-F276JTZb.js → Operations-CCMDENBd.js} +3 -3
  24. package/dist-ui/assets/Settings-WaFKYtwQ.js +1 -0
  25. package/dist-ui/assets/ccip-CDdHldzo.js +1 -0
  26. package/dist-ui/assets/formatTrac-BTy0WudH.js +1 -0
  27. package/dist-ui/assets/{index--rkHgZxC.js → index-2Gzrk1k3.js} +164 -173
  28. package/dist-ui/assets/{index-DOgQqEa_.js → index-BrxEjqsW.js} +3 -3
  29. package/dist-ui/assets/{index-BgRu6zNc.css → index-CmliV5st.css} +1 -1
  30. package/dist-ui/assets/{index-IQUCPHDs.js → index-W4n8cdTA.js} +11 -11
  31. package/dist-ui/assets/{jsonld-32FQRO67-C6LUWPog.js → jsonld-32FQRO67-CbN9NJJW.js} +2 -2
  32. package/dist-ui/assets/{jsonld-RkISz_bF.js → jsonld-DkQdPwg5.js} +1 -1
  33. package/dist-ui/assets/{renderer-3d-2EVDZII7-DwK8fIlO.js → renderer-3d-2EVDZII7-CTUExXUn.js} +2 -2
  34. package/dist-ui/index.html +2 -2
  35. package/package.json +13 -4
  36. package/dist-ui/assets/AgentProfilePage-CDWiC_8K.js +0 -1
  37. package/dist-ui/assets/Network-DqdABbM7.js +0 -1
  38. package/dist-ui/assets/OnChainProvenanceCard-DDG5hBdy.js +0 -1
  39. package/dist-ui/assets/Settings-CXLPuyz1.js +0 -1
package/dist/index.d.ts CHANGED
@@ -10,11 +10,13 @@ export type { NotifWire, ScopedNotificationsResult, NotificationScopeContext, }
10
10
  export type { LlmSettingsCallbacks, TelemetrySettingsCallbacks } from './api.js';
11
11
  export { LogPushWorker } from './gelf-push-worker.js';
12
12
  export type { LogPushWorkerOptions } from './gelf-push-worker.js';
13
+ export { OtlpLogWorker } from './otlp-log-worker.js';
14
+ export type { OtlpLogWorkerOptions } from './otlp-log-worker.js';
13
15
  export { ChatMemoryManager } from './chat-memory.js';
14
16
  export type { MemoryToolContext, MemoryStats, MemoryEntity, SessionPublicationStatus, SessionPublishResult, SessionGraphDeltaWatermark, SessionGraphDeltaResult, } from './chat-memory.js';
15
17
  export { LlmClient, LlmRequestError } from './llm/client.js';
16
18
  export { resolveCapabilities } from './llm/capability-resolver.js';
17
19
  export type { LlmConfig, LlmChatRequest, LlmChatMessage, LlmStreamEvent, LlmCompletionResult, LlmCapabilities } from './llm/types.js';
18
- export { initTelemetry, recordGauge, setOperationSpan, isTelemetryConfigured } from './telemetry.js';
19
- export type { TelemetryConfig } from './telemetry.js';
20
+ export { initTelemetry, shutdownTelemetry, isTelemetryConfigured, recordGauge, setOperationSpan, } from './telemetry.js';
21
+ export type { TelemetryInitConfig, TelemetryResource, OtlpSignalConfig, TelemetryConfig } from './telemetry.js';
20
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,6BAA6B,EAC7B,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,yBAAyB,EACzB,mBAAmB,EAGnB,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,cAAc,EACd,MAAM,EACN,eAAe,EACf,aAAa,EACb,2BAA2B,EAC3B,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EACV,SAAS,EACT,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtI,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACrG,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,6BAA6B,EAC7B,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,yBAAyB,EACzB,mBAAmB,EAGnB,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,cAAc,EACd,MAAM,EACN,eAAe,EACf,aAAa,EACb,2BAA2B,EAC3B,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,YAAY,EACV,SAAS,EACT,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtI,OAAO,EACL,aAAa,EAAE,iBAAiB,EAAE,qBAAqB,EAEvD,WAAW,EAAE,gBAAgB,GAC9B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -8,8 +8,11 @@ export { MetricsCollector } from './metrics-collector.js';
8
8
  export { handleNodeUIRequest } from './api.js';
9
9
  export { scopeNotifications } from './notifications-scope.js';
10
10
  export { LogPushWorker } from './gelf-push-worker.js';
11
+ export { OtlpLogWorker } from './otlp-log-worker.js';
11
12
  export { ChatMemoryManager } from './chat-memory.js';
12
13
  export { LlmClient, LlmRequestError } from './llm/client.js';
13
14
  export { resolveCapabilities } from './llm/capability-resolver.js';
14
- export { initTelemetry, recordGauge, setOperationSpan, isTelemetryConfigured } from './telemetry.js';
15
+ export { initTelemetry, shutdownTelemetry, isTelemetryConfigured,
16
+ // Back-compat shims for the pre-#1317 telemetry API (no-ops / legacy config).
17
+ recordGauge, setOperationSpan, } from './telemetry.js';
15
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,6BAA6B,EAC7B,yBAAyB,EAEzB,yBAAyB,EACzB,mBAAmB;AACnB,uEAAuE;AACvE,sEAAsE;AACtE,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAsBjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAO9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAUrD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,6BAA6B,EAC7B,yBAAyB,EAEzB,yBAAyB,EACzB,mBAAmB;AACnB,uEAAuE;AACvE,sEAAsE;AACtE,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAsBjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAO9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAUrD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EACL,aAAa,EAAE,iBAAiB,EAAE,qBAAqB;AACvD,8EAA8E;AAC9E,WAAW,EAAE,gBAAgB,GAC9B,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * OTLP/HTTP log exporter — ships structured log records to an OpenTelemetry
3
+ * collector (or any OTLP/HTTP logs endpoint) as a second, opt-in sink
4
+ * alongside the always-on local SQLite store.
5
+ *
6
+ * Why hand-rolled rather than @opentelemetry/sdk-logs: as of 2026 the OTel JS
7
+ * Logs SDK is still "Development" (Traces/Metrics are Stable). We emit the
8
+ * stable OTLP/HTTP JSON wire format (ExportLogsServiceRequest) directly and
9
+ * reuse the buffer/flush/backoff shape proven by the syslog LogPushWorker.
10
+ *
11
+ * Reliability contract (this must NEVER slow down or crash the node):
12
+ * - push() only appends to a bounded in-memory buffer (drop-oldest on
13
+ * overflow) and returns immediately; it never awaits the network.
14
+ * - flush() runs on a timer, is guarded against overlap, and swallows every
15
+ * error. On a retryable failure the batch is requeued and an exponential
16
+ * backoff (with jitter, honoring Retry-After) is applied. On a
17
+ * non-retryable failure the batch is dropped (logged once).
18
+ * - The flush timer is unref'd so it never keeps the process alive.
19
+ * - Transport is outbound HTTPS push only — no inbound scrape endpoint.
20
+ */
21
+ import type { LogRecord } from '@origintrail-official/dkg-core';
22
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
23
+ export interface OtlpLogWorkerOptions {
24
+ /** Full OTLP/HTTP logs URL, e.g. http://localhost:4318/v1/logs */
25
+ endpoint: string;
26
+ /** Bearer credential for the collector (sent as Authorization: Bearer …). */
27
+ token?: string;
28
+ /** Extra static headers to attach to every request. */
29
+ headers?: Record<string, string>;
30
+ /** Network identifier: 'testnet' | 'mainnet' | 'devnet'. */
31
+ network: string;
32
+ /** Node's libp2p peer ID. */
33
+ peerId: string;
34
+ nodeName?: string;
35
+ version?: string;
36
+ commit?: string;
37
+ /** 'core' | 'edge' */
38
+ role?: string;
39
+ /** Chain id string, e.g. 'base:8453' → resource attr dkg.chain (matches traces/metrics). */
40
+ chainId?: string;
41
+ /** OTel resource service.name. Default 'dkg-node'. */
42
+ serviceName?: string;
43
+ /**
44
+ * Per-node identifier. Becomes the OTel `service.instance.id`, which Loki
45
+ * promotes to the index label `service_instance_id` — this is what a Grafana
46
+ * "pick a node" dashboard variable selects on. Defaults to nodeName, then
47
+ * peerId. Hosted nodes should set a unique `name` in config.
48
+ */
49
+ serviceInstanceId?: string;
50
+ /**
51
+ * Deployment environment (e.g. 'testnet' | 'mainnet'). Becomes the OTel
52
+ * `deployment.environment`, which Loki promotes to the label
53
+ * `deployment_environment`. Defaults to `network`.
54
+ */
55
+ deploymentEnvironment?: string;
56
+ /** Minimum level forwarded remotely. Default 'info' (debug stays local). */
57
+ minLevel?: LogLevel;
58
+ /** Bounded in-memory buffer; drop-oldest on overflow. Default 500. */
59
+ bufferMaxEntries?: number;
60
+ flushIntervalMs?: number;
61
+ requestTimeoutMs?: number;
62
+ /** Initial retry backoff in ms (doubles up to maxBackoffMs). Default 1000. */
63
+ baseBackoffMs?: number;
64
+ /** Ceiling for retry backoff in ms. Default 60000. */
65
+ maxBackoffMs?: number;
66
+ /** Optional diagnostic sink (e.g. the daemon log). Never throws. */
67
+ onError?: (message: string) => void;
68
+ }
69
+ interface OtlpAttribute {
70
+ key: string;
71
+ value: {
72
+ stringValue: string;
73
+ };
74
+ }
75
+ export declare class OtlpLogWorker {
76
+ private buffer;
77
+ private timer;
78
+ private stopped;
79
+ private flushing;
80
+ private nextAttemptAt;
81
+ private backoffMs;
82
+ private droppedNonRetryable;
83
+ private loggedNonRetryable;
84
+ private readonly endpoint;
85
+ private readonly minRank;
86
+ private readonly maxBuffer;
87
+ private readonly flushIntervalMs;
88
+ private readonly requestTimeoutMs;
89
+ private readonly baseBackoffMs;
90
+ private readonly maxBackoffMs;
91
+ private readonly authHeaders;
92
+ private readonly resourceAttrs;
93
+ private readonly scopeVersion;
94
+ private readonly onError;
95
+ constructor(opts: OtlpLogWorkerOptions);
96
+ /** Append a record. Filters below minLevel; never awaits the network. */
97
+ push(record: LogRecord): void;
98
+ start(): void;
99
+ stop(): void;
100
+ /**
101
+ * Async teardown for the daemon shutdown / telemetry-disable path: stop the
102
+ * timer and AWAIT a final flush, so the caller can guarantee no batch is still
103
+ * being sent (or stranded in the buffer) once this resolves. stop() is the
104
+ * fire-and-forget variant for callers that can't await.
105
+ */
106
+ shutdown(): Promise<void>;
107
+ /** Test/diagnostic hook. */
108
+ pending(): number;
109
+ private flush;
110
+ private requeue;
111
+ private scheduleBackoff;
112
+ private post;
113
+ private buildPayload;
114
+ }
115
+ /**
116
+ * PURE OTLP/HTTP logs wire-format encoder (ExportLogsServiceRequest JSON).
117
+ * Extracted from `OtlpLogWorker` so the protocol/payload shape is independent
118
+ * from the worker's scheduling + retry/backoff mechanics (review: "OtlpLogWorker
119
+ * mixes too many concerns") — change the wire shape here without touching the
120
+ * buffer/timer logic, and vice-versa. No side effects, no `this`.
121
+ */
122
+ export declare function encodeOtlpLogPayload(batch: ReadonlyArray<{
123
+ r: LogRecord;
124
+ tsMs: number;
125
+ }>, resourceAttrs: ReadonlyArray<OtlpAttribute>, scopeVersion?: string): string;
126
+ export {};
127
+ //# sourceMappingURL=otlp-log-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp-log-worker.d.ts","sourceRoot":"","sources":["../src/otlp-log-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,268 @@
1
+ /**
2
+ * OTLP/HTTP log exporter — ships structured log records to an OpenTelemetry
3
+ * collector (or any OTLP/HTTP logs endpoint) as a second, opt-in sink
4
+ * alongside the always-on local SQLite store.
5
+ *
6
+ * Why hand-rolled rather than @opentelemetry/sdk-logs: as of 2026 the OTel JS
7
+ * Logs SDK is still "Development" (Traces/Metrics are Stable). We emit the
8
+ * stable OTLP/HTTP JSON wire format (ExportLogsServiceRequest) directly and
9
+ * reuse the buffer/flush/backoff shape proven by the syslog LogPushWorker.
10
+ *
11
+ * Reliability contract (this must NEVER slow down or crash the node):
12
+ * - push() only appends to a bounded in-memory buffer (drop-oldest on
13
+ * overflow) and returns immediately; it never awaits the network.
14
+ * - flush() runs on a timer, is guarded against overlap, and swallows every
15
+ * error. On a retryable failure the batch is requeued and an exponential
16
+ * backoff (with jitter, honoring Retry-After) is applied. On a
17
+ * non-retryable failure the batch is dropped (logged once).
18
+ * - The flush timer is unref'd so it never keeps the process alive.
19
+ * - Transport is outbound HTTPS push only — no inbound scrape endpoint.
20
+ */
21
+ import { buildTelemetryResourceAttrs } from './telemetry-resource.js';
22
+ // OpenTelemetry severity numbers (logs data model).
23
+ const OTEL_SEVERITY = {
24
+ debug: { num: 5, text: 'DEBUG' },
25
+ info: { num: 9, text: 'INFO' },
26
+ warn: { num: 13, text: 'WARN' },
27
+ error: { num: 17, text: 'ERROR' },
28
+ };
29
+ const LEVEL_RANK = { debug: 0, info: 1, warn: 2, error: 3 };
30
+ const RETRYABLE_STATUS = new Set([408, 429, 500, 502, 503, 504]);
31
+ const DEFAULTS = {
32
+ flushIntervalMs: 2_000,
33
+ maxBuffer: 500,
34
+ maxBatch: 256,
35
+ requestTimeoutMs: 10_000,
36
+ baseBackoffMs: 1_000,
37
+ maxBackoffMs: 60_000,
38
+ serviceName: 'dkg-node',
39
+ minLevel: 'info',
40
+ };
41
+ function attr(key, value) {
42
+ if (value == null || value === '')
43
+ return null;
44
+ return { key, value: { stringValue: String(value) } };
45
+ }
46
+ export class OtlpLogWorker {
47
+ buffer = [];
48
+ timer = null;
49
+ stopped = false;
50
+ flushing = false;
51
+ nextAttemptAt = 0;
52
+ backoffMs = 0;
53
+ droppedNonRetryable = 0;
54
+ loggedNonRetryable = false;
55
+ endpoint;
56
+ minRank;
57
+ maxBuffer;
58
+ flushIntervalMs;
59
+ requestTimeoutMs;
60
+ baseBackoffMs;
61
+ maxBackoffMs;
62
+ authHeaders;
63
+ resourceAttrs;
64
+ scopeVersion;
65
+ onError;
66
+ constructor(opts) {
67
+ this.endpoint = opts.endpoint;
68
+ this.minRank = LEVEL_RANK[opts.minLevel ?? DEFAULTS.minLevel] ?? LEVEL_RANK.info;
69
+ this.maxBuffer = Math.max(1, opts.bufferMaxEntries ?? DEFAULTS.maxBuffer);
70
+ this.flushIntervalMs = opts.flushIntervalMs ?? DEFAULTS.flushIntervalMs;
71
+ this.requestTimeoutMs = opts.requestTimeoutMs ?? DEFAULTS.requestTimeoutMs;
72
+ this.baseBackoffMs = opts.baseBackoffMs ?? DEFAULTS.baseBackoffMs;
73
+ this.maxBackoffMs = opts.maxBackoffMs ?? DEFAULTS.maxBackoffMs;
74
+ this.scopeVersion = opts.version || undefined;
75
+ this.onError = opts.onError ?? (() => { });
76
+ this.authHeaders = { 'content-type': 'application/json', ...(opts.headers ?? {}) };
77
+ if (opts.token)
78
+ this.authHeaders['authorization'] = `Bearer ${opts.token}`;
79
+ // Built from the SHARED resource model so the log resource (and the Loki
80
+ // labels promoted from service.name / service.instance.id /
81
+ // deployment.environment / dkg.node.role) can never drift from the
82
+ // traces/metrics resource. See ./telemetry-resource.
83
+ this.resourceAttrs = Object.entries(buildTelemetryResourceAttrs({
84
+ serviceName: opts.serviceName ?? DEFAULTS.serviceName,
85
+ serviceVersion: opts.version,
86
+ serviceInstanceId: opts.serviceInstanceId,
87
+ deploymentEnvironment: opts.deploymentEnvironment,
88
+ network: opts.network,
89
+ peerId: opts.peerId,
90
+ nodeName: opts.nodeName,
91
+ nodeRole: opts.role,
92
+ commit: opts.commit,
93
+ chainId: opts.chainId,
94
+ })).map(([key, value]) => ({ key, value: { stringValue: value } }));
95
+ }
96
+ /** Append a record. Filters below minLevel; never awaits the network. */
97
+ push(record) {
98
+ if ((LEVEL_RANK[record.level] ?? LEVEL_RANK.info) < this.minRank)
99
+ return;
100
+ if (this.buffer.length >= this.maxBuffer)
101
+ this.buffer.shift();
102
+ this.buffer.push({ r: record, tsMs: Date.now() });
103
+ }
104
+ start() {
105
+ if (this.timer)
106
+ return;
107
+ this.stopped = false;
108
+ this.timer = setInterval(() => {
109
+ void this.flush();
110
+ }, this.flushIntervalMs);
111
+ this.timer.unref();
112
+ }
113
+ stop() {
114
+ this.stopped = true;
115
+ if (this.timer) {
116
+ clearInterval(this.timer);
117
+ this.timer = null;
118
+ }
119
+ // Best-effort final flush; failures are swallowed. Fire-and-forget — use
120
+ // shutdown() when you need to AWAIT the final flush (orderly teardown).
121
+ void this.flush(true);
122
+ }
123
+ /**
124
+ * Async teardown for the daemon shutdown / telemetry-disable path: stop the
125
+ * timer and AWAIT a final flush, so the caller can guarantee no batch is still
126
+ * being sent (or stranded in the buffer) once this resolves. stop() is the
127
+ * fire-and-forget variant for callers that can't await.
128
+ */
129
+ async shutdown() {
130
+ this.stopped = true;
131
+ if (this.timer) {
132
+ clearInterval(this.timer);
133
+ this.timer = null;
134
+ }
135
+ await this.flush(true).catch(() => { });
136
+ }
137
+ /** Test/diagnostic hook. */
138
+ pending() {
139
+ return this.buffer.length;
140
+ }
141
+ async flush(force = false) {
142
+ if (this.flushing)
143
+ return;
144
+ if (this.stopped && !force)
145
+ return;
146
+ if (this.buffer.length === 0)
147
+ return;
148
+ if (!force && Date.now() < this.nextAttemptAt)
149
+ return;
150
+ this.flushing = true;
151
+ const batch = this.buffer.splice(0, DEFAULTS.maxBatch);
152
+ try {
153
+ const body = this.buildPayload(batch);
154
+ const res = await this.post(body);
155
+ if (res.ok) {
156
+ this.backoffMs = 0;
157
+ this.nextAttemptAt = 0;
158
+ }
159
+ else if (RETRYABLE_STATUS.has(res.status)) {
160
+ this.requeue(batch);
161
+ this.scheduleBackoff(res.retryAfterMs);
162
+ }
163
+ else {
164
+ // Non-retryable (e.g. 400/401/403): dropping is correct — retrying
165
+ // a malformed/unauthorized request forever would just grow the buffer.
166
+ this.droppedNonRetryable += batch.length;
167
+ if (!this.loggedNonRetryable) {
168
+ this.loggedNonRetryable = true;
169
+ this.onError(`dropping logs — collector returned ${res.status} (non-retryable); check endpoint/token. ` +
170
+ `${this.droppedNonRetryable} record(s) dropped so far.`);
171
+ }
172
+ }
173
+ }
174
+ catch (err) {
175
+ // Network/timeout error → treat as retryable.
176
+ this.requeue(batch);
177
+ this.scheduleBackoff();
178
+ void err;
179
+ }
180
+ finally {
181
+ this.flushing = false;
182
+ }
183
+ }
184
+ requeue(batch) {
185
+ this.buffer.unshift(...batch);
186
+ while (this.buffer.length > this.maxBuffer)
187
+ this.buffer.shift();
188
+ }
189
+ scheduleBackoff(retryAfterMs) {
190
+ const next = this.backoffMs === 0 ? this.baseBackoffMs : Math.min(this.backoffMs * 2, this.maxBackoffMs);
191
+ this.backoffMs = next;
192
+ const jitter = next * 0.2 * Math.random();
193
+ const delay = retryAfterMs != null ? Math.max(retryAfterMs, next) : next + jitter;
194
+ this.nextAttemptAt = Date.now() + delay;
195
+ }
196
+ async post(body) {
197
+ const ac = new AbortController();
198
+ const timer = setTimeout(() => ac.abort(), this.requestTimeoutMs);
199
+ try {
200
+ const res = await fetch(this.endpoint, {
201
+ method: 'POST',
202
+ headers: this.authHeaders,
203
+ body,
204
+ signal: ac.signal,
205
+ });
206
+ // Drain the body so the socket can be reused / freed.
207
+ await res.arrayBuffer().catch(() => { });
208
+ let retryAfterMs;
209
+ const ra = res.headers.get('retry-after');
210
+ if (ra) {
211
+ const secs = Number(ra);
212
+ if (!Number.isNaN(secs))
213
+ retryAfterMs = secs * 1000;
214
+ }
215
+ return { ok: res.ok, status: res.status, retryAfterMs };
216
+ }
217
+ finally {
218
+ clearTimeout(timer);
219
+ }
220
+ }
221
+ buildPayload(batch) {
222
+ return encodeOtlpLogPayload(batch, this.resourceAttrs, this.scopeVersion);
223
+ }
224
+ }
225
+ /**
226
+ * PURE OTLP/HTTP logs wire-format encoder (ExportLogsServiceRequest JSON).
227
+ * Extracted from `OtlpLogWorker` so the protocol/payload shape is independent
228
+ * from the worker's scheduling + retry/backoff mechanics (review: "OtlpLogWorker
229
+ * mixes too many concerns") — change the wire shape here without touching the
230
+ * buffer/timer logic, and vice-versa. No side effects, no `this`.
231
+ */
232
+ export function encodeOtlpLogPayload(batch, resourceAttrs, scopeVersion) {
233
+ const logRecords = batch.map(({ r, tsMs }) => {
234
+ const sev = OTEL_SEVERITY[r.level] ?? OTEL_SEVERITY.info;
235
+ const nano = String(tsMs * 1_000_000);
236
+ return {
237
+ timeUnixNano: nano,
238
+ observedTimeUnixNano: nano,
239
+ severityNumber: sev.num,
240
+ severityText: sev.text,
241
+ body: { stringValue: r.message },
242
+ // W3C trace correlation — OTLP top-level fields (hex), not attributes.
243
+ // Present only when the log was emitted inside a recording span.
244
+ ...(r.traceId ? { traceId: r.traceId } : {}),
245
+ ...(r.spanId ? { spanId: r.spanId } : {}),
246
+ attributes: [
247
+ attr('dkg.operation_id', r.operationId),
248
+ attr('dkg.operation_name', r.operationName),
249
+ attr('dkg.source_operation_id', r.sourceOperationId),
250
+ attr('dkg.module', r.module),
251
+ ].filter((a) => a !== null),
252
+ };
253
+ });
254
+ return JSON.stringify({
255
+ resourceLogs: [
256
+ {
257
+ resource: { attributes: resourceAttrs },
258
+ scopeLogs: [
259
+ {
260
+ scope: { name: 'dkg-node', version: scopeVersion },
261
+ logRecords,
262
+ },
263
+ ],
264
+ },
265
+ ],
266
+ });
267
+ }
268
+ //# sourceMappingURL=otlp-log-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp-log-worker.js","sourceRoot":"","sources":["../src/otlp-log-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * THE one canonical node-identity → OTel resource-attribute mapping, shared by
3
+ * BOTH the hand-rolled log exporter (`OtlpLogWorker`) and the OTel SDK bootstrap
4
+ * (`telemetry.ts`). Keeping a single builder is the whole point: logs, traces,
5
+ * and metrics describe the same node, so a key/default must change in exactly
6
+ * one place or Loki labels, trace resources, and metric resources silently drift
7
+ * apart (review: "resource identity is duplicated between logs and traces/metrics").
8
+ *
9
+ * Pure (no OTel SDK, no Node built-ins) → safe to import from anywhere.
10
+ */
11
+ export interface TelemetryResourceInput {
12
+ /** OTel service.name. Default 'dkg-node'. */
13
+ serviceName?: string;
14
+ /** OTel service.version (node build version). */
15
+ serviceVersion?: string;
16
+ /**
17
+ * Per-node id → service.instance.id (the Grafana node selector / Loki
18
+ * `service_instance_id` label). Falls back to nodeName then peerId so logs and
19
+ * traces/metrics resolve the SAME instance id even if a caller omits it.
20
+ */
21
+ serviceInstanceId?: string;
22
+ /** Explicit deployment.environment; defaults to `network` when unset. */
23
+ deploymentEnvironment?: string;
24
+ /** testnet | mainnet | devnet → deployment.environment (default) + dkg.network. */
25
+ network?: string;
26
+ peerId?: string;
27
+ nodeName?: string;
28
+ /** 'core' | 'edge' → dkg.node.role */
29
+ nodeRole?: string;
30
+ commit?: string;
31
+ /** e.g. 'base:8453' → dkg.chain */
32
+ chainId?: string;
33
+ }
34
+ /**
35
+ * Build the resource attribute map. Standard OTel keys (service.*, deployment.*)
36
+ * plus the DKG identity keys (dkg.network, dkg.peer_id, dkg.node.name,
37
+ * dkg.node.role, dkg.chain, dkg.commit). Unset values are omitted so the
38
+ * resource never carries empty strings.
39
+ */
40
+ export declare function buildTelemetryResourceAttrs(r?: TelemetryResourceInput): Record<string, string>;
41
+ //# sourceMappingURL=telemetry-resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-resource.d.ts","sourceRoot":"","sources":["../src/telemetry-resource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,sBAAsB;IACrC,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,GAAE,sBAA2B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAclG"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Build the resource attribute map. Standard OTel keys (service.*, deployment.*)
3
+ * plus the DKG identity keys (dkg.network, dkg.peer_id, dkg.node.name,
4
+ * dkg.node.role, dkg.chain, dkg.commit). Unset values are omitted so the
5
+ * resource never carries empty strings.
6
+ */
7
+ export function buildTelemetryResourceAttrs(r = {}) {
8
+ const attrs = { 'service.name': r.serviceName || 'dkg-node' };
9
+ if (r.serviceVersion)
10
+ attrs['service.version'] = r.serviceVersion;
11
+ const instanceId = r.serviceInstanceId || r.nodeName || r.peerId;
12
+ if (instanceId)
13
+ attrs['service.instance.id'] = instanceId;
14
+ const env = r.deploymentEnvironment || r.network;
15
+ if (env)
16
+ attrs['deployment.environment'] = env;
17
+ if (r.network)
18
+ attrs['dkg.network'] = r.network;
19
+ if (r.peerId)
20
+ attrs['dkg.peer_id'] = r.peerId;
21
+ if (r.nodeName)
22
+ attrs['dkg.node.name'] = r.nodeName;
23
+ if (r.nodeRole)
24
+ attrs['dkg.node.role'] = r.nodeRole;
25
+ if (r.commit)
26
+ attrs['dkg.commit'] = r.commit;
27
+ if (r.chainId)
28
+ attrs['dkg.chain'] = r.chainId;
29
+ return attrs;
30
+ }
31
+ //# sourceMappingURL=telemetry-resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-resource.js","sourceRoot":"","sources":["../src/telemetry-resource.ts"],"names":[],"mappings":"AAkCA;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAA4B,EAAE;IACxE,MAAM,KAAK,GAA2B,EAAE,cAAc,EAAE,CAAC,CAAC,WAAW,IAAI,UAAU,EAAE,CAAC;IACtF,IAAI,CAAC,CAAC,cAAc;QAAE,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC;IAClE,MAAM,UAAU,GAAG,CAAC,CAAC,iBAAiB,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC;IACjE,IAAI,UAAU;QAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,UAAU,CAAC;IAC1D,MAAM,GAAG,GAAG,CAAC,CAAC,qBAAqB,IAAI,CAAC,CAAC,OAAO,CAAC;IACjD,IAAI,GAAG;QAAE,KAAK,CAAC,wBAAwB,CAAC,GAAG,GAAG,CAAC;IAC/C,IAAI,CAAC,CAAC,OAAO;QAAE,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;IAChD,IAAI,CAAC,CAAC,MAAM;QAAE,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,IAAI,CAAC,CAAC,QAAQ;QAAE,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IACpD,IAAI,CAAC,CAAC,QAAQ;QAAE,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;IACpD,IAAI,CAAC,CAAC,MAAM;QAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,IAAI,CAAC,CAAC,OAAO;QAAE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;IAC9C,OAAO,KAAK,CAAC;AACf,CAAC"}