@nodii/telemetry 0.21.1 → 0.23.0
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/worker-lite/index.d.ts +126 -0
- package/dist/worker-lite/index.d.ts.map +1 -0
- package/dist/worker-lite/index.js +241 -0
- package/dist/worker-lite/index.js.map +1 -0
- package/dist/worker-lite/otlp-http.d.ts +93 -0
- package/dist/worker-lite/otlp-http.d.ts.map +1 -0
- package/dist/worker-lite/otlp-http.js +179 -0
- package/dist/worker-lite/otlp-http.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { type RedactionConfig } from "../redaction.js";
|
|
2
|
+
import type { ActorType } from "../types.js";
|
|
3
|
+
import { type AttrValue, type OtlpResource } from "./otlp-http.js";
|
|
4
|
+
export type { AttrValue } from "./otlp-http.js";
|
|
5
|
+
export type { RedactionConfig } from "../redaction.js";
|
|
6
|
+
/**
|
|
7
|
+
* The explicit per-request context threaded into each emit — the workerd-safe
|
|
8
|
+
* analogue of the Node `NodiiContext` (15-telemetry § 6.2 / D41). The Workers
|
|
9
|
+
* `fetch` handler builds one per request (from inbound headers + auth) and
|
|
10
|
+
* passes it to every `log.*` / `counter.inc` call. All fields optional so a
|
|
11
|
+
* pre-context emit (cold boot / unauthenticated probe) still emits — the
|
|
12
|
+
* envelope substitutes empty-string `tenant_id`/`request_id` exactly as the
|
|
13
|
+
* Node logger does when no context is active.
|
|
14
|
+
*/
|
|
15
|
+
export interface WorkerContext {
|
|
16
|
+
/** Bare `tenant_id` per D20. */
|
|
17
|
+
tenant_id?: string;
|
|
18
|
+
user_id?: string | null;
|
|
19
|
+
actor_type?: ActorType;
|
|
20
|
+
on_behalf_of?: string | null;
|
|
21
|
+
request_id?: string;
|
|
22
|
+
intent_id?: string | null;
|
|
23
|
+
/** Active trace id (hex), if a trace context was propagated in. */
|
|
24
|
+
trace_id?: string | null;
|
|
25
|
+
/** Active span id (hex), if a trace context was propagated in. */
|
|
26
|
+
span_id?: string | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The `fetch` signature the adapter POSTs OTLP/HTTP with. Defaults to the
|
|
30
|
+
* runtime-global `fetch` (present on workerd + Bun + Node ≥18). Injectable so
|
|
31
|
+
* tests capture the request WITHOUT a live collector (R1 — a real capturing
|
|
32
|
+
* fake, not a Noop default).
|
|
33
|
+
*/
|
|
34
|
+
export type FetchLike = (input: string, init: {
|
|
35
|
+
method: string;
|
|
36
|
+
headers: Record<string, string>;
|
|
37
|
+
body: string;
|
|
38
|
+
}) => Promise<{
|
|
39
|
+
ok: boolean;
|
|
40
|
+
status: number;
|
|
41
|
+
}>;
|
|
42
|
+
/** Config for {@link createWorkerTelemetry}. All values are passed in. */
|
|
43
|
+
export interface WorkerTelemetryConfig {
|
|
44
|
+
/**
|
|
45
|
+
* OTLP/HTTP collector BASE url (Workers env binding), e.g.
|
|
46
|
+
* `https://otel.dev.nucleus-cloud.in`. The adapter appends the standard
|
|
47
|
+
* OTLP/HTTP signal paths (`/v1/logs`, `/v1/metrics`). A url that already ends
|
|
48
|
+
* in a signal path is used verbatim.
|
|
49
|
+
*/
|
|
50
|
+
collectorUrl: string;
|
|
51
|
+
/**
|
|
52
|
+
* Static headers attached to every OTLP/HTTP POST (Workers env binding),
|
|
53
|
+
* e.g. `{ authorization: "Bearer <aud=nodii-obs JWT>" }` for the
|
|
54
|
+
* `oidcauthextension` ingress (15-telemetry § 8 / D95). `content-type:
|
|
55
|
+
* application/json` is set by the adapter and need not be supplied.
|
|
56
|
+
*/
|
|
57
|
+
headers?: Record<string, string>;
|
|
58
|
+
/** D60 resource attr — the service id (e.g. `nodii-pager`). */
|
|
59
|
+
serviceName: string;
|
|
60
|
+
/** D60 resource attr — deployment env (`dev` | `uat` | `prod`). */
|
|
61
|
+
env: string;
|
|
62
|
+
/** D60 resource attr — optional service version. */
|
|
63
|
+
serviceVersion?: string;
|
|
64
|
+
/** Free-form extra resource attributes (D60). */
|
|
65
|
+
resourceAttributes?: Record<string, AttrValue>;
|
|
66
|
+
/**
|
|
67
|
+
* Injectable `fetch` (defaults to the runtime global). Supply a capturing
|
|
68
|
+
* fake in tests to assert the OTLP/HTTP request without a live collector.
|
|
69
|
+
*/
|
|
70
|
+
fetchImpl?: FetchLike;
|
|
71
|
+
/**
|
|
72
|
+
* Called with a one-line diagnostic when an OTLP/HTTP POST fails (non-2xx or
|
|
73
|
+
* network throw). Telemetry export failure MUST NOT break Workers business
|
|
74
|
+
* work (15-telemetry § 4.1 / pillar 5 / R1) — the emit path swallows the
|
|
75
|
+
* error and routes it here. Defaults to `console.warn`.
|
|
76
|
+
*/
|
|
77
|
+
onExportError?: (message: string, cause: unknown) => void;
|
|
78
|
+
/**
|
|
79
|
+
* Extra D15 redaction config, additive on top of the canonical D2 PII-field
|
|
80
|
+
* list + regex/PAN passes that ALWAYS run on the LOG path (15-telemetry § 7.3,
|
|
81
|
+
* fail-closed). Mirrors the Node logger's `.redact()` — `extraPaths` masks
|
|
82
|
+
* additional field-name keys; `scrubPan` toggles the Luhn PAN scrub (default
|
|
83
|
+
* on). Omit for the canonical passes only.
|
|
84
|
+
*/
|
|
85
|
+
redaction?: RedactionConfig;
|
|
86
|
+
}
|
|
87
|
+
/** A structured logger over OTLP/HTTP for Workers. */
|
|
88
|
+
export interface WorkerLogger {
|
|
89
|
+
debug(msg: string, opts?: EmitOpts): Promise<void>;
|
|
90
|
+
info(msg: string, opts?: EmitOpts): Promise<void>;
|
|
91
|
+
warn(msg: string, opts?: EmitOpts): Promise<void>;
|
|
92
|
+
error(msg: string, opts?: EmitOpts): Promise<void>;
|
|
93
|
+
}
|
|
94
|
+
/** Per-emit options: the explicit context + extra structured fields. */
|
|
95
|
+
export interface EmitOpts {
|
|
96
|
+
/** The explicit per-request context (workerd-safe; no ALS). */
|
|
97
|
+
context?: WorkerContext;
|
|
98
|
+
/** Extra structured fields merged into the log-record attributes. */
|
|
99
|
+
fields?: Record<string, AttrValue | null | undefined>;
|
|
100
|
+
}
|
|
101
|
+
/** A monotonic counter handle over OTLP/HTTP for Workers. */
|
|
102
|
+
export interface WorkerCounter {
|
|
103
|
+
/** Increment by 1 (or `by`), stamping the D26 trio + labels from `opts`. */
|
|
104
|
+
inc(opts?: CounterOpts): Promise<void>;
|
|
105
|
+
inc(by: number, opts?: CounterOpts): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
/** Per-increment options: the explicit context + extra labels. */
|
|
108
|
+
export interface CounterOpts {
|
|
109
|
+
context?: WorkerContext;
|
|
110
|
+
labels?: Record<string, AttrValue | null | undefined>;
|
|
111
|
+
}
|
|
112
|
+
/** The handle returned by {@link createWorkerTelemetry}. */
|
|
113
|
+
export interface WorkerTelemetry {
|
|
114
|
+
logger: WorkerLogger;
|
|
115
|
+
/** Register (or fetch) a monotonic counter by name. */
|
|
116
|
+
counter(name: string): WorkerCounter;
|
|
117
|
+
/** The resource attrs stamped on every export (for introspection/tests). */
|
|
118
|
+
readonly resource: OtlpResource;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Build the workerd-runnable telemetry handle. Config is passed in from Workers
|
|
122
|
+
* env bindings (NOT `process.env`). Emits structured logs + counters over
|
|
123
|
+
* OTLP/HTTP via `fetch`.
|
|
124
|
+
*/
|
|
125
|
+
export declare function createWorkerTelemetry(config: WorkerTelemetryConfig): WorkerTelemetry;
|
|
126
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/worker-lite/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// `@nodii/telemetry/worker-lite` — the minimal Cloudflare Workers (workerd)
|
|
2
|
+
// emit adapter.
|
|
3
|
+
//
|
|
4
|
+
// WHY THIS EXISTS (15-telemetry-doctrine § 11 Open Question 3, LIVE):
|
|
5
|
+
// > "Fourth-substrate (Cloudflare Workers) emit gap. `nodii-pager` (D170)
|
|
6
|
+
// > runs on Workers; the Workers-OTLP exporter / minimal `@nodii/telemetry`
|
|
7
|
+
// > Workers adapter is TBD and out of current roster scope."
|
|
8
|
+
//
|
|
9
|
+
// The main package (`.`) + the `./worker` subpath boot the Node OTel SDK with
|
|
10
|
+
// gRPC OTLP exporters (`src/otlp-adapter.ts`) and the BullMQ/Redis-Streams
|
|
11
|
+
// worker substrate (`src/worker/`) — both pull `@grpc/grpc-js` + `node:*`, which
|
|
12
|
+
// CANNOT run on workerd. `nodii-pager` (D170, Cloudflare-resident) needs the
|
|
13
|
+
// minimal slice: structured LOGS + COUNTERS emitted over OTLP/HTTP via `fetch`.
|
|
14
|
+
// This module is that slice — NO `node:*`, NO `@opentelemetry/*`, NO gRPC, NO
|
|
15
|
+
// BullMQ. Only `fetch` + Web-standard APIs (workerd-runnable).
|
|
16
|
+
//
|
|
17
|
+
// DOCTRINE CONFORMANCE:
|
|
18
|
+
// - OTLP is the wire (15-telemetry § 2 / D11). We use OTLP/HTTP (JSON) instead
|
|
19
|
+
// of OTLP/gRPC because gRPC is Node-only; the collector's `otlphttp` receiver
|
|
20
|
+
// accepts the same payload tree (`otlp-http.ts`).
|
|
21
|
+
// - Logs carry the canonical D13 11-field envelope (15-telemetry § 3 →
|
|
22
|
+
// 03-logging § 2), SDK-injected from the supplied context + config — the
|
|
23
|
+
// SAME `LogEnvelope` type the Node logger forms, so Workers logs are
|
|
24
|
+
// wire-consistent with Node ones.
|
|
25
|
+
// - The mandatory correlation trio `tenant_id` / `request_id` / `intent_id`
|
|
26
|
+
// (15-telemetry § 4.2 / D26) rides every log envelope AND every counter
|
|
27
|
+
// datapoint. `tenant_id` is the bare key (§ 5.3 / D20) — same key across
|
|
28
|
+
// signals.
|
|
29
|
+
// - `service` + `deployment.environment.name` + bare `env` resource attrs on
|
|
30
|
+
// every export (§ 7.2 / D60).
|
|
31
|
+
// - D15 SDK-side redaction (§ 7.3 / § 7.5, LOCKED, fail-closed) runs on the
|
|
32
|
+
// LOG path before serialization — the load-bearing PII pass § 7.1/D41 says
|
|
33
|
+
// can't be bypassed per-service. On a redaction failure the record is
|
|
34
|
+
// DROPPED + `telemetry.sdk.redaction_failure_total` increments (drop, not
|
|
35
|
+
// leak). Reuses the pure (workerd-safe) `src/redaction.ts`.
|
|
36
|
+
//
|
|
37
|
+
// CONTEXT MECHANISM (deliverable requirement 4):
|
|
38
|
+
// Workers has NO AsyncLocalStorage guarantee (15-telemetry § 6.1 / D40 fixes
|
|
39
|
+
// ALS for Node/Bun; workerd does not guarantee it, and pulling `node:async_hooks`
|
|
40
|
+
// would break workerd-safety). So the Workers adapter takes an EXPLICIT
|
|
41
|
+
// `WorkerContext` argument on every emit (`log.info(msg, { context, ... })`,
|
|
42
|
+
// `counter.inc({ context, ... })`) rather than an implicit ambient store. The
|
|
43
|
+
// caller threads its per-request context (already available on the Workers
|
|
44
|
+
// `fetch(request, env, ctx)` handler) into each emit. This is the workerd-safe
|
|
45
|
+
// analogue of the Node ALS `NodiiContext` — same fields, explicitly passed.
|
|
46
|
+
//
|
|
47
|
+
// CONFIG (deliverable requirement 5):
|
|
48
|
+
// All config is PASSED IN (Workers env bindings), never read from
|
|
49
|
+
// `process.env`. `createWorkerTelemetry({ collectorUrl, headers, serviceName,
|
|
50
|
+
// env, ... })`.
|
|
51
|
+
// D15 SDK-side redaction (15-telemetry § 7.3 / § 7.5, LOCKED). `redaction.ts` is
|
|
52
|
+
// PURE (zero imports → workerd-safe); we import only its functions + type. This
|
|
53
|
+
// is the load-bearing, fail-closed PII pass that § 7.1/D41 says "can't be
|
|
54
|
+
// bypassed per-service" — so the Workers LOG path runs it exactly like the Node
|
|
55
|
+
// logger (`src/logger.ts`), NOT a per-service bypass.
|
|
56
|
+
import { attemptRedactFields, attemptRedactString, } from "../redaction.js";
|
|
57
|
+
import { buildLogsExportBody, buildMetricsExportBody, buildResource, } from "./otlp-http.js";
|
|
58
|
+
const SCOPE_NAME = "@nodii/telemetry/worker-lite";
|
|
59
|
+
/**
|
|
60
|
+
* Build the workerd-runnable telemetry handle. Config is passed in from Workers
|
|
61
|
+
* env bindings (NOT `process.env`). Emits structured logs + counters over
|
|
62
|
+
* OTLP/HTTP via `fetch`.
|
|
63
|
+
*/
|
|
64
|
+
export function createWorkerTelemetry(config) {
|
|
65
|
+
const resource = buildResource({
|
|
66
|
+
serviceName: config.serviceName,
|
|
67
|
+
env: config.env,
|
|
68
|
+
serviceVersion: config.serviceVersion,
|
|
69
|
+
extra: config.resourceAttributes,
|
|
70
|
+
});
|
|
71
|
+
// Resolve `fetch` at build time. Default to the runtime global (workerd/Bun/
|
|
72
|
+
// Node ≥18). We reference `globalThis.fetch` (present on all three) rather
|
|
73
|
+
// than a bare `fetch` so bundlers don't tree-shake it away.
|
|
74
|
+
const doFetch = config.fetchImpl ?? globalThis.fetch;
|
|
75
|
+
const onExportError = config.onExportError ??
|
|
76
|
+
((message, cause) => {
|
|
77
|
+
// eslint-disable-next-line no-console
|
|
78
|
+
console.warn(`[@nodii/telemetry/worker-lite] ${message}: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
79
|
+
});
|
|
80
|
+
const headers = {
|
|
81
|
+
"content-type": "application/json",
|
|
82
|
+
...config.headers,
|
|
83
|
+
};
|
|
84
|
+
const logsUrl = signalUrl(config.collectorUrl, "logs");
|
|
85
|
+
const metricsUrl = signalUrl(config.collectorUrl, "metrics");
|
|
86
|
+
async function post(url, body) {
|
|
87
|
+
try {
|
|
88
|
+
const res = await doFetch(url, {
|
|
89
|
+
method: "POST",
|
|
90
|
+
headers,
|
|
91
|
+
body: JSON.stringify(body),
|
|
92
|
+
});
|
|
93
|
+
if (!res.ok) {
|
|
94
|
+
onExportError(`OTLP/HTTP export to ${url} returned ${res.status}`, new Error(`status ${res.status}`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
// Export failure must NEVER break business work (§ 4.1 / R1).
|
|
99
|
+
onExportError(`OTLP/HTTP export to ${url} failed`, err);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Emit a single monotonic DELTA counter datapoint over OTLP/HTTP. Shared by
|
|
104
|
+
* the public `counter().inc()` AND the internal D15 redaction-failure emit
|
|
105
|
+
* (workerd has no persistent SDK metric registry, so the fail-closed
|
|
106
|
+
* `telemetry.sdk.redaction_failure_total` is emitted through this same
|
|
107
|
+
* fetch-based path — best-effort, § 7.3).
|
|
108
|
+
*/
|
|
109
|
+
async function emitCounter(name, by, attributes) {
|
|
110
|
+
const nowNano = `${BigInt(Date.now()) * 1000000n}`;
|
|
111
|
+
const point = {
|
|
112
|
+
name,
|
|
113
|
+
value: by,
|
|
114
|
+
attributes,
|
|
115
|
+
// Delta window: for a stateless Workers emit each increment IS its own
|
|
116
|
+
// window, so start == time (a point-in-time delta of `by`).
|
|
117
|
+
startTimeUnixNano: nowNano,
|
|
118
|
+
timeUnixNano: nowNano,
|
|
119
|
+
};
|
|
120
|
+
await post(metricsUrl, buildMetricsExportBody(resource, SCOPE_NAME, [point]));
|
|
121
|
+
}
|
|
122
|
+
async function emitLog(level, msg, opts) {
|
|
123
|
+
// D15 SDK-side redaction (15-telemetry § 7.3 / § 7.5, LOCKED), run BEFORE
|
|
124
|
+
// the OTLP record is built — exactly like the Node logger (`src/logger.ts`
|
|
125
|
+
// emit). Two passes: the regex/PAN scrub on the free-text `msg` and the D2
|
|
126
|
+
// PII-field-name key match on the structured `fields`. FAIL-CLOSED: if
|
|
127
|
+
// either pass returns `{ok:false}` (redaction threw), the record is DROPPED
|
|
128
|
+
// (never emitted unredacted) and `telemetry.sdk.redaction_failure_total`
|
|
129
|
+
// increments. Better to drop than leak. § 7.1/D41: this pass can't be
|
|
130
|
+
// bypassed per-service — so the Workers adapter runs it too.
|
|
131
|
+
//
|
|
132
|
+
// SCOPING: redaction runs on the LOG path ONLY. Counters carry just the
|
|
133
|
+
// controlled D26 trio (tenant_id/request_id/intent_id — low-cardinality IDs,
|
|
134
|
+
// no free text) + caller labels, and worker-lite has NO spans — consistent
|
|
135
|
+
// with § 7.3 ("logs AND span attributes"), so no counter/span redaction is
|
|
136
|
+
// needed here.
|
|
137
|
+
const msgResult = attemptRedactString(msg, config.redaction);
|
|
138
|
+
if (!msgResult.ok) {
|
|
139
|
+
await emitRedactionFailure(msgResult.reason);
|
|
140
|
+
return; // DROP — do not emit the record.
|
|
141
|
+
}
|
|
142
|
+
const rawFields = opts?.fields ?? {};
|
|
143
|
+
const hasFields = Object.keys(rawFields).length > 0;
|
|
144
|
+
const fieldsResult = hasFields
|
|
145
|
+
? attemptRedactFields(rawFields, config.redaction)
|
|
146
|
+
: { ok: true, redacted: {} };
|
|
147
|
+
if (!fieldsResult.ok) {
|
|
148
|
+
await emitRedactionFailure(fieldsResult.reason);
|
|
149
|
+
return; // DROP — do not emit the record.
|
|
150
|
+
}
|
|
151
|
+
const envelope = buildEnvelope(level, msgResult.redacted, config.serviceName, config.env, opts?.context);
|
|
152
|
+
const record = {
|
|
153
|
+
envelope,
|
|
154
|
+
// The redacted fields are a plain record; narrow to the OTLP attr value
|
|
155
|
+
// type the encoder accepts (it drops any non-primitive / null defensively).
|
|
156
|
+
fields: fieldsResult.redacted,
|
|
157
|
+
};
|
|
158
|
+
await post(logsUrl, buildLogsExportBody(resource, SCOPE_NAME, [record]));
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Emit the D15 fail-closed counter (`telemetry.sdk.redaction_failure_total`)
|
|
162
|
+
* with the `reason` label. Best-effort — a failure to emit this counter must
|
|
163
|
+
* never itself throw out of the log path (§ 4.1 / R1); `emitCounter` routes
|
|
164
|
+
* any export error through `onExportError`.
|
|
165
|
+
*/
|
|
166
|
+
async function emitRedactionFailure(reason) {
|
|
167
|
+
await emitCounter("telemetry.sdk.redaction_failure_total", 1, { reason });
|
|
168
|
+
}
|
|
169
|
+
const logger = {
|
|
170
|
+
debug: (msg, opts) => emitLog("debug", msg, opts),
|
|
171
|
+
info: (msg, opts) => emitLog("info", msg, opts),
|
|
172
|
+
warn: (msg, opts) => emitLog("warn", msg, opts),
|
|
173
|
+
error: (msg, opts) => emitLog("error", msg, opts),
|
|
174
|
+
};
|
|
175
|
+
function counter(name) {
|
|
176
|
+
function increment(by, opts) {
|
|
177
|
+
// D26 trio + caller labels. The trio derives from the explicit context;
|
|
178
|
+
// bare `tenant_id` per D20.
|
|
179
|
+
return emitCounter(name, by, {
|
|
180
|
+
...contextTrio(opts?.context),
|
|
181
|
+
...opts?.labels,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
inc(byOrOpts, maybeOpts) {
|
|
186
|
+
if (typeof byOrOpts === "number") {
|
|
187
|
+
return increment(byOrOpts, maybeOpts);
|
|
188
|
+
}
|
|
189
|
+
return increment(1, byOrOpts);
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
return { logger, counter, resource };
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Form the D13 11-field log envelope from the explicit context + config. Mirror
|
|
197
|
+
* of the Node logger's envelope construction (`src/logger.ts` `emit`). The `msg`
|
|
198
|
+
* passed here is ALREADY D15-redacted by the caller (`emitLog`); this function
|
|
199
|
+
* only shapes the envelope. Empty-string `tenant_id`/`request_id` substitution
|
|
200
|
+
* matches the Node logger when no context is active.
|
|
201
|
+
*/
|
|
202
|
+
function buildEnvelope(level, msg, service, env, ctx) {
|
|
203
|
+
return {
|
|
204
|
+
level,
|
|
205
|
+
ts: new Date().toISOString(),
|
|
206
|
+
msg,
|
|
207
|
+
service,
|
|
208
|
+
env,
|
|
209
|
+
tenant_id: ctx?.tenant_id ?? "",
|
|
210
|
+
user_id: ctx?.user_id ?? null,
|
|
211
|
+
on_behalf_of: ctx?.on_behalf_of ?? null,
|
|
212
|
+
actor_type: ctx?.actor_type,
|
|
213
|
+
request_id: ctx?.request_id ?? "",
|
|
214
|
+
trace_id: ctx?.trace_id ?? null,
|
|
215
|
+
span_id: ctx?.span_id ?? null,
|
|
216
|
+
intent_id: ctx?.intent_id ?? null,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* The D26 mandatory span-attribute trio as counter attributes. Bare `tenant_id`
|
|
221
|
+
* (D20). Only present keys are emitted; the OTLP encoder drops null/undefined.
|
|
222
|
+
*/
|
|
223
|
+
function contextTrio(ctx) {
|
|
224
|
+
return {
|
|
225
|
+
tenant_id: ctx?.tenant_id,
|
|
226
|
+
request_id: ctx?.request_id,
|
|
227
|
+
intent_id: ctx?.intent_id,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Resolve the OTLP/HTTP signal endpoint. If `base` already ends in a `/v1/*`
|
|
232
|
+
* signal path it is used verbatim; otherwise the standard path is appended
|
|
233
|
+
* (`<base>/v1/logs`, `<base>/v1/metrics`) per the OTLP/HTTP spec.
|
|
234
|
+
*/
|
|
235
|
+
function signalUrl(base, signal) {
|
|
236
|
+
const trimmed = base.replace(/\/+$/, "");
|
|
237
|
+
if (/\/v1\/(logs|metrics|traces)$/.test(trimmed))
|
|
238
|
+
return trimmed;
|
|
239
|
+
return `${trimmed}/v1/${signal}`;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/worker-lite/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,gBAAgB;AAChB,EAAE;AACF,sEAAsE;AACtE,4EAA4E;AAC5E,+EAA+E;AAC/E,gEAAgE;AAChE,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,iFAAiF;AACjF,6EAA6E;AAC7E,gFAAgF;AAChF,8EAA8E;AAC9E,+DAA+D;AAC/D,EAAE;AACF,wBAAwB;AACxB,iFAAiF;AACjF,kFAAkF;AAClF,sDAAsD;AACtD,yEAAyE;AACzE,6EAA6E;AAC7E,yEAAyE;AACzE,sCAAsC;AACtC,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,eAAe;AACf,+EAA+E;AAC/E,kCAAkC;AAClC,8EAA8E;AAC9E,+EAA+E;AAC/E,0EAA0E;AAC1E,8EAA8E;AAC9E,gEAAgE;AAChE,EAAE;AACF,iDAAiD;AACjD,+EAA+E;AAC/E,oFAAoF;AACpF,0EAA0E;AAC1E,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,iFAAiF;AACjF,8EAA8E;AAC9E,EAAE;AACF,sCAAsC;AACtC,oEAAoE;AACpE,gFAAgF;AAChF,kBAAkB;AAElB,iFAAiF;AACjF,gFAAgF;AAChF,0EAA0E;AAC1E,gFAAgF;AAChF,sDAAsD;AACtD,OAAO,EAEL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAKL,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,GACd,MAAM,gBAAgB,CAAC;AA+HxB,MAAM,UAAU,GAAG,8BAA8B,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAA6B;IAE7B,MAAM,QAAQ,GAAG,aAAa,CAAC;QAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,KAAK,EAAE,MAAM,CAAC,kBAAkB;KACjC,CAAC,CAAC;IACH,6EAA6E;IAC7E,2EAA2E;IAC3E,4DAA4D;IAC5D,MAAM,OAAO,GACX,MAAM,CAAC,SAAS,IAAK,UAAU,CAAC,KAA8B,CAAC;IACjE,MAAM,aAAa,GACjB,MAAM,CAAC,aAAa;QACpB,CAAC,CAAC,OAAe,EAAE,KAAc,EAAE,EAAE;YACnC,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,kCAAkC,OAAO,KACvC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,GAAG,MAAM,CAAC,OAAO;KAClB,CAAC;IAEF,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAE7D,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,IAAa;QAC5C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;gBAC7B,MAAM,EAAE,MAAM;gBACd,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,aAAa,CACX,uBAAuB,GAAG,aAAa,GAAG,CAAC,MAAM,EAAE,EACnD,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,MAAM,EAAE,CAAC,CAClC,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,8DAA8D;YAC9D,aAAa,CAAC,uBAAuB,GAAG,SAAS,EAAE,GAAG,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,UAAU,WAAW,CACxB,IAAY,EACZ,EAAU,EACV,UAAwD;QAExD,MAAM,OAAO,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,QAAU,EAAE,CAAC;QACrD,MAAM,KAAK,GAAuB;YAChC,IAAI;YACJ,KAAK,EAAE,EAAE;YACT,UAAU;YACV,uEAAuE;YACvE,4DAA4D;YAC5D,iBAAiB,EAAE,OAAO;YAC1B,YAAY,EAAE,OAAO;SACtB,CAAC;QACF,MAAM,IAAI,CACR,UAAU,EACV,sBAAsB,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,CACtD,CAAC;IACJ,CAAC;IAED,KAAK,UAAU,OAAO,CACpB,KAAe,EACf,GAAW,EACX,IAA0B;QAE1B,0EAA0E;QAC1E,2EAA2E;QAC3E,2EAA2E;QAC3E,uEAAuE;QACvE,4EAA4E;QAC5E,yEAAyE;QACzE,sEAAsE;QACtE,6DAA6D;QAC7D,EAAE;QACF,wEAAwE;QACxE,6EAA6E;QAC7E,2EAA2E;QAC3E,2EAA2E;QAC3E,eAAe;QACf,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;YAClB,MAAM,oBAAoB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC7C,OAAO,CAAC,iCAAiC;QAC3C,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,SAAS;YAC5B,CAAC,CAAC,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC;YAClD,CAAC,CAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAY,CAAC;QAC1C,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;YACrB,MAAM,oBAAoB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAChD,OAAO,CAAC,iCAAiC;QAC3C,CAAC;QAED,MAAM,QAAQ,GAAG,aAAa,CAC5B,KAAK,EACL,SAAS,CAAC,QAAQ,EAClB,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,GAAG,EACV,IAAI,EAAE,OAAO,CACd,CAAC;QACF,MAAM,MAAM,GAAoB;YAC9B,QAAQ;YACR,wEAAwE;YACxE,4EAA4E;YAC5E,MAAM,EAAE,YAAY,CAAC,QAGpB;SACF,CAAC;QACF,MAAM,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;OAKG;IACH,KAAK,UAAU,oBAAoB,CAAC,MAAc;QAChD,MAAM,WAAW,CAAC,uCAAuC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,MAAM,GAAiB;QAC3B,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;QACjD,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC;QAC/C,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC;QAC/C,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;KAClD,CAAC;IAEF,SAAS,OAAO,CAAC,IAAY;QAC3B,SAAS,SAAS,CAChB,EAAU,EACV,IAA6B;YAE7B,wEAAwE;YACxE,4BAA4B;YAC5B,OAAO,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE;gBAC3B,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC;gBAC7B,GAAG,IAAI,EAAE,MAAM;aAChB,CAAC,CAAC;QACL,CAAC;QACD,OAAO;YACL,GAAG,CAAC,QAA+B,EAAE,SAAuB;gBAC1D,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBACjC,OAAO,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;gBACxC,CAAC;gBACD,OAAO,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;YAChC,CAAC;SACF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CACpB,KAAe,EACf,GAAW,EACX,OAAe,EACf,GAAW,EACX,GAA8B;IAE9B,OAAO;QACL,KAAK;QACL,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,GAAG;QACH,OAAO;QACP,GAAG;QACH,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,EAAE;QAC/B,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,IAAI;QAC7B,YAAY,EAAE,GAAG,EAAE,YAAY,IAAI,IAAI;QACvC,UAAU,EAAE,GAAG,EAAE,UAAU;QAC3B,UAAU,EAAE,GAAG,EAAE,UAAU,IAAI,EAAE;QACjC,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,IAAI;QAC/B,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,IAAI;QAC7B,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,IAAI;KAClC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAClB,GAA8B;IAE9B,OAAO;QACL,SAAS,EAAE,GAAG,EAAE,SAAS;QACzB,UAAU,EAAE,GAAG,EAAE,UAAU;QAC3B,SAAS,EAAE,GAAG,EAAE,SAAS;KAC1B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAAC,IAAY,EAAE,MAA0B;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzC,IAAI,8BAA8B,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACjE,OAAO,GAAG,OAAO,OAAO,MAAM,EAAE,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { LogEnvelope } from "../types.js";
|
|
2
|
+
/** A primitive attribute value the OTLP KeyValue encoder accepts. */
|
|
3
|
+
export type AttrValue = string | number | boolean;
|
|
4
|
+
/** OTLP `KeyValue` (JSON mapping). */
|
|
5
|
+
export interface OtlpKeyValue {
|
|
6
|
+
key: string;
|
|
7
|
+
value: OtlpAnyValue;
|
|
8
|
+
}
|
|
9
|
+
/** OTLP `AnyValue` (JSON mapping) — the subset we emit. */
|
|
10
|
+
export type OtlpAnyValue = {
|
|
11
|
+
stringValue: string;
|
|
12
|
+
} | {
|
|
13
|
+
intValue: string;
|
|
14
|
+
} | {
|
|
15
|
+
doubleValue: number;
|
|
16
|
+
} | {
|
|
17
|
+
boolValue: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Resource attributes stamped on the `resource` of every export (D60). The
|
|
21
|
+
* adapter builds this once from its config; the builders below take it as-is.
|
|
22
|
+
*/
|
|
23
|
+
export interface OtlpResource {
|
|
24
|
+
attributes: OtlpKeyValue[];
|
|
25
|
+
}
|
|
26
|
+
/** Encode a single primitive into an OTLP AnyValue. */
|
|
27
|
+
export declare function toAnyValue(v: AttrValue): OtlpAnyValue;
|
|
28
|
+
/** Encode a flat attribute record into the OTLP KeyValue list. */
|
|
29
|
+
export declare function toKeyValues(attrs: Record<string, AttrValue | null | undefined>): OtlpKeyValue[];
|
|
30
|
+
/**
|
|
31
|
+
* Build the OTLP `resource` from the adapter's resource attributes (D60). The
|
|
32
|
+
* bare `env` key AND the `deployment.environment.name` semantic key are BOTH
|
|
33
|
+
* stamped — mirroring `src/otlp-adapter.ts` so the collector's env-filter OTTL
|
|
34
|
+
* gate (infra request 63337357) resolves Workers signals identically to Node
|
|
35
|
+
* ones. `service.name` is the OTel semantic-convention key.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildResource(attrs: {
|
|
38
|
+
serviceName: string;
|
|
39
|
+
env: string;
|
|
40
|
+
serviceVersion?: string;
|
|
41
|
+
extra?: Record<string, AttrValue>;
|
|
42
|
+
}): OtlpResource;
|
|
43
|
+
/**
|
|
44
|
+
* Flatten a D13 `LogEnvelope` + caller fields into the OTLP log-record
|
|
45
|
+
* attribute list. Mirrors `src/otlp-adapter.ts` `buildLogAttributes` so a
|
|
46
|
+
* Workers log row is shaped identically to a Node one: bare `tenant_id` (D20),
|
|
47
|
+
* `request_id`, and the optional identity/correlation keys.
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildLogAttributes(envelope: LogEnvelope, fields: Record<string, AttrValue | null | undefined>): OtlpKeyValue[];
|
|
50
|
+
/** A single log record to encode (envelope + already-formed extra fields). */
|
|
51
|
+
export interface WorkerLogRecord {
|
|
52
|
+
envelope: LogEnvelope;
|
|
53
|
+
fields: Record<string, AttrValue | null | undefined>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build an OTLP/HTTP `ExportLogsServiceRequest` JSON body from a batch of log
|
|
57
|
+
* records under one resource. `timeUnixNano` is derived from the envelope `ts`
|
|
58
|
+
* ISO-8601 timestamp (the log emit time), matching the Node adapter's
|
|
59
|
+
* `timestamp: Date.now()` intent but preserving the envelope's own instant.
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildLogsExportBody(resource: OtlpResource, scopeName: string, records: readonly WorkerLogRecord[]): {
|
|
62
|
+
resourceLogs: unknown[];
|
|
63
|
+
};
|
|
64
|
+
/** A single counter datapoint to encode. */
|
|
65
|
+
export interface WorkerCounterPoint {
|
|
66
|
+
name: string;
|
|
67
|
+
/** Monotonic-sum increment for this export window. */
|
|
68
|
+
value: number;
|
|
69
|
+
attributes: Record<string, AttrValue | null | undefined>;
|
|
70
|
+
/** Emission instant, unix-nanos as a decimal string. */
|
|
71
|
+
timeUnixNano: string;
|
|
72
|
+
/** Start of the delta window, unix-nanos as a decimal string. */
|
|
73
|
+
startTimeUnixNano: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build an OTLP/HTTP `ExportMetricsServiceRequest` JSON body for a batch of
|
|
77
|
+
* counter datapoints under one resource. Every counter is emitted as a
|
|
78
|
+
* monotonic `sum` with **DELTA** temporality (`aggregationTemporality: 1`) —
|
|
79
|
+
* matching D21 (delta temporality for counters) and the Node adapter's
|
|
80
|
+
* `AggregationTemporality.DELTA`. One OTLP `metric` per distinct counter name;
|
|
81
|
+
* datapoints with the same name group under it.
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildMetricsExportBody(resource: OtlpResource, scopeName: string, points: readonly WorkerCounterPoint[]): {
|
|
84
|
+
resourceMetrics: unknown[];
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Convert an ISO-8601 timestamp to unix-nanoseconds as a decimal string (the
|
|
88
|
+
* OTLP proto-JSON encoding for `fixed64` time fields). Millisecond precision
|
|
89
|
+
* (JS `Date` granularity) padded to nanos. Falls back to the current instant
|
|
90
|
+
* for an unparseable input rather than emitting `NaN`.
|
|
91
|
+
*/
|
|
92
|
+
export declare function isoToUnixNano(iso: string): string;
|
|
93
|
+
//# sourceMappingURL=otlp-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp-http.d.ts","sourceRoot":"","sources":["../../src/worker-lite/otlp-http.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,WAAW,EAAY,MAAM,aAAa,CAAC;AAEzD,qEAAqE;AACrE,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAElD,sCAAsC;AACtC,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,YAAY,CAAC;CACrB;AAED,2DAA2D;AAC3D,MAAM,MAAM,YAAY,GACpB;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GACvB;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpB;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GACvB;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAE3B;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,YAAY,EAAE,CAAC;CAC5B;AAeD,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG,YAAY,CAQrD;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC,GAClD,YAAY,EAAE,CAOhB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC,GAAG,YAAY,CAYf;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC,GACnD,YAAY,EAAE,CAehB;AAED,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;CACtD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,SAAS,eAAe,EAAE,GAClC;IAAE,YAAY,EAAE,OAAO,EAAE,CAAA;CAAE,CAsB7B;AAED,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACzD,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,kBAAkB,EAAE,GACpC;IAAE,eAAe,EAAE,OAAO,EAAE,CAAA;CAAE,CA6BhC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIjD"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// OTLP/HTTP (JSON) payload builders for the Cloudflare Workers adapter.
|
|
2
|
+
//
|
|
3
|
+
// workerd (Cloudflare Workers) CANNOT run the Node OTel SDK gRPC exporters
|
|
4
|
+
// (`@opentelemetry/exporter-*-otlp-grpc`) that `src/otlp-adapter.ts` wires —
|
|
5
|
+
// those pull `@grpc/grpc-js` + `node:*`. The Workers runtime exposes only
|
|
6
|
+
// `fetch` + Web-standard APIs, so this module hand-builds the OTLP/HTTP JSON
|
|
7
|
+
// envelope (the same wire the collector's `otlphttp` receiver accepts) and the
|
|
8
|
+
// adapter POSTs it with `fetch`. NO `@opentelemetry/*` import, NO `node:*`
|
|
9
|
+
// import — purely data-shaping over plain objects.
|
|
10
|
+
//
|
|
11
|
+
// The JSON shape follows the OTLP/HTTP spec's ExportLogsServiceRequest /
|
|
12
|
+
// ExportMetricsServiceRequest (opentelemetry-proto → JSON mapping): a
|
|
13
|
+
// `resourceLogs[]` / `resourceMetrics[]` tree with a `resource.attributes`
|
|
14
|
+
// KeyValue list, one `scopeLogs` / `scopeMetrics` entry, and the records.
|
|
15
|
+
//
|
|
16
|
+
// The log record shape reuses the canonical D13 11-field `LogEnvelope`
|
|
17
|
+
// (15-telemetry § 3 → 03-logging § 2) EXACTLY so Workers logs are wire-consistent
|
|
18
|
+
// with the Node adapter's logs (`src/otlp-adapter.ts` buildLogAttributes) — the
|
|
19
|
+
// same bare `tenant_id` key (D20), the same `request_id` / `intent_id` / `trace_id`
|
|
20
|
+
// correlation keys (D26/D3), the same `service` + `deployment.environment.name`
|
|
21
|
+
// resource attrs (D60). A counter datapoint carries the D26 mandatory
|
|
22
|
+
// span-attribute trio (`tenant_id`, `request_id`, `intent_id`) as its attributes
|
|
23
|
+
// when a context is supplied, so Workers metrics correlate per-tenant too (D20).
|
|
24
|
+
/**
|
|
25
|
+
* SeverityNumber per the OTLP logs spec (same numeric mapping the Node adapter
|
|
26
|
+
* derives via `@opentelemetry/api-logs` SeverityNumber): DEBUG=5, INFO=9,
|
|
27
|
+
* WARN=13, ERROR=17. Kept as a local constant so this module adds NO
|
|
28
|
+
* `@opentelemetry/*` dependency (workerd-safety).
|
|
29
|
+
*/
|
|
30
|
+
const SEVERITY_NUMBER = {
|
|
31
|
+
debug: 5,
|
|
32
|
+
info: 9,
|
|
33
|
+
warn: 13,
|
|
34
|
+
error: 17,
|
|
35
|
+
};
|
|
36
|
+
/** Encode a single primitive into an OTLP AnyValue. */
|
|
37
|
+
export function toAnyValue(v) {
|
|
38
|
+
if (typeof v === "boolean")
|
|
39
|
+
return { boolValue: v };
|
|
40
|
+
if (typeof v === "number") {
|
|
41
|
+
// Integers → intValue (string per proto-JSON int64 rule); non-integers →
|
|
42
|
+
// doubleValue. Matches how the collector round-trips numeric attributes.
|
|
43
|
+
return Number.isInteger(v) ? { intValue: String(v) } : { doubleValue: v };
|
|
44
|
+
}
|
|
45
|
+
return { stringValue: v };
|
|
46
|
+
}
|
|
47
|
+
/** Encode a flat attribute record into the OTLP KeyValue list. */
|
|
48
|
+
export function toKeyValues(attrs) {
|
|
49
|
+
const out = [];
|
|
50
|
+
for (const [key, v] of Object.entries(attrs)) {
|
|
51
|
+
if (v === null || v === undefined)
|
|
52
|
+
continue;
|
|
53
|
+
out.push({ key, value: toAnyValue(v) });
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build the OTLP `resource` from the adapter's resource attributes (D60). The
|
|
59
|
+
* bare `env` key AND the `deployment.environment.name` semantic key are BOTH
|
|
60
|
+
* stamped — mirroring `src/otlp-adapter.ts` so the collector's env-filter OTTL
|
|
61
|
+
* gate (infra request 63337357) resolves Workers signals identically to Node
|
|
62
|
+
* ones. `service.name` is the OTel semantic-convention key.
|
|
63
|
+
*/
|
|
64
|
+
export function buildResource(attrs) {
|
|
65
|
+
const kv = {
|
|
66
|
+
"service.name": attrs.serviceName,
|
|
67
|
+
"deployment.environment.name": attrs.env,
|
|
68
|
+
// Bare `env` — the collector env-filter OTTL gate keys on this exact name.
|
|
69
|
+
env: attrs.env,
|
|
70
|
+
...(attrs.serviceVersion
|
|
71
|
+
? { "service.version": attrs.serviceVersion }
|
|
72
|
+
: {}),
|
|
73
|
+
...attrs.extra,
|
|
74
|
+
};
|
|
75
|
+
return { attributes: toKeyValues(kv) };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Flatten a D13 `LogEnvelope` + caller fields into the OTLP log-record
|
|
79
|
+
* attribute list. Mirrors `src/otlp-adapter.ts` `buildLogAttributes` so a
|
|
80
|
+
* Workers log row is shaped identically to a Node one: bare `tenant_id` (D20),
|
|
81
|
+
* `request_id`, and the optional identity/correlation keys.
|
|
82
|
+
*/
|
|
83
|
+
export function buildLogAttributes(envelope, fields) {
|
|
84
|
+
const attrs = {
|
|
85
|
+
"service.name": envelope.service,
|
|
86
|
+
"deployment.environment.name": envelope.env,
|
|
87
|
+
tenant_id: envelope.tenant_id,
|
|
88
|
+
request_id: envelope.request_id,
|
|
89
|
+
...(envelope.user_id ? { user_id: envelope.user_id } : {}),
|
|
90
|
+
...(envelope.actor_type ? { actor_type: envelope.actor_type } : {}),
|
|
91
|
+
...(envelope.on_behalf_of ? { on_behalf_of: envelope.on_behalf_of } : {}),
|
|
92
|
+
...(envelope.intent_id ? { intent_id: envelope.intent_id } : {}),
|
|
93
|
+
...(envelope.trace_id ? { "telemetry.trace_id": envelope.trace_id } : {}),
|
|
94
|
+
...(envelope.span_id ? { "telemetry.span_id": envelope.span_id } : {}),
|
|
95
|
+
...fields,
|
|
96
|
+
};
|
|
97
|
+
return toKeyValues(attrs);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Build an OTLP/HTTP `ExportLogsServiceRequest` JSON body from a batch of log
|
|
101
|
+
* records under one resource. `timeUnixNano` is derived from the envelope `ts`
|
|
102
|
+
* ISO-8601 timestamp (the log emit time), matching the Node adapter's
|
|
103
|
+
* `timestamp: Date.now()` intent but preserving the envelope's own instant.
|
|
104
|
+
*/
|
|
105
|
+
export function buildLogsExportBody(resource, scopeName, records) {
|
|
106
|
+
const logRecords = records.map((r) => {
|
|
107
|
+
const timeUnixNano = isoToUnixNano(r.envelope.ts);
|
|
108
|
+
return {
|
|
109
|
+
timeUnixNano,
|
|
110
|
+
observedTimeUnixNano: timeUnixNano,
|
|
111
|
+
severityNumber: SEVERITY_NUMBER[r.envelope.level],
|
|
112
|
+
severityText: r.envelope.level,
|
|
113
|
+
body: { stringValue: r.envelope.msg },
|
|
114
|
+
attributes: buildLogAttributes(r.envelope, r.fields),
|
|
115
|
+
...(r.envelope.trace_id ? { traceId: r.envelope.trace_id } : {}),
|
|
116
|
+
...(r.envelope.span_id ? { spanId: r.envelope.span_id } : {}),
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
return {
|
|
120
|
+
resourceLogs: [
|
|
121
|
+
{
|
|
122
|
+
resource,
|
|
123
|
+
scopeLogs: [{ scope: { name: scopeName }, logRecords }],
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Build an OTLP/HTTP `ExportMetricsServiceRequest` JSON body for a batch of
|
|
130
|
+
* counter datapoints under one resource. Every counter is emitted as a
|
|
131
|
+
* monotonic `sum` with **DELTA** temporality (`aggregationTemporality: 1`) —
|
|
132
|
+
* matching D21 (delta temporality for counters) and the Node adapter's
|
|
133
|
+
* `AggregationTemporality.DELTA`. One OTLP `metric` per distinct counter name;
|
|
134
|
+
* datapoints with the same name group under it.
|
|
135
|
+
*/
|
|
136
|
+
export function buildMetricsExportBody(resource, scopeName, points) {
|
|
137
|
+
const byName = new Map();
|
|
138
|
+
for (const p of points) {
|
|
139
|
+
const bucket = byName.get(p.name);
|
|
140
|
+
if (bucket)
|
|
141
|
+
bucket.push(p);
|
|
142
|
+
else
|
|
143
|
+
byName.set(p.name, [p]);
|
|
144
|
+
}
|
|
145
|
+
const metrics = [...byName.entries()].map(([name, pts]) => ({
|
|
146
|
+
name,
|
|
147
|
+
sum: {
|
|
148
|
+
// 1 = AGGREGATION_TEMPORALITY_DELTA (OTLP metrics proto enum). D21.
|
|
149
|
+
aggregationTemporality: 1,
|
|
150
|
+
isMonotonic: true,
|
|
151
|
+
dataPoints: pts.map((p) => ({
|
|
152
|
+
asInt: String(Math.trunc(p.value)),
|
|
153
|
+
startTimeUnixNano: p.startTimeUnixNano,
|
|
154
|
+
timeUnixNano: p.timeUnixNano,
|
|
155
|
+
attributes: toKeyValues(p.attributes),
|
|
156
|
+
})),
|
|
157
|
+
},
|
|
158
|
+
}));
|
|
159
|
+
return {
|
|
160
|
+
resourceMetrics: [
|
|
161
|
+
{
|
|
162
|
+
resource,
|
|
163
|
+
scopeMetrics: [{ scope: { name: scopeName }, metrics }],
|
|
164
|
+
},
|
|
165
|
+
],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Convert an ISO-8601 timestamp to unix-nanoseconds as a decimal string (the
|
|
170
|
+
* OTLP proto-JSON encoding for `fixed64` time fields). Millisecond precision
|
|
171
|
+
* (JS `Date` granularity) padded to nanos. Falls back to the current instant
|
|
172
|
+
* for an unparseable input rather than emitting `NaN`.
|
|
173
|
+
*/
|
|
174
|
+
export function isoToUnixNano(iso) {
|
|
175
|
+
const ms = Date.parse(iso);
|
|
176
|
+
const epochMs = Number.isNaN(ms) ? Date.now() : ms;
|
|
177
|
+
return `${BigInt(epochMs) * 1000000n}`;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=otlp-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp-http.js","sourceRoot":"","sources":["../../src/worker-lite/otlp-http.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodii/telemetry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Substrate observability library for the Nodii microservice stack — OTel wrapper, log envelope, intent lifecycle, audit signal, agent registry, context propagation. Spec: planning hub docKey=telemetry.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
"./worker": {
|
|
35
35
|
"types": "./dist/worker/index.d.ts",
|
|
36
36
|
"default": "./dist/worker/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./worker-lite": {
|
|
39
|
+
"types": "./dist/worker-lite/index.d.ts",
|
|
40
|
+
"default": "./dist/worker-lite/index.js"
|
|
37
41
|
}
|
|
38
42
|
},
|
|
39
43
|
"files": [
|