@nifrajs/otel 3.5.0 → 4.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 (62) hide show
  1. package/README.md +90 -3
  2. package/dist/cache.d.ts +46 -0
  3. package/dist/cache.d.ts.map +1 -0
  4. package/dist/cache.js +78 -0
  5. package/dist/cache.js.map +1 -0
  6. package/dist/context-trace.d.ts +8 -0
  7. package/dist/context-trace.d.ts.map +1 -0
  8. package/dist/context-trace.js +16 -0
  9. package/dist/context-trace.js.map +1 -0
  10. package/dist/effects.d.ts.map +1 -1
  11. package/dist/effects.js +2 -0
  12. package/dist/effects.js.map +1 -1
  13. package/dist/events.d.ts +69 -0
  14. package/dist/events.d.ts.map +1 -0
  15. package/dist/events.js +106 -0
  16. package/dist/events.js.map +1 -0
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/jobs.d.ts +56 -0
  21. package/dist/jobs.d.ts.map +1 -0
  22. package/dist/jobs.js +98 -0
  23. package/dist/jobs.js.map +1 -0
  24. package/dist/lifecycle.d.ts +13 -1
  25. package/dist/lifecycle.d.ts.map +1 -1
  26. package/dist/lifecycle.js +12 -3
  27. package/dist/lifecycle.js.map +1 -1
  28. package/dist/metrics.d.ts.map +1 -1
  29. package/dist/metrics.js +0 -0
  30. package/dist/metrics.js.map +1 -1
  31. package/dist/otlp.d.ts.map +1 -1
  32. package/dist/otlp.js +17 -1
  33. package/dist/otlp.js.map +1 -1
  34. package/dist/route-template.d.ts +14 -0
  35. package/dist/route-template.d.ts.map +1 -0
  36. package/dist/route-template.js +38 -0
  37. package/dist/route-template.js.map +1 -0
  38. package/dist/sdk-bridge.d.ts +107 -0
  39. package/dist/sdk-bridge.d.ts.map +1 -0
  40. package/dist/sdk-bridge.js +243 -0
  41. package/dist/sdk-bridge.js.map +1 -0
  42. package/dist/span.d.ts +8 -1
  43. package/dist/span.d.ts.map +1 -1
  44. package/dist/span.js +1 -0
  45. package/dist/span.js.map +1 -1
  46. package/dist/tracing.d.ts.map +1 -1
  47. package/dist/tracing.js +11 -2
  48. package/dist/tracing.js.map +1 -1
  49. package/package.json +33 -3
  50. package/src/cache.ts +115 -0
  51. package/src/context-trace.ts +14 -0
  52. package/src/effects.ts +2 -0
  53. package/src/events.ts +170 -0
  54. package/src/index.ts +2 -0
  55. package/src/jobs.ts +141 -0
  56. package/src/lifecycle.ts +26 -3
  57. package/src/metrics.ts +0 -0
  58. package/src/otlp.ts +18 -2
  59. package/src/route-template.ts +43 -0
  60. package/src/sdk-bridge.ts +375 -0
  61. package/src/span.ts +9 -1
  62. package/src/tracing.ts +11 -2
@@ -0,0 +1,243 @@
1
+ /**
2
+ * A bridge between nifra spans and the OpenTelemetry SDK. The app passes its own `@opentelemetry/api`;
3
+ * nifra takes no dependency on it.
4
+ *
5
+ * import * as api from "@opentelemetry/api"
6
+ * import { otelBridge } from "@nifrajs/otel/sdk-bridge"
7
+ *
8
+ * const bridge = otelBridge({ api })
9
+ * app.use(tracing({ adapters: [bridge.adapter] })).use(bridge.plugin)
10
+ * // a pg / undici span started inside a handler is now a child of the request span
11
+ *
12
+ * Context propagation needs an async context manager registered with the SDK (on Node, Bun and Deno the
13
+ * AsyncLocalStorage one from `@opentelemetry/context-async-hooks`; on Workers, `nodejs_compat`).
14
+ */
15
+ import { defineIdentityPlugin } from "@nifrajs/core/server";
16
+ import { traceOfContext } from "./context-trace.js";
17
+ import { generateSpanId, generateTraceId } from "./traceparent.js";
18
+ // `SpanKind` of @opentelemetry/api, stable since 1.0. A kind is caller data, so anything unknown
19
+ // starts as server, the kind of the spans that predate the field.
20
+ function otelKind(kind) {
21
+ switch (kind) {
22
+ case "internal":
23
+ return 0;
24
+ case "client":
25
+ return 2;
26
+ case "producer":
27
+ return 3;
28
+ case "consumer":
29
+ return 4;
30
+ default:
31
+ return 1;
32
+ }
33
+ }
34
+ function otelLink(link) {
35
+ const out = {
36
+ context: { traceId: link.traceId, spanId: link.spanId, traceFlags: 0, isRemote: true },
37
+ };
38
+ if (link.attributes !== undefined)
39
+ out.attributes = { ...link.attributes };
40
+ return out;
41
+ }
42
+ // `SpanStatusCode` of @opentelemetry/api, stable since 1.0.
43
+ const STATUS_OK = 1;
44
+ const STATUS_ERROR = 2;
45
+ const SAMPLED = 1;
46
+ const INVALID = Object.freeze({
47
+ traceId: "00000000000000000000000000000000",
48
+ spanId: "0000000000000000",
49
+ traceFlags: 0,
50
+ });
51
+ /**
52
+ * A span that only carries a context. Instrumentations read the active span's `spanContext()` to pick
53
+ * their parent; nifra owns the span's lifecycle, so every other call is a no-op.
54
+ */
55
+ class ContextSpan {
56
+ resolve;
57
+ constructor(resolve) {
58
+ this.resolve = resolve;
59
+ }
60
+ spanContext() {
61
+ return this.resolve();
62
+ }
63
+ setAttribute() {
64
+ return this;
65
+ }
66
+ setAttributes() {
67
+ return this;
68
+ }
69
+ addEvent() {
70
+ return this;
71
+ }
72
+ addLink() {
73
+ return this;
74
+ }
75
+ addLinks() {
76
+ return this;
77
+ }
78
+ setStatus() {
79
+ return this;
80
+ }
81
+ updateName() {
82
+ return this;
83
+ }
84
+ end() { }
85
+ isRecording() {
86
+ return false;
87
+ }
88
+ recordException() { }
89
+ }
90
+ /** Build the bridge. See {@link OtelBridge} for what each part does. */
91
+ export function otelBridge(options) {
92
+ const api = options.api;
93
+ const maxActive = options.maxActive ?? 10_000;
94
+ const maxActiveAgeMs = options.maxActiveAgeMs ?? 5 * 60_000;
95
+ if (!Number.isSafeInteger(maxActive) || maxActive < 1) {
96
+ throw new RangeError("otelBridge maxActive must be a positive safe integer");
97
+ }
98
+ if (!Number.isSafeInteger(maxActiveAgeMs) || maxActiveAgeMs < 1) {
99
+ throw new RangeError("otelBridge maxActiveAgeMs must be a positive safe integer");
100
+ }
101
+ const now = options.now ?? Date.now;
102
+ let tracer = options.tracer;
103
+ const tracerOf = () => {
104
+ tracer ??= api.trace.getTracer("@nifrajs/otel");
105
+ return tracer;
106
+ };
107
+ let warned = false;
108
+ const onIdMismatch = options.onIdMismatch ??
109
+ (() => console.warn("[nifra/otel] mirrored spans got new ids from the SDK; pass `idGenerator: bridge.idGenerator` to the tracer provider so forwarded traceparents name real spans"));
110
+ // The ids the next SDK span must take. Set and cleared around one synchronous `startSpan` call.
111
+ let pending;
112
+ const idGenerator = {
113
+ generateTraceId() {
114
+ const id = pending?.traceId;
115
+ if (pending !== undefined)
116
+ pending.traceId = undefined;
117
+ return id ?? generateTraceId();
118
+ },
119
+ generateSpanId() {
120
+ const id = pending?.spanId;
121
+ if (pending !== undefined)
122
+ pending.spanId = undefined;
123
+ return id ?? generateSpanId();
124
+ },
125
+ };
126
+ const active = new Map();
127
+ let nextSweepAt = Number.POSITIVE_INFINITY;
128
+ const evict = (spanId) => {
129
+ const entry = active.get(spanId);
130
+ if (entry === undefined)
131
+ return;
132
+ active.delete(spanId);
133
+ try {
134
+ entry.span.setAttributes({ "nifra.bridge.evicted": true });
135
+ entry.span.end();
136
+ }
137
+ catch {
138
+ // A failing SDK cannot break the request that triggered the eviction.
139
+ }
140
+ };
141
+ // Same retention shape as effectTracing: insertion order is age order, so a sweep stops at the
142
+ // first live entry and costs O(evicted).
143
+ const sweep = () => {
144
+ const at = now();
145
+ if (!Number.isFinite(at) || at < nextSweepAt)
146
+ return at;
147
+ nextSweepAt = Number.POSITIVE_INFINITY;
148
+ for (const [spanId, entry] of active) {
149
+ const expiresAt = entry.at + maxActiveAgeMs;
150
+ if (at >= expiresAt) {
151
+ evict(spanId);
152
+ }
153
+ else {
154
+ nextSweepAt = expiresAt;
155
+ break;
156
+ }
157
+ }
158
+ return at;
159
+ };
160
+ const contextOf = (trace) => active.get(trace.spanId)?.span.spanContext() ?? {
161
+ traceId: trace.traceId,
162
+ spanId: trace.spanId,
163
+ traceFlags: trace.sampled ? SAMPLED : 0,
164
+ isRemote: false,
165
+ };
166
+ const contextWith = (active, spanContext) => api.trace.setSpan(active, new ContextSpan(spanContext));
167
+ const adapter = {
168
+ onStart(span) {
169
+ const at = sweep();
170
+ while (active.size >= maxActive) {
171
+ const oldest = active.keys().next().value;
172
+ if (oldest === undefined)
173
+ break;
174
+ evict(oldest);
175
+ }
176
+ const parentSpanId = span.parentSpanId;
177
+ let parent = api.ROOT_CONTEXT;
178
+ if (parentSpanId !== undefined) {
179
+ const mirroredParent = active.get(parentSpanId)?.span;
180
+ const parentSpan = mirroredParent ??
181
+ new ContextSpan(() => ({
182
+ traceId: span.traceId,
183
+ spanId: parentSpanId,
184
+ traceFlags: span.sampled ? SAMPLED : 0,
185
+ isRemote: true,
186
+ }));
187
+ parent = api.trace.setSpan(parent, parentSpan);
188
+ }
189
+ pending = { traceId: span.traceId, spanId: span.spanId };
190
+ let mirrored;
191
+ try {
192
+ const start = {
193
+ kind: otelKind(span.kind),
194
+ startTime: span.startTime,
195
+ attributes: { ...span.attributes },
196
+ };
197
+ if (span.links !== undefined)
198
+ start.links = span.links.map(otelLink);
199
+ mirrored = tracerOf().startSpan(span.name, start, parent);
200
+ }
201
+ finally {
202
+ pending = undefined;
203
+ }
204
+ if (!warned && mirrored.isRecording() && mirrored.spanContext().spanId !== span.spanId) {
205
+ warned = true;
206
+ onIdMismatch();
207
+ }
208
+ active.set(span.spanId, Object.freeze({ span: mirrored, at: Number.isFinite(at) ? at : 0 }));
209
+ nextSweepAt = Math.min(nextSweepAt, (Number.isFinite(at) ? at : 0) + maxActiveAgeMs);
210
+ },
211
+ onEnd(span) {
212
+ const entry = active.get(span.spanId);
213
+ if (entry === undefined)
214
+ return;
215
+ active.delete(span.spanId);
216
+ entry.span.setAttributes(span.attributes);
217
+ if (span.status !== "unset")
218
+ entry.span.setStatus({ code: span.status === "error" ? STATUS_ERROR : STATUS_OK });
219
+ entry.span.end(span.endTime);
220
+ },
221
+ };
222
+ const scope = (trace, run) => api.context.with(contextWith(api.context.active(), () => contextOf(trace)), run);
223
+ const apply = (app) => {
224
+ app.around((c, next) => {
225
+ const active = api.context.active();
226
+ const outer = api.trace.getSpan(active);
227
+ // The request span opens in `tracing()`'s derive, which runs inside this wrapper, so the
228
+ // context is resolved lazily when an instrumentation starts a child.
229
+ return api.context.with(contextWith(active, () => {
230
+ const trace = traceOfContext(c);
231
+ return trace === null ? (outer?.spanContext() ?? INVALID) : contextOf(trace);
232
+ }), next);
233
+ });
234
+ return app;
235
+ };
236
+ return {
237
+ adapter,
238
+ plugin: defineIdentityPlugin("nifra:otel-sdk-bridge", apply),
239
+ scope,
240
+ idGenerator,
241
+ };
242
+ }
243
+ //# sourceMappingURL=sdk-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-bridge.js","sourceRoot":"","sources":["../src/sdk-bridge.ts"],"names":[],"mappings":"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"}
package/dist/span.d.ts CHANGED
@@ -7,6 +7,11 @@
7
7
  */
8
8
  export type SpanStatus = "unset" | "ok" | "error";
9
9
  export type AttributeValue = string | number | boolean;
10
+ /**
11
+ * The OTel span kind. A span without one is exported as `server`, the kind of the request spans that
12
+ * predate this field.
13
+ */
14
+ export type SpanKind = "server" | "client" | "producer" | "consumer" | "internal";
10
15
  /** A non-parent causal relationship to a span in another trace (the OTel `Link` model). */
11
16
  export interface ObservationLink {
12
17
  readonly traceId: string;
@@ -23,8 +28,10 @@ export interface NifraSpan {
23
28
  readonly parentSpanId?: string;
24
29
  /** Whether the trace is sampled (the W3C flag). */
25
30
  readonly sampled: boolean;
26
- /** Span name - `"<METHOD> <path>"`. */
31
+ /** Span name - `"<METHOD> <path>"` for a request. */
27
32
  readonly name: string;
33
+ /** OTel span kind. Absent means `server`. */
34
+ readonly kind?: SpanKind;
28
35
  /** Wall-clock start (epoch ms). */
29
36
  readonly startTime: number;
30
37
  /** Wall-clock end (epoch ms) - set on completion. */
@@ -1 +1 @@
1
- {"version":3,"file":"span.d.ts","sourceRoot":"","sources":["../src/span.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,CAAA;AACjD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAEtD,2FAA2F;AAC3F,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAA;CAC/D;AAED,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,UAAU,CAAA;IAClB,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACnD,iGAAiG;IACjG,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAA;CAC5C;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IAC/B,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;CAC7B;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,GACtC,kBAAkB,CAqBpB;AAED;kDACkD;AAClD,wBAAgB,mBAAmB,CACjC,GAAG,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAEtB,GACA,kBAAkB,CAgBpB"}
1
+ {"version":3,"file":"span.d.ts","sourceRoot":"","sources":["../src/span.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,OAAO,CAAA;AACjD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AACtD;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAA;AAEjF,2FAA2F;AAC3F,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAA;CAC/D;AAED,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;IACxB,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,UAAU,CAAA;IAClB,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACnD,iGAAiG;IACjG,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,eAAe,EAAE,CAAA;CAC5C;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IAC/B,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;CAC7B;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,GACtC,kBAAkB,CAqBpB;AAED;kDACkD;AAClD,wBAAgB,mBAAmB,CACjC,GAAG,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAEtB,GACA,kBAAkB,CAiBpB"}
package/dist/span.js CHANGED
@@ -42,6 +42,7 @@ export function consoleSpanExporter(log = (l) => {
42
42
  onEnd(span) {
43
43
  log(JSON.stringify({
44
44
  name: span.name,
45
+ kind: span.kind,
45
46
  traceId: span.traceId,
46
47
  spanId: span.spanId,
47
48
  parentSpanId: span.parentSpanId,
package/dist/span.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"span.js","sourceRoot":"","sources":["../src/span.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+CH;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAAuC;IAEvC,OAAO;QACL,OAAO,CAAC,IAAI;YACV,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAA;gBACzB,CAAC;gBAAC,MAAM,CAAC;oBACP,wCAAwC;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI;YACR,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBACrB,CAAC;gBAAC,MAAM,CAAC;oBACP,wCAAwC;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED;kDACkD;AAClD,MAAM,UAAU,mBAAmB,CACjC,MAA8B,CAAC,CAAC,EAAE,EAAE;IAClC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC;IAED,OAAO;QACL,KAAK,CAAC,IAAI;YACR,GAAG,CACD,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,GAAG,IAAI,CAAC,UAAU;aACnB,CAAC,CACH,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"span.js","sourceRoot":"","sources":["../src/span.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsDH;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CACxC,QAAuC;IAEvC,OAAO;QACL,OAAO,CAAC,IAAI;YACV,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAA;gBACzB,CAAC;gBAAC,MAAM,CAAC;oBACP,wCAAwC;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI;YACR,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBACrB,CAAC;gBAAC,MAAM,CAAC;oBACP,wCAAwC;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED;kDACkD;AAClD,MAAM,UAAU,mBAAmB,CACjC,MAA8B,CAAC,CAAC,EAAE,EAAE;IAClC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC;IAED,OAAO;QACL,KAAK,CAAC,IAAI;YACR,GAAG,CACD,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,GAAG,IAAI,CAAC,UAAU;aACnB,CAAC,CACH,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAKvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAExE,yFAAyF;AACzF,MAAM,MAAM,YAAY,GAAG,kBAAkB,CAAA;AAE7C,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;IACvC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAA;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IACtC,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,uDAAuD;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAA;IACjC;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE;QACnB,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAA;QACrC,sDAAsD;QACtD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;QAC3B;;;WAGG;QACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CACvB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,gBAAgB,KACtB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;KAChC,CAAA;CACF;AAMD;uDACuD;AACvD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,YAAY,EACnB,SAAS,CAAC,EAAE,gBAAgB,GAC3B;IAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAKrE;AAUD;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,aAAa,CAAC,cAAc,CAAC,CA0GnF"}
1
+ {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EAKvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAExE,yFAAyF;AACzF,MAAM,MAAM,YAAY,GAAG,kBAAkB,CAAA;AAE7C,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;IACvC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAA;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IACtC,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,uDAAuD;IACvD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAA;IACjC;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE;QACnB,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAA;QACrC,sDAAsD;QACtD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;QAC3B;;;WAGG;QACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CACvB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,gBAAgB,KACtB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;KAChC,CAAA;CACF;AAMD;uDACuD;AACvD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,YAAY,EACnB,SAAS,CAAC,EAAE,gBAAgB,GAC3B;IAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAKrE;AAUD;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,aAAa,CAAC,cAAc,CAAC,CAkHnF"}
package/dist/tracing.js CHANGED
@@ -7,6 +7,7 @@
7
7
  import { causalityHeaders, continueCausality, readCausalityHeaders, startCausality, } from "@nifrajs/core/causality";
8
8
  import { defineContextPlugin } from "@nifrajs/core/server";
9
9
  import { createObservationLifecycle, } from "./lifecycle.js";
10
+ import { methodLabel, routeTemplateOf } from "./route-template.js";
10
11
  import { consoleSpanExporter } from "./span.js";
11
12
  /** Spread into an outgoing `fetch`/`ctx.api` call's headers to continue the trace downstream:
12
13
  * `fetch(url, { headers: traceHeaders(c.trace) })`. */
@@ -53,14 +54,22 @@ export function tracing(options = {}) {
53
54
  return defineContextPlugin("tracing", (app) => {
54
55
  for (const stop of stopHooks)
55
56
  app.onStop(stop);
57
+ const routeOf = routeTemplateOf(app);
56
58
  return app
57
59
  .derive((c) => {
58
60
  const path = pathOf(c.req.url);
61
+ const method = methodLabel(c.req.method);
62
+ // Named `{method} {route template}` per the HTTP conventions: the raw path would make every
63
+ // id its own span name, and carry whatever a path holds into every trace backend's index.
64
+ const route = routeOf(c.req.method, path);
59
65
  const observation = lifecycle.start({
60
- name: `${c.req.method} ${path}`,
66
+ name: `${method === "_OTHER" ? "HTTP" : method}${route === undefined ? "" : ` ${route}`}`,
67
+ kind: "server",
61
68
  traceparent: c.req.headers.get("traceparent"),
62
69
  attributes: {
63
- "http.request.method": c.req.method,
70
+ "http.request.method": method,
71
+ ...(method === "_OTHER" ? { "http.request.method_original": c.req.method } : {}),
72
+ ...(route === undefined ? {} : { "http.route": route }),
64
73
  "url.path": path,
65
74
  ...(serviceName === undefined ? {} : { "service.name": serviceName }),
66
75
  },
@@ -1 +1 @@
1
- {"version":3,"file":"tracing.js","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tracing.js","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nifrajs/otel",
3
- "version": "3.5.0",
3
+ "version": "4.0.2",
4
4
  "description": "Distributed tracing for nifra - W3C traceparent/tracestate propagation + OpenTelemetry-semantic-convention spans via a pluggable exporter. Bridge to the OpenTelemetry SDK or log spans directly; no SDK bundled. Edge-safe.",
5
5
  "keywords": [
6
6
  "bun",
@@ -16,6 +16,9 @@
16
16
  "w3c-traceparent"
17
17
  ],
18
18
  "type": "module",
19
+ "nifra": {
20
+ "environment": "library"
21
+ },
19
22
  "main": "./dist/index.js",
20
23
  "module": "./dist/index.js",
21
24
  "types": "./dist/index.d.ts",
@@ -34,6 +37,26 @@
34
37
  "bun": "./src/effects.ts",
35
38
  "types": "./dist/effects.d.ts",
36
39
  "default": "./dist/effects.js"
40
+ },
41
+ "./cache": {
42
+ "bun": "./src/cache.ts",
43
+ "types": "./dist/cache.d.ts",
44
+ "default": "./dist/cache.js"
45
+ },
46
+ "./jobs": {
47
+ "bun": "./src/jobs.ts",
48
+ "types": "./dist/jobs.d.ts",
49
+ "default": "./dist/jobs.js"
50
+ },
51
+ "./events": {
52
+ "bun": "./src/events.ts",
53
+ "types": "./dist/events.d.ts",
54
+ "default": "./dist/events.js"
55
+ },
56
+ "./sdk-bridge": {
57
+ "bun": "./src/sdk-bridge.ts",
58
+ "types": "./dist/sdk-bridge.d.ts",
59
+ "default": "./dist/sdk-bridge.js"
37
60
  }
38
61
  },
39
62
  "files": [
@@ -49,10 +72,17 @@
49
72
  "access": "public"
50
73
  },
51
74
  "peerDependencies": {
52
- "@nifrajs/core": "^3.5.0"
75
+ "@nifrajs/core": "^4.0.2"
53
76
  },
54
77
  "devDependencies": {
55
- "@nifrajs/core": "workspace:*"
78
+ "@nifrajs/cache": "workspace:*",
79
+ "@nifrajs/core": "workspace:*",
80
+ "@nifrajs/events": "workspace:*",
81
+ "@nifrajs/jobs": "workspace:*",
82
+ "@opentelemetry/api": "^1.9.1",
83
+ "@opentelemetry/context-async-hooks": "^2.11.0",
84
+ "@opentelemetry/instrumentation-undici": "^0.32.0",
85
+ "@opentelemetry/sdk-trace-base": "^2.11.0"
56
86
  },
57
87
  "repository": {
58
88
  "type": "git",
package/src/cache.ts ADDED
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Spans for `@nifrajs/cache` operations. `cacheTracing()` returns the cache's `observer`: every operation
3
+ * on a view bound with `cache.for(c)` becomes a child span of `c.trace` (or of `JobContext.trace` inside
4
+ * a traced job). Raw keys never leave the process unless you say so with `keyAttribute`.
5
+ *
6
+ * import { cacheTracing } from "@nifrajs/otel/cache"
7
+ * const cache = createCache({ observer: cacheTracing({ exporter }) })
8
+ * await cache.for(c).wrap(`user:${id}`, load) // span "cache wrap", nifra.cache.key_prefix = "user"
9
+ */
10
+
11
+ import { traceOfContext } from "./context-trace.ts"
12
+ import { createObservationLifecycle } from "./lifecycle.ts"
13
+ import type { AttributeValue, ObservationAdapter } from "./span.ts"
14
+
15
+ /** The `CacheEvent` of `@nifrajs/cache`, declared structurally so this package does not depend on it. */
16
+ export interface CacheTracingEvent {
17
+ readonly op: string
18
+ readonly outcome: string
19
+ readonly startedAt: number
20
+ readonly durationMs: number
21
+ readonly key: string | undefined
22
+ readonly tag: string | undefined
23
+ readonly tagCount: number
24
+ readonly context: object | undefined
25
+ }
26
+
27
+ /**
28
+ * What of a key (or an invalidated tag) a span carries:
29
+ * - `"prefix"` (default): the leading token before the first `:`, exported as `nifra.cache.key_prefix`
30
+ * only when it matches `^[a-z][a-z0-9_-]{0,31}$` - `user:42` gives `user`, a key with no `:` gives
31
+ * nothing;
32
+ * - `"none"`: nothing;
33
+ * - a function: its result is exported as `nifra.cache.key` (return `undefined` to omit). It runs on
34
+ * raw keys, so it owns the redaction.
35
+ */
36
+ export type CacheKeyAttribute = "prefix" | "none" | ((key: string) => string | undefined)
37
+
38
+ export interface CacheTracingOptions {
39
+ readonly exporter?: ObservationAdapter
40
+ readonly adapters?: readonly ObservationAdapter[]
41
+ readonly keyAttribute?: CacheKeyAttribute
42
+ }
43
+
44
+ /** Pass as `createCache({ observer })`. */
45
+ export type CacheTracingObserver = (event: CacheTracingEvent) => void
46
+
47
+ const KEY_PREFIX = /^[a-z][a-z0-9_-]{0,31}$/
48
+
49
+ function keyPrefix(key: string): string | undefined {
50
+ const end = key.indexOf(":")
51
+ if (end < 1 || end > 32) return undefined
52
+ const prefix = key.slice(0, end)
53
+ return KEY_PREFIX.test(prefix) ? prefix : undefined
54
+ }
55
+
56
+ /**
57
+ * Spans for cache operations on views bound with `for(context)`. A bound operation becomes a child of
58
+ * the context's trace; an operation on the unbound cache, or under a context with no trace, is not
59
+ * traced. A stale `wrap` that starts a background refresh gets a separate `cache revalidate` span in its
60
+ * own trace, LINKED to the request span: the refresh outlives the request, so it is not its child.
61
+ */
62
+ export function cacheTracing(options: CacheTracingOptions = {}): CacheTracingObserver {
63
+ const adapters = [
64
+ ...(options.exporter === undefined ? [] : [options.exporter]),
65
+ ...(options.adapters ?? []),
66
+ ]
67
+ const lifecycle = createObservationLifecycle({ adapters })
68
+ const keyAttribute = options.keyAttribute ?? "prefix"
69
+
70
+ const keyAttributes = (
71
+ attributes: Record<string, AttributeValue>,
72
+ value: string,
73
+ prefixName: string,
74
+ fullName: string,
75
+ ): void => {
76
+ if (keyAttribute === "none") return
77
+ if (keyAttribute === "prefix") {
78
+ const prefix = keyPrefix(value)
79
+ if (prefix !== undefined) attributes[prefixName] = prefix
80
+ return
81
+ }
82
+ try {
83
+ const exported = keyAttribute(value)
84
+ if (typeof exported === "string") attributes[fullName] = exported
85
+ } catch {
86
+ // A throwing key mapper drops the attribute, never the span.
87
+ }
88
+ }
89
+
90
+ return (event) => {
91
+ const trace = traceOfContext(event.context)
92
+ if (trace === null) return
93
+ const attributes: Record<string, AttributeValue> = {
94
+ "nifra.cache.operation": event.op,
95
+ "nifra.cache.outcome": event.outcome,
96
+ "nifra.cache.tag_count": event.tagCount,
97
+ }
98
+ if (event.key !== undefined)
99
+ keyAttributes(attributes, event.key, "nifra.cache.key_prefix", "nifra.cache.key")
100
+ if (event.tag !== undefined)
101
+ keyAttributes(attributes, event.tag, "nifra.cache.tag_prefix", "nifra.cache.tag")
102
+ const revalidation = event.op === "revalidate"
103
+ lifecycle
104
+ .start({
105
+ name: `cache ${event.op}`,
106
+ kind: "internal",
107
+ startTime: event.startedAt,
108
+ attributes,
109
+ ...(revalidation
110
+ ? { parent: null, links: [{ traceId: trace.traceId, spanId: trace.spanId }] }
111
+ : { parent: trace }),
112
+ })
113
+ .end({ status: event.outcome === "error" ? "error" : "ok", durationMs: event.durationMs })
114
+ }
115
+ }
@@ -0,0 +1,14 @@
1
+ import { type ParsedTraceparent, parseTraceparent } from "./traceparent.ts"
2
+
3
+ /**
4
+ * The trace a bound context carries (`c.trace` from `tracing()`, `JobContext.trace` from `jobTracing()`),
5
+ * read structurally and validated through its W3C `traceparent`, so a context of any other shape is
6
+ * simply untraced.
7
+ */
8
+ export function traceOfContext(context: unknown): ParsedTraceparent | null {
9
+ if (typeof context !== "object" || context === null || !("trace" in context)) return null
10
+ const trace = context.trace
11
+ if (typeof trace !== "object" || trace === null || !("traceparent" in trace)) return null
12
+ const traceparent = trace.traceparent
13
+ return typeof traceparent === "string" ? parseTraceparent(traceparent) : null
14
+ }
package/src/effects.ts CHANGED
@@ -110,6 +110,7 @@ export function effectTracing(options: EffectTracingOptions = {}): EffectTracing
110
110
  Object.freeze({
111
111
  observation: lifecycle.start({
112
112
  name: `nifra.effect.${event.stage}`,
113
+ kind: "internal",
113
114
  parent: event.trace ?? null,
114
115
  attributes: attributesOf(event),
115
116
  }),
@@ -124,6 +125,7 @@ export function effectTracing(options: EffectTracingOptions = {}): EffectTracing
124
125
  if (entry === undefined) {
125
126
  observation = lifecycle.start({
126
127
  name: `nifra.effect.${event.stage}`,
128
+ kind: "internal",
127
129
  parent: event.trace ?? null,
128
130
  attributes: attributesOf(event),
129
131
  })