@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
package/README.md CHANGED
@@ -73,9 +73,96 @@ interface ObservationAdapter {
73
73
  - `consoleSpanExporter()` - logs each completed span as one structured line (dev / starting point).
74
74
  - `tracing({ adapters: [devtoolsAdapter, privateAdapter] })` - fan out the same lifecycle; adapter
75
75
  failures are isolated and never alter the response.
76
- - **OpenTelemetry SDK bridge** - a ~10-line adapter maps `NifraSpan` onto a real OTel `Span` from a
77
- `Tracer` (the attribute names already follow OTel conventions, so they pass straight through). Your
78
- app depends on `@opentelemetry/*`; `@nifrajs/otel` does not.
76
+ - **OpenTelemetry SDK bridge** - `otelBridge()` from `@nifrajs/otel/sdk-bridge` (below). Your app
77
+ depends on `@opentelemetry/*`; `@nifrajs/otel` does not.
78
+
79
+ Every span carries an OTel `kind`: request spans are `server`, capability and cache spans
80
+ `internal`, job enqueues `producer`, job runs and event consumers `consumer`. `otlpExporter()` sends
81
+ it as the OTLP enum; a span without one goes out as `SERVER`.
82
+
83
+ ## Cache, jobs and events
84
+
85
+ Work that runs through a context bound to the request joins the request's trace. Each tracer takes
86
+ the same `exporter` / `adapters` options as `tracing()`; pass the same adapters to all of them.
87
+
88
+ ```ts
89
+ import { cacheTracing } from "@nifrajs/otel/cache"
90
+ import { jobTracing } from "@nifrajs/otel/jobs"
91
+
92
+ const cache = createCache({ observer: cacheTracing({ exporter }) })
93
+ const queue = createQueue({ store, instrument: jobTracing({ exporter }) })
94
+ const email = queue.define("email-job", {
95
+ async handler(payload, ctx) {
96
+ await cache.for(ctx).wrap("tmpl:welcome", loadTemplate) // ctx.trace: the process span
97
+ },
98
+ })
99
+
100
+ app.use(tracing({ exporter })).get("/orders", async (c) => {
101
+ const orders = await cache.for(c).wrap("orders:recent", loadOrders) // "cache wrap", outcome miss/hit
102
+ await email.for(c).enqueue({ to: c.query.to }) // "send email-job", producer
103
+ return orders
104
+ })
105
+ ```
106
+
107
+ - **Cache** (`@nifrajs/otel/cache`): one `cache <op>` span per operation on a `cache.for(c)` view,
108
+ with `nifra.cache.operation`, `nifra.cache.outcome` (`hit`, `stale`, `miss`, `ok`, `error`) and
109
+ `nifra.cache.tag_count`. Raw keys stay in the process: the span carries the key prefix (`user:42`
110
+ gives `user`) unless `keyAttribute` is `"none"` or a function. A stale read's background refresh is a
111
+ separate `cache revalidate` trace, linked to the request span. The unbound cache is not traced.
112
+ - **Jobs** (`@nifrajs/otel/jobs`): `send <job>` (producer) per enqueue and `process <job>` (consumer)
113
+ per attempt, with the OTel messaging attributes (`messaging.system = "nifra.jobs"`,
114
+ `messaging.operation.type` / `.name`, `messaging.destination.name`, `messaging.message.id`). The
115
+ send span's context is stored with the job; each attempt is its child, plus a link to it, so one
116
+ trace runs from the request to the worker. A failed attempt is an error span, and the one that
117
+ dead-letters the job carries `nifra.job.dead_lettered = true`. A malformed stored traceparent starts
118
+ a new trace.
119
+ - **Events** (`@nifrajs/otel/events`): nifra does not deliver events, so wrap the consumer once.
120
+ `traceEventConsumer(contractOrRegistry, handler, { exporter })` gives each envelope a
121
+ `process <type>` span linked to the producer through its causality. Input that fails to parse is an
122
+ error span with an issue count and never reaches the handler. To give an envelope that link, build
123
+ its causality from the request: `contract.create(payload, { id, causality:
124
+ continueCausality(c.causality, "event", id, { relation: "emitted" }).context })`.
125
+
126
+ Error text and payloads never enter a span.
127
+
128
+ ## OpenTelemetry SDK bridge
129
+
130
+ The SDK's own instrumentations (pg, mysql2, ioredis, undici, prisma) read the active span from the
131
+ OTel context. `otelBridge()` puts nifra's spans there; the app passes its own `@opentelemetry/api`.
132
+
133
+ ```ts
134
+ import * as api from "@opentelemetry/api"
135
+ import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks"
136
+ import { otelBridge } from "@nifrajs/otel/sdk-bridge"
137
+
138
+ const bridge = otelBridge({ api })
139
+ const provider = new BasicTracerProvider({
140
+ idGenerator: bridge.idGenerator, // mirrored spans keep nifra's ids
141
+ spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter())],
142
+ })
143
+ api.trace.setGlobalTracerProvider(provider)
144
+ api.context.setGlobalContextManager(new AsyncLocalStorageContextManager().enable())
145
+
146
+ app.use(tracing({ adapters: [bridge.adapter] })).use(bridge.plugin)
147
+ const queue = createQueue({ store, instrument: jobTracing({ adapters: [bridge.adapter], scope: bridge.scope }) })
148
+ ```
149
+
150
+ - `bridge.plugin` runs each subsequent route with its request span active, so a pg query or `fetch`
151
+ inside the handler is a child of the request span. It costs one `around()` frame per request, only
152
+ when installed.
153
+ - `bridge.adapter` mirrors nifra spans into SDK spans (kind, parent, links, attributes, status,
154
+ timing), so one SDK pipeline exports everything. Leave it out and keep `otlpExporter()` if nifra's
155
+ own exporter ships nifra's spans; the SDK spans still nest under them.
156
+ - `bridge.idGenerator` makes mirrored spans keep nifra's exact trace and span ids, so the
157
+ `traceparent` nifra forwards and the trace context a job stores name real spans. Without it the
158
+ adapter warns once.
159
+ - `bridge.scope` runs code with any nifra span active: pass it to `jobTracing()` and
160
+ `traceEventConsumer()` so queries inside a job or event handler nest under it.
161
+
162
+ Context propagation needs the SDK's AsyncLocalStorage context manager. Checked on Node 26, Bun 1.4,
163
+ Deno 2.9 and workerd (`nodejs_compat`): a span started in a handler, after an `await`, is a child of
164
+ the request span on all four. The SDK's undici instrumentation records `fetch` only on Node, where
165
+ `fetch` is undici; Bun's and Deno's `fetch` produce no undici span.
79
166
 
80
167
  ## Connect your collector
81
168
 
@@ -0,0 +1,46 @@
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
+ import type { ObservationAdapter } from "./span.js";
11
+ /** The `CacheEvent` of `@nifrajs/cache`, declared structurally so this package does not depend on it. */
12
+ export interface CacheTracingEvent {
13
+ readonly op: string;
14
+ readonly outcome: string;
15
+ readonly startedAt: number;
16
+ readonly durationMs: number;
17
+ readonly key: string | undefined;
18
+ readonly tag: string | undefined;
19
+ readonly tagCount: number;
20
+ readonly context: object | undefined;
21
+ }
22
+ /**
23
+ * What of a key (or an invalidated tag) a span carries:
24
+ * - `"prefix"` (default): the leading token before the first `:`, exported as `nifra.cache.key_prefix`
25
+ * only when it matches `^[a-z][a-z0-9_-]{0,31}$` - `user:42` gives `user`, a key with no `:` gives
26
+ * nothing;
27
+ * - `"none"`: nothing;
28
+ * - a function: its result is exported as `nifra.cache.key` (return `undefined` to omit). It runs on
29
+ * raw keys, so it owns the redaction.
30
+ */
31
+ export type CacheKeyAttribute = "prefix" | "none" | ((key: string) => string | undefined);
32
+ export interface CacheTracingOptions {
33
+ readonly exporter?: ObservationAdapter;
34
+ readonly adapters?: readonly ObservationAdapter[];
35
+ readonly keyAttribute?: CacheKeyAttribute;
36
+ }
37
+ /** Pass as `createCache({ observer })`. */
38
+ export type CacheTracingObserver = (event: CacheTracingEvent) => void;
39
+ /**
40
+ * Spans for cache operations on views bound with `for(context)`. A bound operation becomes a child of
41
+ * the context's trace; an operation on the unbound cache, or under a context with no trace, is not
42
+ * traced. A stale `wrap` that starts a background refresh gets a separate `cache revalidate` span in its
43
+ * own trace, LINKED to the request span: the refresh outlives the request, so it is not its child.
44
+ */
45
+ export declare function cacheTracing(options?: CacheTracingOptions): CacheTracingObserver;
46
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAkB,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAEnE,yGAAyG;AACzG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAA;AAEzF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAA;CAC1C;AAED,2CAA2C;AAC3C,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;AAWrE;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,oBAAoB,CAqDpF"}
package/dist/cache.js ADDED
@@ -0,0 +1,78 @@
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
+ import { traceOfContext } from "./context-trace.js";
11
+ import { createObservationLifecycle } from "./lifecycle.js";
12
+ const KEY_PREFIX = /^[a-z][a-z0-9_-]{0,31}$/;
13
+ function keyPrefix(key) {
14
+ const end = key.indexOf(":");
15
+ if (end < 1 || end > 32)
16
+ return undefined;
17
+ const prefix = key.slice(0, end);
18
+ return KEY_PREFIX.test(prefix) ? prefix : undefined;
19
+ }
20
+ /**
21
+ * Spans for cache operations on views bound with `for(context)`. A bound operation becomes a child of
22
+ * the context's trace; an operation on the unbound cache, or under a context with no trace, is not
23
+ * traced. A stale `wrap` that starts a background refresh gets a separate `cache revalidate` span in its
24
+ * own trace, LINKED to the request span: the refresh outlives the request, so it is not its child.
25
+ */
26
+ export function cacheTracing(options = {}) {
27
+ const adapters = [
28
+ ...(options.exporter === undefined ? [] : [options.exporter]),
29
+ ...(options.adapters ?? []),
30
+ ];
31
+ const lifecycle = createObservationLifecycle({ adapters });
32
+ const keyAttribute = options.keyAttribute ?? "prefix";
33
+ const keyAttributes = (attributes, value, prefixName, fullName) => {
34
+ if (keyAttribute === "none")
35
+ return;
36
+ if (keyAttribute === "prefix") {
37
+ const prefix = keyPrefix(value);
38
+ if (prefix !== undefined)
39
+ attributes[prefixName] = prefix;
40
+ return;
41
+ }
42
+ try {
43
+ const exported = keyAttribute(value);
44
+ if (typeof exported === "string")
45
+ attributes[fullName] = exported;
46
+ }
47
+ catch {
48
+ // A throwing key mapper drops the attribute, never the span.
49
+ }
50
+ };
51
+ return (event) => {
52
+ const trace = traceOfContext(event.context);
53
+ if (trace === null)
54
+ return;
55
+ const attributes = {
56
+ "nifra.cache.operation": event.op,
57
+ "nifra.cache.outcome": event.outcome,
58
+ "nifra.cache.tag_count": event.tagCount,
59
+ };
60
+ if (event.key !== undefined)
61
+ keyAttributes(attributes, event.key, "nifra.cache.key_prefix", "nifra.cache.key");
62
+ if (event.tag !== undefined)
63
+ keyAttributes(attributes, event.tag, "nifra.cache.tag_prefix", "nifra.cache.tag");
64
+ const revalidation = event.op === "revalidate";
65
+ lifecycle
66
+ .start({
67
+ name: `cache ${event.op}`,
68
+ kind: "internal",
69
+ startTime: event.startedAt,
70
+ attributes,
71
+ ...(revalidation
72
+ ? { parent: null, links: [{ traceId: trace.traceId, spanId: trace.spanId }] }
73
+ : { parent: trace }),
74
+ })
75
+ .end({ status: event.outcome === "error" ? "error" : "ok", durationMs: event.durationMs });
76
+ };
77
+ }
78
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type ParsedTraceparent } from "./traceparent.js";
2
+ /**
3
+ * The trace a bound context carries (`c.trace` from `tracing()`, `JobContext.trace` from `jobTracing()`),
4
+ * read structurally and validated through its W3C `traceparent`, so a context of any other shape is
5
+ * simply untraced.
6
+ */
7
+ export declare function traceOfContext(context: unknown): ParsedTraceparent | null;
8
+ //# sourceMappingURL=context-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-trace.d.ts","sourceRoot":"","sources":["../src/context-trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAoB,MAAM,kBAAkB,CAAA;AAE3E;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAMzE"}
@@ -0,0 +1,16 @@
1
+ import { parseTraceparent } from "./traceparent.js";
2
+ /**
3
+ * The trace a bound context carries (`c.trace` from `tracing()`, `JobContext.trace` from `jobTracing()`),
4
+ * read structurally and validated through its W3C `traceparent`, so a context of any other shape is
5
+ * simply untraced.
6
+ */
7
+ export function traceOfContext(context) {
8
+ if (typeof context !== "object" || context === null || !("trace" in context))
9
+ return null;
10
+ const trace = context.trace;
11
+ if (typeof trace !== "object" || trace === null || !("traceparent" in trace))
12
+ return null;
13
+ const traceparent = trace.traceparent;
14
+ return typeof traceparent === "string" ? parseTraceparent(traceparent) : null;
15
+ }
16
+ //# sourceMappingURL=context-trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-trace.js","sourceRoot":"","sources":["../src/context-trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAE3E;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC;QAAE,OAAO,IAAI,CAAA;IACzF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACzF,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAA;IACrC,OAAO,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC/E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"effects.d.ts","sourceRoot":"","sources":["../src/effects.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAE5G,OAAO,KAAK,EAAwB,uBAAuB,EAAE,MAAM,gCAAgC,CAAA;AACnG,OAAO,KAAK,EAAa,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErE,OAAO,KAAK,EAAkB,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAEnE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD,6FAA6F;IAC7F,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAA;CAC3C;AAoBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAoGrF"}
1
+ {"version":3,"file":"effects.d.ts","sourceRoot":"","sources":["../src/effects.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAE5G,OAAO,KAAK,EAAwB,uBAAuB,EAAE,MAAM,gCAAgC,CAAA;AACnG,OAAO,KAAK,EAAa,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErE,OAAO,KAAK,EAAkB,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAEnE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD,6FAA6F;IAC7F,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAA;CAC3C;AAoBD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CAsGrF"}
package/dist/effects.js CHANGED
@@ -93,6 +93,7 @@ export function effectTracing(options = {}) {
93
93
  active.set(key, Object.freeze({
94
94
  observation: lifecycle.start({
95
95
  name: `nifra.effect.${event.stage}`,
96
+ kind: "internal",
96
97
  parent: event.trace ?? null,
97
98
  attributes: attributesOf(event),
98
99
  }),
@@ -106,6 +107,7 @@ export function effectTracing(options = {}) {
106
107
  if (entry === undefined) {
107
108
  observation = lifecycle.start({
108
109
  name: `nifra.effect.${event.stage}`,
110
+ kind: "internal",
109
111
  parent: event.trace ?? null,
110
112
  attributes: attributesOf(event),
111
113
  });
@@ -1 +1 @@
1
- {"version":3,"file":"effects.js","sourceRoot":"","sources":["../src/effects.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"effects.js","sourceRoot":"","sources":["../src/effects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Consumer spans for `@nifrajs/events` envelopes. nifra does not deliver events, so it cannot trace them
3
+ * on its own: wrap the consumer once and every envelope it receives gets a `process <type>` span, linked
4
+ * to the producer through the envelope's durable causality.
5
+ *
6
+ * import { traceEventConsumer } from "@nifrajs/otel/events"
7
+ * const consume = traceEventConsumer(orderPaid, async (event, ctx) => fulfil(event.payload), { exporter })
8
+ * await consume(message.body) // from a queue, an SSE frame, a webhook body
9
+ */
10
+ import type { CausalityContext } from "@nifrajs/core/causality";
11
+ import { type ObservationContext, type ObservationScope } from "./lifecycle.js";
12
+ import type { ObservationAdapter } from "./span.js";
13
+ /** The envelope fields a consumer span reads. `EventEnvelope` from `@nifrajs/events` has them. */
14
+ export interface TracedEventEnvelope {
15
+ readonly id: string;
16
+ readonly type: string;
17
+ readonly version: number;
18
+ readonly causality?: CausalityContext;
19
+ }
20
+ /**
21
+ * An event contract or a registry from `@nifrajs/events`, declared structurally: anything whose
22
+ * `parse(input)` never throws and reports success with an envelope, or failure with `issues` (a contract)
23
+ * or a `reason` (a registry).
24
+ */
25
+ export interface TracedEventSource<Envelope extends TracedEventEnvelope> {
26
+ /** A contract's own type, used to name the span of an envelope that failed to parse. */
27
+ readonly type?: string;
28
+ parse(input: unknown): {
29
+ readonly success: true;
30
+ readonly envelope: Envelope;
31
+ } | {
32
+ readonly success: false;
33
+ readonly issues?: readonly unknown[];
34
+ readonly reason?: string;
35
+ };
36
+ }
37
+ /** What the wrapped handler receives next to the envelope: the consumer span's trace context. */
38
+ export interface EventConsumerContext {
39
+ readonly trace: ObservationContext;
40
+ }
41
+ export type TracedEventResult<Value> = {
42
+ readonly success: true;
43
+ readonly value: Value;
44
+ } | {
45
+ readonly success: false;
46
+ readonly issueCount: number;
47
+ };
48
+ /** The traced consumer. `parent` is an ambient trace (`c.trace` in a webhook route), if there is one. */
49
+ export type TracedEventConsumer<Value> = (input: unknown, parent?: ObservationContext) => Promise<TracedEventResult<Value>>;
50
+ export interface EventTracingOptions {
51
+ readonly exporter?: ObservationAdapter;
52
+ readonly adapters?: readonly ObservationAdapter[];
53
+ /** `messaging.system`: the transport the envelopes arrive on. Default `"nifra.events"`. */
54
+ readonly system?: string;
55
+ /** Runs the handler with the consumer span active in an ambient context (see `ObservationScope`). */
56
+ readonly scope?: ObservationScope;
57
+ }
58
+ /**
59
+ * Wrap an event consumer so each envelope is one `process <type>` span (kind consumer), linked to the
60
+ * producer's span through `causalitySpanLink(envelope.causality)`. With a `parent`, the span is that
61
+ * span's child; otherwise it starts its own trace. Attributes: `nifra.event.type`, `nifra.event.version`,
62
+ * `messaging.message.id` (the envelope id), and the messaging operation.
63
+ *
64
+ * Input that fails to parse never reaches the handler: it becomes an error span carrying only an issue
65
+ * count (and a registry's bounded reason), resolves `{ success: false }`, and exports no payload. A
66
+ * throwing handler ends its span as an error and rejects.
67
+ */
68
+ export declare function traceEventConsumer<Envelope extends TracedEventEnvelope, Result>(source: TracedEventSource<Envelope>, handler: (envelope: Envelope, context: EventConsumerContext) => Result, options?: EventTracingOptions): TracedEventConsumer<Awaited<Result>>;
69
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE/D,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EAEtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAkB,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAGnE,kGAAkG;AAClG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAA;CACtC;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB,CAAC,QAAQ,SAAS,mBAAmB;IACrE,wFAAwF;IACxF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,KAAK,EAAE,OAAO,GAChB;QAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;KAAE,GACvD;QACE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAA;QACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;QACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KACzB,CAAA;CACN;AAED,iGAAiG;AACjG,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAA;CACnC;AAED,MAAM,MAAM,iBAAiB,CAAC,KAAK,IAC/B;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5D,yGAAyG;AACzG,MAAM,MAAM,mBAAmB,CAAC,KAAK,IAAI,CACvC,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,kBAAkB,KACxB,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAA;AAEtC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,qGAAqG;IACrG,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;CAClC;AASD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,SAAS,mBAAmB,EAAE,MAAM,EAC7E,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,EACnC,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,oBAAoB,KAAK,MAAM,EACtE,OAAO,GAAE,mBAAwB,GAChC,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CA8EtC"}
package/dist/events.js ADDED
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Consumer spans for `@nifrajs/events` envelopes. nifra does not deliver events, so it cannot trace them
3
+ * on its own: wrap the consumer once and every envelope it receives gets a `process <type>` span, linked
4
+ * to the producer through the envelope's durable causality.
5
+ *
6
+ * import { traceEventConsumer } from "@nifrajs/otel/events"
7
+ * const consume = traceEventConsumer(orderPaid, async (event, ctx) => fulfil(event.payload), { exporter })
8
+ * await consume(message.body) // from a queue, an SSE frame, a webhook body
9
+ */
10
+ import { causalitySpanLink } from "./causality.js";
11
+ import { createObservationLifecycle, } from "./lifecycle.js";
12
+ import { parseTraceparent } from "./traceparent.js";
13
+ const REGISTRY_REASONS = new Set([
14
+ "not-an-object",
15
+ "unknown-contract",
16
+ "invalid-payload",
17
+ ]);
18
+ const TYPE_NAME = /^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/;
19
+ /**
20
+ * Wrap an event consumer so each envelope is one `process <type>` span (kind consumer), linked to the
21
+ * producer's span through `causalitySpanLink(envelope.causality)`. With a `parent`, the span is that
22
+ * span's child; otherwise it starts its own trace. Attributes: `nifra.event.type`, `nifra.event.version`,
23
+ * `messaging.message.id` (the envelope id), and the messaging operation.
24
+ *
25
+ * Input that fails to parse never reaches the handler: it becomes an error span carrying only an issue
26
+ * count (and a registry's bounded reason), resolves `{ success: false }`, and exports no payload. A
27
+ * throwing handler ends its span as an error and rejects.
28
+ */
29
+ export function traceEventConsumer(source, handler, options = {}) {
30
+ const adapters = [
31
+ ...(options.exporter === undefined ? [] : [options.exporter]),
32
+ ...(options.adapters ?? []),
33
+ ];
34
+ const lifecycle = createObservationLifecycle({ adapters });
35
+ const system = options.system ?? "nifra.events";
36
+ const scope = options.scope;
37
+ const sourceType = typeof source.type === "string" && TYPE_NAME.test(source.type) ? source.type : undefined;
38
+ const operation = {
39
+ "messaging.system": system,
40
+ "messaging.operation.type": "process",
41
+ "messaging.operation.name": "process",
42
+ };
43
+ return async (input, parent) => {
44
+ const ambient = parent === undefined ? null : parseTraceparent(parent.traceparent);
45
+ const name = sourceType === undefined ? "process" : `process ${sourceType}`;
46
+ let parsed;
47
+ try {
48
+ parsed = source.parse(input);
49
+ }
50
+ catch (error) {
51
+ // A contract with an async payload schema throws here; that is a bug, not bad input.
52
+ lifecycle
53
+ .start({ name, kind: "consumer", parent: ambient, attributes: operation })
54
+ .end({ status: "error", attributes: { "error.type": "_OTHER" } });
55
+ throw error;
56
+ }
57
+ if (!parsed.success) {
58
+ const attributes = {
59
+ ...operation,
60
+ "nifra.event.issue_count": parsed.issues?.length ?? 1,
61
+ "error.type": "invalid_event",
62
+ };
63
+ if (parsed.reason !== undefined && REGISTRY_REASONS.has(parsed.reason))
64
+ attributes["nifra.event.parse_failure"] = parsed.reason;
65
+ lifecycle
66
+ .start({
67
+ name,
68
+ kind: "consumer",
69
+ parent: ambient,
70
+ attributes,
71
+ })
72
+ .end({ status: "error" });
73
+ return { success: false, issueCount: parsed.issues?.length ?? 1 };
74
+ }
75
+ const envelope = parsed.envelope;
76
+ const start = {
77
+ name: `process ${envelope.type}`,
78
+ kind: "consumer",
79
+ parent: ambient,
80
+ attributes: {
81
+ ...operation,
82
+ "messaging.message.id": envelope.id,
83
+ "nifra.event.type": envelope.type,
84
+ "nifra.event.version": envelope.version,
85
+ },
86
+ };
87
+ const link = envelope.causality === undefined ? undefined : causalitySpanLink(envelope.causality);
88
+ if (link !== undefined)
89
+ start.links = [link];
90
+ const span = lifecycle.start(start);
91
+ const context = { trace: span.context };
92
+ try {
93
+ const value = scope === undefined
94
+ ? await handler(envelope, context)
95
+ : await scope(span.context, () => handler(envelope, context));
96
+ span.end({ status: "ok" });
97
+ return { success: true, value };
98
+ }
99
+ catch (error) {
100
+ span.recordError(error);
101
+ span.end({ status: "error", attributes: { "error.type": "_OTHER" } });
102
+ throw error;
103
+ }
104
+ };
105
+ }
106
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -10,9 +10,9 @@
10
10
  */
11
11
  export { causalitySpanLink } from "./causality.js";
12
12
  export { type EffectTracingOptions, type EffectTracingPlugin, effectTracing, } from "./effects.js";
13
- export { type ActiveObservation, createObservationLifecycle, type EndObservation, type ObservationClock, type ObservationContext, type ObservationLifecycle, type ObservationLifecycleOptions, type ObservationParent, type StartObservation, } from "./lifecycle.js";
13
+ export { type ActiveObservation, createObservationLifecycle, type EndObservation, type ObservationClock, type ObservationContext, type ObservationLifecycle, type ObservationLifecycleOptions, type ObservationParent, type ObservationScope, type StartObservation, } from "./lifecycle.js";
14
14
  export { type OtlpExporter, type OtlpExporterOptions, otlpExporter } from "./otlp.js";
15
- export { type AttributeValue, combineObservationAdapters, consoleSpanExporter, type NifraSpan, type ObservationAdapter, type ObservationLink, type SpanStatus, } from "./span.js";
15
+ export { type AttributeValue, combineObservationAdapters, consoleSpanExporter, type NifraSpan, type ObservationAdapter, type ObservationLink, type SpanKind, type SpanStatus, } from "./span.js";
16
16
  export { formatTraceparent, generateSpanId, generateTraceId, type ParsedTraceparent, parseTraceparent, } from "./traceparent.js";
17
17
  export { type TraceContext, type TracingOptions, traceHeaders, tracing } from "./tracing.js";
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACrF,OAAO,EACL,KAAK,cAAc,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,KAAK,iBAAiB,EACtB,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACrF,OAAO,EACL,KAAK,cAAc,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,UAAU,GAChB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,KAAK,iBAAiB,EACtB,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAGL,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EAEL,0BAA0B,GAQ3B,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAA+C,YAAY,EAAE,MAAM,WAAW,CAAA;AACrF,OAAO,EAEL,0BAA0B,EAC1B,mBAAmB,GAKpB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EAEf,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAA0C,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAGL,aAAa,GACd,MAAM,cAAc,CAAA;AACrB,OAAO,EAEL,0BAA0B,GAS3B,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAA+C,YAAY,EAAE,MAAM,WAAW,CAAA;AACrF,OAAO,EAEL,0BAA0B,EAC1B,mBAAmB,GAMpB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EAEf,gBAAgB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAA0C,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA"}
package/dist/jobs.d.ts ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Spans for `@nifrajs/jobs`, following the OpenTelemetry messaging conventions. `jobTracing()` is the
3
+ * queue's `instrument`: each enqueue is a `send <job>` producer span and each attempt a `process <job>`
4
+ * consumer span. The send span's context is stored with the job, and the process span is its CHILD
5
+ * (plus a link to it), so one trace runs from the request that enqueued the job through every attempt.
6
+ *
7
+ * import { jobTracing } from "@nifrajs/otel/jobs"
8
+ * const queue = createQueue({ store, instrument: jobTracing({ exporter }) })
9
+ * await sendEmail.for(c).enqueue({ to }) // "send send-email", child of the request span
10
+ */
11
+ import { type ObservationContext, type ObservationScope } from "./lifecycle.js";
12
+ import type { ObservationAdapter } from "./span.js";
13
+ /** `JobEnqueueInfo` from `@nifrajs/jobs`, declared structurally so this package does not depend on it. */
14
+ export interface JobTracingEnqueueInfo {
15
+ readonly name: string;
16
+ readonly traceparent: string | undefined;
17
+ }
18
+ /** `JobRunInfo` from `@nifrajs/jobs`, declared structurally. */
19
+ export interface JobTracingRunInfo {
20
+ readonly id: string;
21
+ readonly name: string;
22
+ readonly attempt: number;
23
+ readonly maxAttempts: number;
24
+ readonly traceparent: string | undefined;
25
+ }
26
+ /** Structurally a `QueueInstrument` from `@nifrajs/jobs`: pass it as `createQueue({ instrument })`. */
27
+ export interface JobTracingInstrument {
28
+ enqueue(info: JobTracingEnqueueInfo, next: (scope?: {
29
+ readonly traceparent?: string;
30
+ }) => Promise<string>): Promise<string>;
31
+ run(info: JobTracingRunInfo, next: (scope?: {
32
+ readonly trace?: ObservationContext;
33
+ }) => Promise<string>): Promise<string>;
34
+ }
35
+ export interface JobTracingOptions {
36
+ readonly exporter?: ObservationAdapter;
37
+ readonly adapters?: readonly ObservationAdapter[];
38
+ /**
39
+ * Runs each attempt with its process span active in an ambient context. Pass `otelBridge().scope`
40
+ * from `@nifrajs/otel/sdk-bridge` so OpenTelemetry instrumentations (pg, undici) inside the handler
41
+ * nest under the process span.
42
+ */
43
+ readonly scope?: ObservationScope;
44
+ }
45
+ /**
46
+ * The queue instrument. Span names are `send <job name>` (kind producer) and `process <job name>` (kind
47
+ * consumer), with `messaging.system = "nifra.jobs"`, `messaging.operation.type`/`.name`,
48
+ * `messaging.destination.name` (the job name) and `messaging.message.id`. A process span also carries
49
+ * `nifra.job.attempt` and `nifra.job.outcome`; an attempt that failed is an error span, and one that
50
+ * dead-lettered the job adds `nifra.job.dead_lettered = true`. Error text is never exported.
51
+ *
52
+ * The stored traceparent is untrusted: a malformed one starts the process span as a new trace. The
53
+ * sampled flag travels with it.
54
+ */
55
+ export declare function jobTracing(options?: JobTracingOptions): JobTracingInstrument;
56
+ //# sourceMappingURL=jobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobs.d.ts","sourceRoot":"","sources":["../src/jobs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EAEtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAkB,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAGnE,0GAA0G;AAC1G,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;CACzC;AAED,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;CACzC;AAED,uGAAuG;AACvG,MAAM,WAAW,oBAAoB;IACnC,OAAO,CACL,IAAI,EAAE,qBAAqB,EAC3B,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,GACnE,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB,GAAG,CACD,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,kBAAkB,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,GACzE,OAAO,CAAC,MAAM,CAAC,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;CAClC;AAID;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,oBAAoB,CAsEhF"}