@nodii/telemetry 0.0.1 → 0.1.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/README.md +223 -1
- package/dist/active-span.d.ts +12 -0
- package/dist/active-span.d.ts.map +1 -0
- package/dist/active-span.js +20 -0
- package/dist/active-span.js.map +1 -0
- package/dist/agent-invocable.d.ts +24 -0
- package/dist/agent-invocable.d.ts.map +1 -0
- package/dist/agent-invocable.js +64 -0
- package/dist/agent-invocable.js.map +1 -0
- package/dist/audit.d.ts +47 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +78 -0
- package/dist/audit.js.map +1 -0
- package/dist/context.d.ts +40 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +70 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +18 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -5
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +39 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +114 -0
- package/dist/init.js.map +1 -0
- package/dist/intent.d.ts +21 -0
- package/dist/intent.d.ts.map +1 -0
- package/dist/intent.js +123 -0
- package/dist/intent.js.map +1 -0
- package/dist/logger.d.ts +19 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +99 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.d.ts +53 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +152 -0
- package/dist/metrics.js.map +1 -0
- package/dist/otlp-adapter.d.ts +44 -0
- package/dist/otlp-adapter.d.ts.map +1 -0
- package/dist/otlp-adapter.js +351 -0
- package/dist/otlp-adapter.js.map +1 -0
- package/dist/outbox-emit.d.ts +34 -0
- package/dist/outbox-emit.d.ts.map +1 -0
- package/dist/outbox-emit.js +58 -0
- package/dist/outbox-emit.js.map +1 -0
- package/dist/redaction.d.ts +51 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +173 -0
- package/dist/redaction.js.map +1 -0
- package/dist/sdk-counters.d.ts +14 -0
- package/dist/sdk-counters.d.ts.map +1 -0
- package/dist/sdk-counters.js +42 -0
- package/dist/sdk-counters.js.map +1 -0
- package/dist/tracer.d.ts +63 -0
- package/dist/tracer.d.ts.map +1 -0
- package/dist/tracer.js +214 -0
- package/dist/tracer.js.map +1 -0
- package/dist/types.d.ts +230 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +66 -0
- package/dist/types.js.map +1 -0
- package/dist/uuid.d.ts +5 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +34 -0
- package/dist/uuid.js.map +1 -0
- package/package.json +28 -6
package/dist/metrics.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// Metrics per D18 / D19 / D20 / D21 / D22 / D23 / D24.
|
|
2
|
+
//
|
|
3
|
+
// Discipline at v0.1.0:
|
|
4
|
+
// - `metrics.counter()` and `metrics.histogram()` accept a name +
|
|
5
|
+
// family + description. The name MUST exist in the vocabulary
|
|
6
|
+
// registry loaded by `initTelemetry({ vocabularyRegistry })` per
|
|
7
|
+
// D24. Names not in the registry are rejected with
|
|
8
|
+
// `telemetry.sdk.cardinality_rejected_total{family, reason='not_in_vocabulary'}`
|
|
9
|
+
// and a thrown `MetricVocabularyError`.
|
|
10
|
+
// - `family` is one of the six locked families (D18). Mismatches with
|
|
11
|
+
// the registry-declared family are rejected the same way.
|
|
12
|
+
// - `tenant_id` is a bare label (D20) — the registration helper
|
|
13
|
+
// validates label keys against a deny-list that excludes `tenant.id`
|
|
14
|
+
// and `tenantId` variants.
|
|
15
|
+
// - Histograms are exponential (D19); the wrapper exposes
|
|
16
|
+
// `histogram.record(value, labels)` and stores the configuration
|
|
17
|
+
// for the OTel adapter to consume in TS-12. Max 160 buckets (D19).
|
|
18
|
+
// - Delta temporality (D21) is declared on the wrapper; the OTel
|
|
19
|
+
// adapter sets the OTLP export accordingly.
|
|
20
|
+
import { requireTelemetry } from "./init";
|
|
21
|
+
import { incSdkCounter } from "./sdk-counters";
|
|
22
|
+
import { METRIC_FAMILIES, } from "./types";
|
|
23
|
+
/** Thrown by `metrics.counter/histogram` when registration is rejected. */
|
|
24
|
+
export class MetricVocabularyError extends Error {
|
|
25
|
+
metric;
|
|
26
|
+
reason;
|
|
27
|
+
constructor(metric, reason) {
|
|
28
|
+
super(`metric "${metric}" rejected: ${reason}`);
|
|
29
|
+
this.metric = metric;
|
|
30
|
+
this.reason = reason;
|
|
31
|
+
this.name = "MetricVocabularyError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* D20: bare-label discipline. Reject `tenant.id` and `tenantId`
|
|
36
|
+
* variants at registration. Also reject any underscored Postgres-y
|
|
37
|
+
* variants like `tenantid`. The locked correct key is `tenant_id`.
|
|
38
|
+
*/
|
|
39
|
+
const FORBIDDEN_LABEL_KEYS = new Set([
|
|
40
|
+
"tenant.id",
|
|
41
|
+
"tenantId",
|
|
42
|
+
"tenantid",
|
|
43
|
+
"TENANT_ID",
|
|
44
|
+
]);
|
|
45
|
+
function validateLabelKeys(metric, family, labelKeys) {
|
|
46
|
+
for (const k of labelKeys) {
|
|
47
|
+
if (FORBIDDEN_LABEL_KEYS.has(k)) {
|
|
48
|
+
const reason = "label_key_forbidden";
|
|
49
|
+
incSdkCounter("telemetry.sdk.cardinality_rejected_total", {
|
|
50
|
+
family,
|
|
51
|
+
reason,
|
|
52
|
+
});
|
|
53
|
+
throw new MetricVocabularyError(metric, `label key '${k}' forbidden — use bare 'tenant_id' per D20`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function validateRegistration(metric, family) {
|
|
58
|
+
if (!METRIC_FAMILIES.includes(family)) {
|
|
59
|
+
const reason = "family_unknown";
|
|
60
|
+
incSdkCounter("telemetry.sdk.cardinality_rejected_total", {
|
|
61
|
+
family,
|
|
62
|
+
reason,
|
|
63
|
+
});
|
|
64
|
+
throw new MetricVocabularyError(metric, reason);
|
|
65
|
+
}
|
|
66
|
+
const cfg = requireTelemetry();
|
|
67
|
+
const entry = cfg.vocabularyRegistry[metric];
|
|
68
|
+
if (!entry) {
|
|
69
|
+
const reason = "not_in_vocabulary";
|
|
70
|
+
incSdkCounter("telemetry.sdk.cardinality_rejected_total", {
|
|
71
|
+
family,
|
|
72
|
+
reason,
|
|
73
|
+
});
|
|
74
|
+
throw new MetricVocabularyError(metric, reason);
|
|
75
|
+
}
|
|
76
|
+
if (entry.family !== family) {
|
|
77
|
+
const reason = "family_mismatch";
|
|
78
|
+
incSdkCounter("telemetry.sdk.cardinality_rejected_total", {
|
|
79
|
+
family,
|
|
80
|
+
reason,
|
|
81
|
+
});
|
|
82
|
+
throw new MetricVocabularyError(metric, `family mismatch — registry says '${entry.family}', caller said '${family}'`);
|
|
83
|
+
}
|
|
84
|
+
return entry;
|
|
85
|
+
}
|
|
86
|
+
const inProcessBackend = {
|
|
87
|
+
recordCounter(_name, _by, _labels) {
|
|
88
|
+
/* no-op; TS-12 replaces */
|
|
89
|
+
},
|
|
90
|
+
recordHistogram(_name, _value, _labels) {
|
|
91
|
+
/* no-op; TS-12 replaces */
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
let backend = inProcessBackend;
|
|
95
|
+
export function _setMetricsBackend(b) {
|
|
96
|
+
backend = b;
|
|
97
|
+
}
|
|
98
|
+
export function _resetMetricsBackendForTests() {
|
|
99
|
+
backend = inProcessBackend;
|
|
100
|
+
}
|
|
101
|
+
function counter(name, reg) {
|
|
102
|
+
const entry = validateRegistration(name, reg.family);
|
|
103
|
+
validateLabelKeys(name, reg.family, reg.labelKeys ?? []);
|
|
104
|
+
const description = reg.description || entry.description;
|
|
105
|
+
return {
|
|
106
|
+
name,
|
|
107
|
+
family: reg.family,
|
|
108
|
+
description,
|
|
109
|
+
inc(byOrLabels, maybeLabels) {
|
|
110
|
+
let by;
|
|
111
|
+
let labels;
|
|
112
|
+
if (typeof byOrLabels === "number") {
|
|
113
|
+
by = byOrLabels;
|
|
114
|
+
labels = maybeLabels ?? {};
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
by = 1;
|
|
118
|
+
labels = byOrLabels ?? {};
|
|
119
|
+
}
|
|
120
|
+
backend.recordCounter(name, by, labels);
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function histogram(name, reg) {
|
|
125
|
+
const entry = validateRegistration(name, reg.family);
|
|
126
|
+
validateLabelKeys(name, reg.family, reg.labelKeys ?? []);
|
|
127
|
+
const description = reg.description || entry.description;
|
|
128
|
+
const maxBuckets = reg.maxBuckets ?? 160;
|
|
129
|
+
if (maxBuckets > 160) {
|
|
130
|
+
throw new MetricVocabularyError(name, `maxBuckets ${maxBuckets} exceeds D19 cap (160)`);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
name,
|
|
134
|
+
family: reg.family,
|
|
135
|
+
description,
|
|
136
|
+
maxBuckets,
|
|
137
|
+
record(value, labels = {}) {
|
|
138
|
+
backend.recordHistogram(name, value, labels);
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* The `metrics.*` namespace (D149 verbatim name). Use:
|
|
144
|
+
*
|
|
145
|
+
* const c = metrics.counter('billing_payments_total', { family: 'async_worker', description: '...' });
|
|
146
|
+
* c.inc({ tenant_id, pgw, status });
|
|
147
|
+
*/
|
|
148
|
+
export const metrics = {
|
|
149
|
+
counter,
|
|
150
|
+
histogram,
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { LoggerProvider } from "@opentelemetry/sdk-logs";
|
|
2
|
+
import { MeterProvider } from "@opentelemetry/sdk-metrics";
|
|
3
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
4
|
+
import { type CounterHandle, type HistogramHandle } from "./metrics";
|
|
5
|
+
import type { ErrorHandlingConfig, ResourceAttributes } from "./types";
|
|
6
|
+
/** Config for the OTLP adapter — the subset of init config it needs. */
|
|
7
|
+
export interface OtlpAdapterConfig {
|
|
8
|
+
serviceName: string;
|
|
9
|
+
env: string;
|
|
10
|
+
serviceVersion?: string;
|
|
11
|
+
deploymentRegion?: string;
|
|
12
|
+
otlpEndpoint: string;
|
|
13
|
+
errorHandling: ErrorHandlingConfig;
|
|
14
|
+
resourceAttributes: Record<string, string | number | boolean>;
|
|
15
|
+
}
|
|
16
|
+
/** Handle returned by `installOtlpAdapter` so callers can shut down. */
|
|
17
|
+
export interface OtlpAdapterHandle {
|
|
18
|
+
/** Force-flushes all signal pipelines (spans + logs + metrics). */
|
|
19
|
+
forceFlush(): Promise<void>;
|
|
20
|
+
/** Shuts everything down. Calls flush first. */
|
|
21
|
+
shutdown(): Promise<void>;
|
|
22
|
+
/** Direct accessor — used by Lambda lifecycle wrappers. */
|
|
23
|
+
tracerProvider: NodeTracerProvider;
|
|
24
|
+
loggerProvider: LoggerProvider;
|
|
25
|
+
meterProvider: MeterProvider;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Installs the real OTLP exporters by replacing the no-op emitter,
|
|
29
|
+
* sink, and backend with adapters that flush to OTel SDK providers
|
|
30
|
+
* wired to OTLP gRPC.
|
|
31
|
+
*
|
|
32
|
+
* Idempotent — second call returns the same handle.
|
|
33
|
+
*/
|
|
34
|
+
export declare function installOtlpAdapter(cfg: OtlpAdapterConfig): OtlpAdapterHandle;
|
|
35
|
+
/** Force-flushes the active OTLP pipelines. No-op when not installed. */
|
|
36
|
+
export declare function forceFlush(): Promise<void>;
|
|
37
|
+
/** Shuts down the OTLP pipelines. No-op when not installed. */
|
|
38
|
+
export declare function shutdownOtlpAdapter(): Promise<void>;
|
|
39
|
+
/** For tests + introspection. */
|
|
40
|
+
export declare function getOtlpAdapterHandle(): OtlpAdapterHandle | null;
|
|
41
|
+
/** Test-only reset; does NOT shutdown providers. */
|
|
42
|
+
export declare function _resetOtlpAdapterForTests(): void;
|
|
43
|
+
export type { CounterHandle, HistogramHandle, ResourceAttributes };
|
|
44
|
+
//# sourceMappingURL=otlp-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp-adapter.d.ts","sourceRoot":"","sources":["../src/otlp-adapter.ts"],"names":[],"mappings":"AAkCA,OAAO,EAEL,cAAc,EACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAEL,aAAa,EAEd,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;AAQvC,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,eAAe,EAGrB,MAAM,WAAW,CAAC;AAGnB,OAAO,KAAK,EACV,mBAAmB,EAEnB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,mBAAmB,CAAC;IACnC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC/D;AAED,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,2DAA2D;IAC3D,cAAc,EAAE,kBAAkB,CAAC;IACnC,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,aAAa,CAAC;CAC9B;AAID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,GAAG,iBAAiB,CA2M5E;AAED,yEAAyE;AACzE,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAGhD;AAED,+DAA+D;AAC/D,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAGzD;AAED,iCAAiC;AACjC,wBAAgB,oBAAoB,IAAI,iBAAiB,GAAG,IAAI,CAE/D;AAED,oDAAoD;AACpD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAkHD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
// Real OTLP wiring per D153 + D154. This module replaces the no-op
|
|
2
|
+
// emitters/sinks/backends installed by tracer.ts, logger.ts, and
|
|
3
|
+
// metrics.ts at module-init time with real OTel SDK exporters writing
|
|
4
|
+
// to an OTLP gRPC collector (signoz/signoz-otel-collector) at
|
|
5
|
+
// `OTLPEndpoint` (default `http://localhost:4317`).
|
|
6
|
+
//
|
|
7
|
+
// Wired here:
|
|
8
|
+
// - NodeTracerProvider + BatchSpanProcessor + OTLPTraceExporter
|
|
9
|
+
// - LoggerProvider + BatchLogRecordProcessor + OTLPLogExporter
|
|
10
|
+
// - MeterProvider + PeriodicExportingMetricReader + OTLPMetricExporter
|
|
11
|
+
//
|
|
12
|
+
// We do NOT call NodeSDK.start() — instead we wire providers directly
|
|
13
|
+
// so we can keep the existing SpanEmitter / LogSink / MetricsBackend
|
|
14
|
+
// injection points the rest of the library depends on. This way we
|
|
15
|
+
// don't break the existing v0.1.0 API surface or its tests.
|
|
16
|
+
import { credentials } from "@grpc/grpc-js";
|
|
17
|
+
import { SpanKind as OtelSpanKind, SpanStatusCode, TraceFlags, context as otelContext, trace as otelTrace, } from "@opentelemetry/api";
|
|
18
|
+
import { SeverityNumber, logs as otelLogs, } from "@opentelemetry/api-logs";
|
|
19
|
+
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-grpc";
|
|
20
|
+
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-grpc";
|
|
21
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";
|
|
22
|
+
import { Resource } from "@opentelemetry/resources";
|
|
23
|
+
import { BatchLogRecordProcessor, LoggerProvider, } from "@opentelemetry/sdk-logs";
|
|
24
|
+
import { AggregationTemporality, MeterProvider, PeriodicExportingMetricReader, } from "@opentelemetry/sdk-metrics";
|
|
25
|
+
import { BatchSpanProcessor, NodeTracerProvider, } from "@opentelemetry/sdk-trace-node";
|
|
26
|
+
import { ATTR_DEPLOYMENT_ENVIRONMENT_NAME, ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from "@opentelemetry/semantic-conventions";
|
|
27
|
+
import { _setLogSink } from "./logger";
|
|
28
|
+
import { _setMetricsBackend, } from "./metrics";
|
|
29
|
+
import { incSdkCounter } from "./sdk-counters";
|
|
30
|
+
import { _setSpanEmitter } from "./tracer";
|
|
31
|
+
let activeHandle = null;
|
|
32
|
+
/**
|
|
33
|
+
* Installs the real OTLP exporters by replacing the no-op emitter,
|
|
34
|
+
* sink, and backend with adapters that flush to OTel SDK providers
|
|
35
|
+
* wired to OTLP gRPC.
|
|
36
|
+
*
|
|
37
|
+
* Idempotent — second call returns the same handle.
|
|
38
|
+
*/
|
|
39
|
+
export function installOtlpAdapter(cfg) {
|
|
40
|
+
if (activeHandle)
|
|
41
|
+
return activeHandle;
|
|
42
|
+
// Normalize the endpoint so all 3 languages accept the same shape.
|
|
43
|
+
// TS's OTLP exporter requires the `http://` or `https://` scheme on
|
|
44
|
+
// `url`. Python/Go accept bare host:port. We accept either and
|
|
45
|
+
// canonicalize for TS by adding `http://` if missing.
|
|
46
|
+
const otlpUrl = normalizeOtlpUrlForTs(cfg.otlpEndpoint);
|
|
47
|
+
const resource = new Resource({
|
|
48
|
+
[ATTR_SERVICE_NAME]: cfg.serviceName,
|
|
49
|
+
[ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: cfg.env,
|
|
50
|
+
...(cfg.serviceVersion
|
|
51
|
+
? { [ATTR_SERVICE_VERSION]: cfg.serviceVersion }
|
|
52
|
+
: {}),
|
|
53
|
+
...(cfg.deploymentRegion ? { "cloud.region": cfg.deploymentRegion } : {}),
|
|
54
|
+
...cfg.resourceAttributes,
|
|
55
|
+
});
|
|
56
|
+
// ── Trace pipeline. D153 sending_queue=5000; drop on full.
|
|
57
|
+
const traceExporter = new OTLPTraceExporter({
|
|
58
|
+
url: otlpUrl,
|
|
59
|
+
credentials: credentials.createInsecure(),
|
|
60
|
+
});
|
|
61
|
+
const batchSpanProcessor = new BatchSpanProcessor(traceExporter, {
|
|
62
|
+
maxQueueSize: cfg.errorHandling.otlpSendingQueueSize,
|
|
63
|
+
maxExportBatchSize: 512,
|
|
64
|
+
scheduledDelayMillis: 1000,
|
|
65
|
+
exportTimeoutMillis: 10000,
|
|
66
|
+
});
|
|
67
|
+
const tracerProvider = new NodeTracerProvider({
|
|
68
|
+
resource,
|
|
69
|
+
spanProcessors: [batchSpanProcessor],
|
|
70
|
+
});
|
|
71
|
+
tracerProvider.register();
|
|
72
|
+
// ── Log pipeline. D153 backpressure shares the same lock.
|
|
73
|
+
const logExporter = new OTLPLogExporter({
|
|
74
|
+
url: otlpUrl,
|
|
75
|
+
credentials: credentials.createInsecure(),
|
|
76
|
+
});
|
|
77
|
+
const logRecordProcessor = new BatchLogRecordProcessor(logExporter, {
|
|
78
|
+
maxQueueSize: cfg.errorHandling.otlpSendingQueueSize,
|
|
79
|
+
maxExportBatchSize: 512,
|
|
80
|
+
scheduledDelayMillis: 1000,
|
|
81
|
+
exportTimeoutMillis: 10000,
|
|
82
|
+
});
|
|
83
|
+
const loggerProvider = new LoggerProvider({ resource });
|
|
84
|
+
loggerProvider.addLogRecordProcessor(logRecordProcessor);
|
|
85
|
+
otelLogs.setGlobalLoggerProvider(loggerProvider);
|
|
86
|
+
// ── Metrics pipeline. D21: delta temporality for counters + histograms.
|
|
87
|
+
const metricExporter = new OTLPMetricExporter({
|
|
88
|
+
url: otlpUrl,
|
|
89
|
+
credentials: credentials.createInsecure(),
|
|
90
|
+
temporalityPreference: AggregationTemporality.DELTA,
|
|
91
|
+
});
|
|
92
|
+
const metricReader = new PeriodicExportingMetricReader({
|
|
93
|
+
exporter: metricExporter,
|
|
94
|
+
exportIntervalMillis: 10000,
|
|
95
|
+
exportTimeoutMillis: 5000,
|
|
96
|
+
});
|
|
97
|
+
const meterProvider = new MeterProvider({
|
|
98
|
+
resource,
|
|
99
|
+
readers: [metricReader],
|
|
100
|
+
});
|
|
101
|
+
// ── Wire SpanEmitter to OTel tracer.
|
|
102
|
+
const otelTracer = tracerProvider.getTracer(cfg.serviceName);
|
|
103
|
+
const spanEmitter = {
|
|
104
|
+
emit(record) {
|
|
105
|
+
// We already produced our own span record with hex IDs. The
|
|
106
|
+
// cleanest path is to start an OTel span with the same name,
|
|
107
|
+
// attributes, and status using the existing trace context, then
|
|
108
|
+
// end it. Timestamps are taken from the record so the trace
|
|
109
|
+
// shape matches.
|
|
110
|
+
try {
|
|
111
|
+
const span = otelTracer.startSpan(record.name, {
|
|
112
|
+
startTime: hrtimeFromNs(record.start_ns),
|
|
113
|
+
attributes: toAttributes(record.attributes),
|
|
114
|
+
kind: kindToOTel(record.kind),
|
|
115
|
+
});
|
|
116
|
+
for (const ev of record.events) {
|
|
117
|
+
span.addEvent(ev.name, ev.attributes ? toAttributes(ev.attributes) : undefined, hrtimeFromNs(ev.ts_ns));
|
|
118
|
+
}
|
|
119
|
+
if (record.status === "ERROR") {
|
|
120
|
+
span.setStatus({
|
|
121
|
+
code: SpanStatusCode.ERROR,
|
|
122
|
+
message: record.status_message,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
else if (record.status === "OK") {
|
|
126
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
127
|
+
}
|
|
128
|
+
span.end(hrtimeFromNs(record.end_ns));
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
incSdkCounter("telemetry.sdk.export_failures_total", {
|
|
132
|
+
signal: "traces",
|
|
133
|
+
reason: classifyExportError(err),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
_setSpanEmitter(spanEmitter);
|
|
139
|
+
// ── Wire LogSink to OTel logger.
|
|
140
|
+
const otelLogger = loggerProvider.getLogger(cfg.serviceName);
|
|
141
|
+
const logSink = (envelope, fields) => {
|
|
142
|
+
try {
|
|
143
|
+
const traceCtx = currentTraceCtx();
|
|
144
|
+
const merged = {
|
|
145
|
+
severityNumber: severityFromLevel(envelope.level),
|
|
146
|
+
severityText: envelope.level,
|
|
147
|
+
body: envelope.msg,
|
|
148
|
+
attributes: toAttributes(buildLogAttributes(envelope, fields)),
|
|
149
|
+
timestamp: Date.now(),
|
|
150
|
+
...(traceCtx
|
|
151
|
+
? {
|
|
152
|
+
traceId: traceCtx.traceId,
|
|
153
|
+
spanId: traceCtx.spanId,
|
|
154
|
+
traceFlags: traceCtx.traceFlags,
|
|
155
|
+
}
|
|
156
|
+
: {}),
|
|
157
|
+
};
|
|
158
|
+
otelLogger.emit(merged);
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
incSdkCounter("telemetry.sdk.export_failures_total", {
|
|
162
|
+
signal: "logs",
|
|
163
|
+
reason: classifyExportError(err),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
_setLogSink(logSink);
|
|
168
|
+
// ── Wire MetricsBackend to OTel meter.
|
|
169
|
+
const meter = meterProvider.getMeter(cfg.serviceName);
|
|
170
|
+
const counterCache = new Map();
|
|
171
|
+
const histogramCache = new Map();
|
|
172
|
+
const otelBackend = {
|
|
173
|
+
recordCounter(name, by, labels) {
|
|
174
|
+
try {
|
|
175
|
+
let c = counterCache.get(name);
|
|
176
|
+
if (!c) {
|
|
177
|
+
c = meter.createCounter(name);
|
|
178
|
+
counterCache.set(name, c);
|
|
179
|
+
}
|
|
180
|
+
c.add(by, toAttributes(labels));
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
incSdkCounter("telemetry.sdk.export_failures_total", {
|
|
184
|
+
signal: "metrics",
|
|
185
|
+
reason: classifyExportError(err),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
recordHistogram(name, value, labels) {
|
|
190
|
+
try {
|
|
191
|
+
let h = histogramCache.get(name);
|
|
192
|
+
if (!h) {
|
|
193
|
+
h = meter.createHistogram(name);
|
|
194
|
+
histogramCache.set(name, h);
|
|
195
|
+
}
|
|
196
|
+
h.record(value, toAttributes(labels));
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
incSdkCounter("telemetry.sdk.export_failures_total", {
|
|
200
|
+
signal: "metrics",
|
|
201
|
+
reason: classifyExportError(err),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
_setMetricsBackend(otelBackend);
|
|
207
|
+
activeHandle = {
|
|
208
|
+
tracerProvider,
|
|
209
|
+
loggerProvider,
|
|
210
|
+
meterProvider,
|
|
211
|
+
async forceFlush() {
|
|
212
|
+
await Promise.allSettled([
|
|
213
|
+
tracerProvider.forceFlush(),
|
|
214
|
+
loggerProvider.forceFlush(),
|
|
215
|
+
meterProvider.forceFlush(),
|
|
216
|
+
]);
|
|
217
|
+
},
|
|
218
|
+
async shutdown() {
|
|
219
|
+
await this.forceFlush();
|
|
220
|
+
await Promise.allSettled([
|
|
221
|
+
tracerProvider.shutdown(),
|
|
222
|
+
loggerProvider.shutdown(),
|
|
223
|
+
meterProvider.shutdown(),
|
|
224
|
+
]);
|
|
225
|
+
activeHandle = null;
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
return activeHandle;
|
|
229
|
+
}
|
|
230
|
+
/** Force-flushes the active OTLP pipelines. No-op when not installed. */
|
|
231
|
+
export async function forceFlush() {
|
|
232
|
+
if (!activeHandle)
|
|
233
|
+
return;
|
|
234
|
+
await activeHandle.forceFlush();
|
|
235
|
+
}
|
|
236
|
+
/** Shuts down the OTLP pipelines. No-op when not installed. */
|
|
237
|
+
export async function shutdownOtlpAdapter() {
|
|
238
|
+
if (!activeHandle)
|
|
239
|
+
return;
|
|
240
|
+
await activeHandle.shutdown();
|
|
241
|
+
}
|
|
242
|
+
/** For tests + introspection. */
|
|
243
|
+
export function getOtlpAdapterHandle() {
|
|
244
|
+
return activeHandle;
|
|
245
|
+
}
|
|
246
|
+
/** Test-only reset; does NOT shutdown providers. */
|
|
247
|
+
export function _resetOtlpAdapterForTests() {
|
|
248
|
+
activeHandle = null;
|
|
249
|
+
}
|
|
250
|
+
// ── helpers ────────────────────────────────────────────────────────
|
|
251
|
+
function hrtimeFromNs(ns) {
|
|
252
|
+
const n = typeof ns === "bigint" ? ns : BigInt(Math.floor(ns));
|
|
253
|
+
const seconds = Number(n / 1000000000n);
|
|
254
|
+
const nanos = Number(n % 1000000000n);
|
|
255
|
+
return [seconds, nanos];
|
|
256
|
+
}
|
|
257
|
+
function toAttributes(attrs) {
|
|
258
|
+
const out = {};
|
|
259
|
+
for (const [k, v] of Object.entries(attrs)) {
|
|
260
|
+
if (v === null || v === undefined)
|
|
261
|
+
continue;
|
|
262
|
+
if (typeof v === "string" ||
|
|
263
|
+
typeof v === "number" ||
|
|
264
|
+
typeof v === "boolean") {
|
|
265
|
+
out[k] = v;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
out[k] = JSON.stringify(v);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return out;
|
|
272
|
+
}
|
|
273
|
+
function kindToOTel(kind) {
|
|
274
|
+
switch (kind) {
|
|
275
|
+
case "SERVER":
|
|
276
|
+
return OtelSpanKind.SERVER;
|
|
277
|
+
case "CLIENT":
|
|
278
|
+
return OtelSpanKind.CLIENT;
|
|
279
|
+
case "PRODUCER":
|
|
280
|
+
return OtelSpanKind.PRODUCER;
|
|
281
|
+
case "CONSUMER":
|
|
282
|
+
return OtelSpanKind.CONSUMER;
|
|
283
|
+
default:
|
|
284
|
+
return OtelSpanKind.INTERNAL;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function severityFromLevel(level) {
|
|
288
|
+
switch (level) {
|
|
289
|
+
case "debug":
|
|
290
|
+
return SeverityNumber.DEBUG;
|
|
291
|
+
case "info":
|
|
292
|
+
return SeverityNumber.INFO;
|
|
293
|
+
case "warn":
|
|
294
|
+
return SeverityNumber.WARN;
|
|
295
|
+
case "error":
|
|
296
|
+
return SeverityNumber.ERROR;
|
|
297
|
+
default:
|
|
298
|
+
return SeverityNumber.UNSPECIFIED;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function buildLogAttributes(envelope, fields) {
|
|
302
|
+
const attrs = {
|
|
303
|
+
"service.name": envelope.service,
|
|
304
|
+
"deployment.environment.name": envelope.env,
|
|
305
|
+
tenant_id: envelope.tenant_id,
|
|
306
|
+
request_id: envelope.request_id,
|
|
307
|
+
...(envelope.user_id ? { user_id: envelope.user_id } : {}),
|
|
308
|
+
...(envelope.actor_type ? { actor_type: envelope.actor_type } : {}),
|
|
309
|
+
...(envelope.on_behalf_of ? { on_behalf_of: envelope.on_behalf_of } : {}),
|
|
310
|
+
...(envelope.intent_id ? { intent_id: envelope.intent_id } : {}),
|
|
311
|
+
...(envelope.trace_id ? { "telemetry.trace_id": envelope.trace_id } : {}),
|
|
312
|
+
...(envelope.span_id ? { "telemetry.span_id": envelope.span_id } : {}),
|
|
313
|
+
...fields,
|
|
314
|
+
};
|
|
315
|
+
return attrs;
|
|
316
|
+
}
|
|
317
|
+
function currentTraceCtx() {
|
|
318
|
+
const span = otelTrace.getSpan(otelContext.active());
|
|
319
|
+
if (!span)
|
|
320
|
+
return null;
|
|
321
|
+
const sc = span.spanContext();
|
|
322
|
+
if (!sc.traceId)
|
|
323
|
+
return null;
|
|
324
|
+
return {
|
|
325
|
+
traceId: sc.traceId,
|
|
326
|
+
spanId: sc.spanId,
|
|
327
|
+
traceFlags: sc.traceFlags ?? TraceFlags.NONE,
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function classifyExportError(err) {
|
|
331
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
332
|
+
if (/queue/i.test(msg))
|
|
333
|
+
return "queue_full";
|
|
334
|
+
if (/timeout/i.test(msg))
|
|
335
|
+
return "timeout";
|
|
336
|
+
if (/5\d\d/.test(msg))
|
|
337
|
+
return "server_5xx";
|
|
338
|
+
return "network_error";
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Cross-language endpoint normalization. Python and Go accept
|
|
342
|
+
* `localhost:4317`; TS's OTLP gRPC exporter requires a URL with
|
|
343
|
+
* scheme. We accept both and prepend `http://` for TS if absent.
|
|
344
|
+
*/
|
|
345
|
+
function normalizeOtlpUrlForTs(endpoint) {
|
|
346
|
+
const trimmed = endpoint.trim();
|
|
347
|
+
if (/^[a-zA-Z]+:\/\//.test(trimmed))
|
|
348
|
+
return trimmed;
|
|
349
|
+
return `http://${trimmed}`;
|
|
350
|
+
}
|
|
351
|
+
//# sourceMappingURL=otlp-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp-adapter.js","sourceRoot":"","sources":["../src/otlp-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface OutboxEvent {
|
|
2
|
+
/** Locked topic format `<service>.<entity>.<verb>.v<N>`. */
|
|
3
|
+
topic: string;
|
|
4
|
+
/** Stable event id. UUIDv7 preferred. */
|
|
5
|
+
event_id: string;
|
|
6
|
+
payload: Record<string, unknown>;
|
|
7
|
+
/** Schema version embedded in the topic; surfaced here for outbox writers that want it as a column. */
|
|
8
|
+
schema_version: number;
|
|
9
|
+
}
|
|
10
|
+
export interface OutboxColumns {
|
|
11
|
+
tenant_id: string | null;
|
|
12
|
+
request_id: string | null;
|
|
13
|
+
intent_id: string | null;
|
|
14
|
+
trace_parent: string | null;
|
|
15
|
+
trace_state: string | null;
|
|
16
|
+
context_envelope: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
export type OutboxWriter = (event: OutboxEvent, columns: OutboxColumns) => Promise<void> | void;
|
|
19
|
+
/**
|
|
20
|
+
* SDK-internal: the `@nodii/telemetry/outbox` adapter or service init
|
|
21
|
+
* code sets the writer. Public callers MUST NOT call this directly.
|
|
22
|
+
*/
|
|
23
|
+
export declare function _setOutboxWriter(w: OutboxWriter): void;
|
|
24
|
+
export declare function _resetOutboxWriterForTests(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Stage an outbox row. Per D43: hybrid columns + context_envelope
|
|
27
|
+
* jsonb. The columns are derived from the active NodiiContext + OTel
|
|
28
|
+
* span; the envelope is a JSON blob of the remaining context fields.
|
|
29
|
+
*
|
|
30
|
+
* Returns the resolved columns so callers (typically the intent
|
|
31
|
+
* lifecycle) can verify what was staged.
|
|
32
|
+
*/
|
|
33
|
+
export declare function emitOutbox(event: OutboxEvent): Promise<OutboxColumns>;
|
|
34
|
+
//# sourceMappingURL=outbox-emit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox-emit.d.ts","sourceRoot":"","sources":["../src/outbox-emit.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,WAAW;IAC1B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,uGAAuG;IACvG,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,MAAM,MAAM,YAAY,GAAG,CACzB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,KACnB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAQ1B;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,YAAY,GAAG,IAAI,CAEtD;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAoB3E"}
|