@nifrajs/otel 3.5.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -3
- package/dist/cache.d.ts +46 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +78 -0
- package/dist/cache.js.map +1 -0
- package/dist/context-trace.d.ts +8 -0
- package/dist/context-trace.d.ts.map +1 -0
- package/dist/context-trace.js +16 -0
- package/dist/context-trace.js.map +1 -0
- package/dist/effects.d.ts.map +1 -1
- package/dist/effects.js +2 -0
- package/dist/effects.js.map +1 -1
- package/dist/events.d.ts +69 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +106 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jobs.d.ts +56 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +98 -0
- package/dist/jobs.js.map +1 -0
- package/dist/lifecycle.d.ts +13 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +12 -3
- package/dist/lifecycle.js.map +1 -1
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +0 -0
- package/dist/metrics.js.map +1 -1
- package/dist/otlp.d.ts.map +1 -1
- package/dist/otlp.js +17 -1
- package/dist/otlp.js.map +1 -1
- package/dist/route-template.d.ts +14 -0
- package/dist/route-template.d.ts.map +1 -0
- package/dist/route-template.js +38 -0
- package/dist/route-template.js.map +1 -0
- package/dist/sdk-bridge.d.ts +107 -0
- package/dist/sdk-bridge.d.ts.map +1 -0
- package/dist/sdk-bridge.js +243 -0
- package/dist/sdk-bridge.js.map +1 -0
- package/dist/span.d.ts +8 -1
- package/dist/span.d.ts.map +1 -1
- package/dist/span.js +1 -0
- package/dist/span.js.map +1 -1
- package/dist/tracing.d.ts.map +1 -1
- package/dist/tracing.js +11 -2
- package/dist/tracing.js.map +1 -1
- package/package.json +33 -3
- package/src/cache.ts +115 -0
- package/src/context-trace.ts +14 -0
- package/src/effects.ts +2 -0
- package/src/events.ts +170 -0
- package/src/index.ts +2 -0
- package/src/jobs.ts +141 -0
- package/src/lifecycle.ts +26 -3
- package/src/metrics.ts +0 -0
- package/src/otlp.ts +18 -2
- package/src/route-template.ts +43 -0
- package/src/sdk-bridge.ts +375 -0
- package/src/span.ts +9 -1
- 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** -
|
|
77
|
-
|
|
78
|
-
|
|
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
|
|
package/dist/cache.d.ts
ADDED
|
@@ -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"}
|
package/dist/effects.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
});
|
package/dist/effects.js.map
CHANGED
|
@@ -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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"}
|
package/dist/events.d.ts
ADDED
|
@@ -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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|