abxbus 2.4.19 → 2.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/middleware_otel_tracing.d.ts +13 -1
- package/dist/cjs/middleware_otel_tracing.js +175 -2
- package/dist/cjs/middleware_otel_tracing.js.map +2 -2
- package/dist/esm/index.js.map +2 -2
- package/dist/esm/middleware_otel_tracing.js +175 -2
- package/dist/esm/middleware_otel_tracing.js.map +2 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/middleware_otel_tracing.d.ts +13 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/middleware_otel_tracing.ts +211 -2
package/dist/cjs/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { monotonicDatetime } from './helpers.js';
|
|
|
8
8
|
export type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './middlewares.js';
|
|
9
9
|
export { OtelTracingMiddleware } from './middleware_otel_tracing.js';
|
|
10
10
|
export type { OtelTracingMiddlewareOptions } from './middleware_otel_tracing.js';
|
|
11
|
+
export type { OtelTracingSpanFactory, OtelTracingSpanFactoryInput } from './middleware_otel_tracing.js';
|
|
11
12
|
export { EventHandlerTimeoutError, EventHandlerCancelledError, EventHandlerAbortedError, EventHandlerResultSchemaError, } from './event_handler.js';
|
|
12
13
|
export type { EventConcurrencyMode, EventHandlerConcurrencyMode, EventHandlerCompletionMode, EventBusInterfaceForLockManager, } from './lock_manager.js';
|
|
13
14
|
export type { EventClass, EventHandlerCallable as EventHandler, EventPattern, EventStatus, FindOptions, FindWindow } from './types.js';
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { BaseEvent, BaseEventSchema } from './base_event.js'\nexport { EventHistory } from './event_history.js'\nexport type { EventHistoryFindOptions, EventHistoryTrimOptions } from './event_history.js'\nexport { EventResult } from './event_result.js'\nexport { EventBus } from './event_bus.js'\nexport type { EventBusJSON, EventBusOptions } from './event_bus.js'\nexport { monotonicDatetime } from './helpers.js'\nexport type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './middlewares.js'\nexport { OtelTracingMiddleware } from './middleware_otel_tracing.js'\nexport type { OtelTracingMiddlewareOptions } from './middleware_otel_tracing.js'\nexport {\n EventHandlerTimeoutError,\n EventHandlerCancelledError,\n EventHandlerAbortedError,\n EventHandlerResultSchemaError,\n} from './event_handler.js'\nexport type {\n EventConcurrencyMode,\n EventHandlerConcurrencyMode,\n EventHandlerCompletionMode,\n EventBusInterfaceForLockManager,\n} from './lock_manager.js'\nexport type { EventClass, EventHandlerCallable as EventHandler, EventPattern, EventStatus, FindOptions, FindWindow } from './types.js'\nexport { retry, clearSemaphoreRegistry, RetryTimeoutError, SemaphoreTimeoutError } from './retry.js'\nexport type { RetryOptions } from './retry.js'\nexport {\n HTTPEventBridge,\n SocketEventBridge,\n NATSEventBridge,\n RedisEventBridge,\n PostgresEventBridge,\n JSONLEventBridge,\n SQLiteEventBridge,\n} from './bridges.js'\nexport type { HTTPEventBridgeOptions } from './bridges.js'\nexport { events_suck } from './events_suck.js'\nexport type { EventsSuckClient, EventsSuckClientClass, GeneratedEvents } from './events_suck.js'\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA2C;AAC3C,2BAA6B;AAE7B,0BAA4B;AAC5B,uBAAyB;AAEzB,qBAAkC;AAElC,qCAAsC;
|
|
4
|
+
"sourcesContent": ["export { BaseEvent, BaseEventSchema } from './base_event.js'\nexport { EventHistory } from './event_history.js'\nexport type { EventHistoryFindOptions, EventHistoryTrimOptions } from './event_history.js'\nexport { EventResult } from './event_result.js'\nexport { EventBus } from './event_bus.js'\nexport type { EventBusJSON, EventBusOptions } from './event_bus.js'\nexport { monotonicDatetime } from './helpers.js'\nexport type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './middlewares.js'\nexport { OtelTracingMiddleware } from './middleware_otel_tracing.js'\nexport type { OtelTracingMiddlewareOptions } from './middleware_otel_tracing.js'\nexport type { OtelTracingSpanFactory, OtelTracingSpanFactoryInput } from './middleware_otel_tracing.js'\nexport {\n EventHandlerTimeoutError,\n EventHandlerCancelledError,\n EventHandlerAbortedError,\n EventHandlerResultSchemaError,\n} from './event_handler.js'\nexport type {\n EventConcurrencyMode,\n EventHandlerConcurrencyMode,\n EventHandlerCompletionMode,\n EventBusInterfaceForLockManager,\n} from './lock_manager.js'\nexport type { EventClass, EventHandlerCallable as EventHandler, EventPattern, EventStatus, FindOptions, FindWindow } from './types.js'\nexport { retry, clearSemaphoreRegistry, RetryTimeoutError, SemaphoreTimeoutError } from './retry.js'\nexport type { RetryOptions } from './retry.js'\nexport {\n HTTPEventBridge,\n SocketEventBridge,\n NATSEventBridge,\n RedisEventBridge,\n PostgresEventBridge,\n JSONLEventBridge,\n SQLiteEventBridge,\n} from './bridges.js'\nexport type { HTTPEventBridgeOptions } from './bridges.js'\nexport { events_suck } from './events_suck.js'\nexport type { EventsSuckClient, EventsSuckClientClass, GeneratedEvents } from './events_suck.js'\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA2C;AAC3C,2BAA6B;AAE7B,0BAA4B;AAC5B,uBAAyB;AAEzB,qBAAkC;AAElC,qCAAsC;AAGtC,2BAKO;AAQP,mBAAwF;AAExF,qBAQO;AAEP,yBAA4B;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,19 +1,29 @@
|
|
|
1
|
-
import { trace, type SpanAttributes, type Tracer } from '@opentelemetry/api';
|
|
1
|
+
import { trace, type Span, type SpanAttributes, type SpanContext, type Tracer } from '@opentelemetry/api';
|
|
2
2
|
import type { BaseEvent } from './base_event.js';
|
|
3
3
|
import type { EventBus } from './event_bus.js';
|
|
4
4
|
import type { EventResult } from './event_result.js';
|
|
5
5
|
import type { EventBusMiddleware } from './middlewares.js';
|
|
6
6
|
import type { EventStatus } from './types.js';
|
|
7
7
|
type OpenTelemetryTraceApi = Pick<typeof trace, 'getTracer' | 'setSpan'>;
|
|
8
|
+
export type OtelTracingSpanFactoryInput = {
|
|
9
|
+
name: string;
|
|
10
|
+
span_context: SpanContext;
|
|
11
|
+
parent_span_context?: SpanContext;
|
|
12
|
+
attributes: SpanAttributes;
|
|
13
|
+
start_time?: Date;
|
|
14
|
+
};
|
|
15
|
+
export type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span;
|
|
8
16
|
export type OtelTracingMiddlewareOptions = {
|
|
9
17
|
tracer?: Tracer;
|
|
10
18
|
trace_api?: OpenTelemetryTraceApi;
|
|
19
|
+
span_factory?: OtelTracingSpanFactory;
|
|
11
20
|
root_span_name?: string | ((eventbus: EventBus, event: BaseEvent) => string);
|
|
12
21
|
root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes);
|
|
13
22
|
};
|
|
14
23
|
export declare class OtelTracingMiddleware implements EventBusMiddleware {
|
|
15
24
|
private readonly tracer;
|
|
16
25
|
private readonly trace_api;
|
|
26
|
+
private readonly span_factory?;
|
|
17
27
|
private readonly root_span_name;
|
|
18
28
|
private readonly root_span_attributes;
|
|
19
29
|
private readonly root_spans;
|
|
@@ -32,5 +42,7 @@ export declare class OtelTracingMiddleware implements EventBusMiddleware {
|
|
|
32
42
|
private startRootSpan;
|
|
33
43
|
private completeRootSpan;
|
|
34
44
|
private parentContextForEvent;
|
|
45
|
+
private completeEventSpanWithFactory;
|
|
46
|
+
private completeHandlerSpanWithFactory;
|
|
35
47
|
}
|
|
36
48
|
export {};
|
|
@@ -25,6 +25,7 @@ var import_api = require("@opentelemetry/api");
|
|
|
25
25
|
class OtelTracingMiddleware {
|
|
26
26
|
tracer;
|
|
27
27
|
trace_api;
|
|
28
|
+
span_factory;
|
|
28
29
|
root_span_name;
|
|
29
30
|
root_span_attributes;
|
|
30
31
|
root_spans = /* @__PURE__ */ new Map();
|
|
@@ -36,11 +37,15 @@ class OtelTracingMiddleware {
|
|
|
36
37
|
constructor(options = {}) {
|
|
37
38
|
this.trace_api = options.trace_api ?? import_api.trace;
|
|
38
39
|
this.tracer = options.tracer ?? this.trace_api.getTracer("abxbus");
|
|
40
|
+
this.span_factory = options.span_factory;
|
|
39
41
|
this.root_span_name = options.root_span_name;
|
|
40
42
|
this.root_span_attributes = options.root_span_attributes;
|
|
41
43
|
}
|
|
42
44
|
onEventChange(eventbus, event, status) {
|
|
43
45
|
if (status === "started") {
|
|
46
|
+
if (this.span_factory) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
44
49
|
this.startEventSpan(eventbus, event);
|
|
45
50
|
return;
|
|
46
51
|
}
|
|
@@ -50,11 +55,14 @@ class OtelTracingMiddleware {
|
|
|
50
55
|
}
|
|
51
56
|
onEventResultChange(eventbus, event, event_result, status) {
|
|
52
57
|
if (status === "started") {
|
|
58
|
+
if (this.span_factory) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
53
61
|
this.startHandlerSpan(eventbus, event, event_result);
|
|
54
62
|
return;
|
|
55
63
|
}
|
|
56
64
|
if (status === "completed") {
|
|
57
|
-
this.completeHandlerSpan(event_result);
|
|
65
|
+
this.completeHandlerSpan(eventbus, event, event_result);
|
|
58
66
|
}
|
|
59
67
|
}
|
|
60
68
|
startEventSpan(eventbus, event) {
|
|
@@ -88,6 +96,10 @@ class OtelTracingMiddleware {
|
|
|
88
96
|
return span;
|
|
89
97
|
}
|
|
90
98
|
completeEventSpan(eventbus, event) {
|
|
99
|
+
if (this.span_factory) {
|
|
100
|
+
this.completeEventSpanWithFactory(eventbus, event);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
91
103
|
const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event);
|
|
92
104
|
if (event.event_errors.length > 0) {
|
|
93
105
|
recordSpanError(span, event.event_errors[0]);
|
|
@@ -138,7 +150,11 @@ class OtelTracingMiddleware {
|
|
|
138
150
|
this.handler_contexts.set(handlerSpanKey(event_result.event_id, event_result.handler_id), span_context);
|
|
139
151
|
return span;
|
|
140
152
|
}
|
|
141
|
-
completeHandlerSpan(event_result) {
|
|
153
|
+
completeHandlerSpan(eventbus, event, event_result) {
|
|
154
|
+
if (this.span_factory) {
|
|
155
|
+
this.completeHandlerSpanWithFactory(eventbus, event, event_result);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
142
158
|
const span = this.handler_spans.get(event_result.id);
|
|
143
159
|
if (!span) {
|
|
144
160
|
return;
|
|
@@ -205,10 +221,167 @@ class OtelTracingMiddleware {
|
|
|
205
221
|
}
|
|
206
222
|
return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : void 0;
|
|
207
223
|
}
|
|
224
|
+
completeEventSpanWithFactory(eventbus, event) {
|
|
225
|
+
const root_event = rootEventForEvent(eventbus, event);
|
|
226
|
+
const trace_id = traceIdForRootEvent(root_event.event_id);
|
|
227
|
+
const event_context = eventSpanContext(trace_id, event.event_id);
|
|
228
|
+
const start_time = dateFromIso(event.event_started_at);
|
|
229
|
+
const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at));
|
|
230
|
+
if (!event.event_parent_id) {
|
|
231
|
+
const root_span = this.span_factory({
|
|
232
|
+
name: resolveRootSpanName(this.root_span_name, eventbus, event),
|
|
233
|
+
span_context: rootSpanContext(trace_id, event.event_id),
|
|
234
|
+
attributes: rootSpanAttributes(this.root_span_attributes, eventbus, event),
|
|
235
|
+
start_time
|
|
236
|
+
});
|
|
237
|
+
root_span.setStatus({ code: import_api.SpanStatusCode.OK });
|
|
238
|
+
root_span.end(end_time);
|
|
239
|
+
}
|
|
240
|
+
const span = this.span_factory({
|
|
241
|
+
name: `abxbus.event ${event.event_type}`,
|
|
242
|
+
span_context: event_context,
|
|
243
|
+
parent_span_context: parentSpanContextForEvent(event, trace_id),
|
|
244
|
+
attributes: eventSpanAttributes(eventbus, event),
|
|
245
|
+
start_time
|
|
246
|
+
});
|
|
247
|
+
if (event.event_errors.length > 0) {
|
|
248
|
+
recordSpanError(span, event.event_errors[0]);
|
|
249
|
+
} else {
|
|
250
|
+
span.setStatus({ code: import_api.SpanStatusCode.OK });
|
|
251
|
+
}
|
|
252
|
+
span.end(end_time);
|
|
253
|
+
}
|
|
254
|
+
completeHandlerSpanWithFactory(eventbus, event, event_result) {
|
|
255
|
+
const root_event = rootEventForEvent(eventbus, event);
|
|
256
|
+
const trace_id = traceIdForRootEvent(root_event.event_id);
|
|
257
|
+
const start_time = dateFromIso(event_result.started_at);
|
|
258
|
+
const span = this.span_factory({
|
|
259
|
+
name: `abxbus.handler ${event.event_type} ${event_result.handler_name}`,
|
|
260
|
+
span_context: handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id),
|
|
261
|
+
parent_span_context: eventSpanContext(trace_id, event.event_id),
|
|
262
|
+
attributes: handlerSpanAttributes(eventbus, event, event_result),
|
|
263
|
+
start_time
|
|
264
|
+
});
|
|
265
|
+
if (event_result.error !== void 0) {
|
|
266
|
+
recordSpanError(span, event_result.error);
|
|
267
|
+
} else {
|
|
268
|
+
span.setStatus({ code: import_api.SpanStatusCode.OK });
|
|
269
|
+
}
|
|
270
|
+
span.end(endTimeAfterStart(start_time, dateFromIso(event_result.completed_at)));
|
|
271
|
+
}
|
|
208
272
|
}
|
|
209
273
|
function handlerSpanKey(event_id, handler_id) {
|
|
210
274
|
return `${event_id}:${handler_id}`;
|
|
211
275
|
}
|
|
276
|
+
function eventSpanAttributes(eventbus, event) {
|
|
277
|
+
return compactAttributes({
|
|
278
|
+
"abxbus.bus.id": eventbus.id,
|
|
279
|
+
"abxbus.bus.name": eventbus.name,
|
|
280
|
+
"abxbus.event.id": event.event_id,
|
|
281
|
+
"abxbus.event.type": event.event_type,
|
|
282
|
+
"abxbus.event.version": event.event_version,
|
|
283
|
+
"abxbus.event.session_id": stringValue(event.session_id),
|
|
284
|
+
"abxbus.event.parent_id": event.event_parent_id,
|
|
285
|
+
"abxbus.event.emitted_by_handler_id": event.event_emitted_by_handler_id,
|
|
286
|
+
"abxbus.event.path": event.event_path.join(" "),
|
|
287
|
+
"abxbus.event.status": event.event_status,
|
|
288
|
+
"abxbus.event.result_count": event.event_results.size,
|
|
289
|
+
"abxbus.event.error_count": event.event_errors.length,
|
|
290
|
+
"abxbus.event.child_count": event.event_children.length
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
function handlerSpanAttributes(eventbus, event, event_result) {
|
|
294
|
+
return compactAttributes({
|
|
295
|
+
"abxbus.bus.id": eventbus.id,
|
|
296
|
+
"abxbus.bus.name": eventbus.name,
|
|
297
|
+
"abxbus.event.id": event.event_id,
|
|
298
|
+
"abxbus.event.type": event.event_type,
|
|
299
|
+
"abxbus.handler.id": event_result.handler_id,
|
|
300
|
+
"abxbus.handler.name": event_result.handler_name,
|
|
301
|
+
"abxbus.handler.file_path": event_result.handler_file_path,
|
|
302
|
+
"abxbus.handler.event_pattern": event_result.handler.event_pattern,
|
|
303
|
+
"abxbus.event_result.id": event_result.id,
|
|
304
|
+
"abxbus.event_result.status": event_result.status,
|
|
305
|
+
"abxbus.handler.child_count": event_result.event_children.length
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function rootSpanAttributes(root_span_attributes, eventbus, event) {
|
|
309
|
+
const session_id = stringValue(event.session_id);
|
|
310
|
+
return compactAttributes({
|
|
311
|
+
...resolveAttributes(root_span_attributes, eventbus, event),
|
|
312
|
+
"abxbus.trace.root": true,
|
|
313
|
+
"abxbus.bus.id": eventbus.id,
|
|
314
|
+
"abxbus.bus.name": eventbus.name,
|
|
315
|
+
"abxbus.root_event.id": event.event_id,
|
|
316
|
+
"abxbus.root_event.type": event.event_type,
|
|
317
|
+
"abxbus.root_event.session_id": session_id,
|
|
318
|
+
"abxbus.root_event.status": event.event_status,
|
|
319
|
+
"abxbus.root_event.error_count": event.event_errors.length,
|
|
320
|
+
"abxbus.root_event.child_count": event.event_children.length
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
function rootEventForEvent(eventbus, event) {
|
|
324
|
+
let current = event._event_original ?? event;
|
|
325
|
+
const seen = /* @__PURE__ */ new Set();
|
|
326
|
+
while (current.event_parent_id && !seen.has(current.event_id)) {
|
|
327
|
+
seen.add(current.event_id);
|
|
328
|
+
const parent = eventbus.findEventById(current.event_parent_id);
|
|
329
|
+
if (!parent) {
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
current = parent._event_original ?? parent;
|
|
333
|
+
}
|
|
334
|
+
return current;
|
|
335
|
+
}
|
|
336
|
+
function parentSpanContextForEvent(event, trace_id) {
|
|
337
|
+
if (!event.event_parent_id) {
|
|
338
|
+
return rootSpanContext(trace_id, event.event_id);
|
|
339
|
+
}
|
|
340
|
+
if (event.event_emitted_by_handler_id) {
|
|
341
|
+
return handlerSpanContext(trace_id, event.event_parent_id, event.event_emitted_by_handler_id);
|
|
342
|
+
}
|
|
343
|
+
return eventSpanContext(trace_id, event.event_parent_id);
|
|
344
|
+
}
|
|
345
|
+
function rootSpanContext(trace_id, event_id) {
|
|
346
|
+
return {
|
|
347
|
+
traceId: trace_id,
|
|
348
|
+
spanId: deterministicSpanId(`abxbus.root:${event_id}`),
|
|
349
|
+
traceFlags: 1
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function eventSpanContext(trace_id, event_id) {
|
|
353
|
+
return {
|
|
354
|
+
traceId: trace_id,
|
|
355
|
+
spanId: deterministicSpanId(`abxbus.event:${event_id}`),
|
|
356
|
+
traceFlags: 1
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
function handlerSpanContext(trace_id, event_id, handler_id) {
|
|
360
|
+
return {
|
|
361
|
+
traceId: trace_id,
|
|
362
|
+
spanId: deterministicSpanId(`abxbus.handler:${event_id}:${handler_id}`),
|
|
363
|
+
traceFlags: 1
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function traceIdForRootEvent(event_id) {
|
|
367
|
+
return `${fnv1a64Hex(`abxbus.trace.a:${event_id}`)}${fnv1a64Hex(`abxbus.trace.b:${event_id}`)}`;
|
|
368
|
+
}
|
|
369
|
+
function deterministicSpanId(input) {
|
|
370
|
+
return fnv1a64Hex(input);
|
|
371
|
+
}
|
|
372
|
+
function fnv1a64Hex(input) {
|
|
373
|
+
let hash = 0xcbf29ce484222325n;
|
|
374
|
+
const prime = 0x100000001b3n;
|
|
375
|
+
const mask = 0xffffffffffffffffn;
|
|
376
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
377
|
+
hash ^= BigInt(input.charCodeAt(index));
|
|
378
|
+
hash = hash * prime & mask;
|
|
379
|
+
}
|
|
380
|
+
if (hash === 0n) {
|
|
381
|
+
hash = 1n;
|
|
382
|
+
}
|
|
383
|
+
return hash.toString(16).padStart(16, "0");
|
|
384
|
+
}
|
|
212
385
|
function dateFromIso(value) {
|
|
213
386
|
if (value == null) {
|
|
214
387
|
return void 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/middleware_otel_tracing.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n ROOT_CONTEXT,\n SpanStatusCode,\n trace,\n type Context,\n type Span,\n type SpanAttributeValue,\n type SpanAttributes,\n type Tracer,\n} from '@opentelemetry/api'\n\nimport type { BaseEvent } from './base_event.js'\nimport type { EventBus } from './event_bus.js'\nimport type { EventResult } from './event_result.js'\nimport type { EventBusMiddleware } from './middlewares.js'\nimport type { EventStatus } from './types.js'\n\ntype OpenTelemetryTraceApi = Pick<typeof trace, 'getTracer' | 'setSpan'>\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n root_span_name?: string | ((eventbus: EventBus, event: BaseEvent) => string)\n root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes)\n}\n\nexport class OtelTracingMiddleware implements EventBusMiddleware {\n private readonly tracer: Tracer\n private readonly trace_api: OpenTelemetryTraceApi\n private readonly root_span_name: OtelTracingMiddlewareOptions['root_span_name']\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\n private readonly root_spans = new Map<string, Span>()\n private readonly root_contexts = new Map<string, Context>()\n private readonly event_spans = new Map<string, Span>()\n private readonly event_contexts = new Map<string, Context>()\n private readonly handler_spans = new Map<string, Span>()\n private readonly handler_contexts = new Map<string, Context>()\n\n constructor(options: OtelTracingMiddlewareOptions = {}) {\n this.trace_api = options.trace_api ?? trace\n this.tracer = options.tracer ?? this.trace_api.getTracer('abxbus')\n this.root_span_name = options.root_span_name\n this.root_span_attributes = options.root_span_attributes\n }\n\n onEventChange(eventbus: EventBus, event: BaseEvent, status: EventStatus): void {\n if (status === 'started') {\n this.startEventSpan(eventbus, event)\n return\n }\n\n if (status === 'completed') {\n this.completeEventSpan(eventbus, event)\n }\n }\n\n onEventResultChange(eventbus: EventBus, event: BaseEvent, event_result: EventResult, status: EventStatus): void {\n if (status === 'started') {\n this.startHandlerSpan(eventbus, event, event_result)\n return\n }\n\n if (status === 'completed') {\n this.completeHandlerSpan(event_result)\n }\n }\n\n private startEventSpan(eventbus: EventBus, event: BaseEvent): Span {\n const existing = this.event_spans.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const parent_context = this.parentContextForEvent(event) ?? this.startRootSpan(eventbus, event)\n const start_time = dateFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n `abxbus.event ${event.event_type}`,\n {\n attributes: compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.event.version': event.event_version,\n 'abxbus.event.session_id': stringValue((event as { session_id?: unknown }).session_id),\n 'abxbus.event.parent_id': event.event_parent_id,\n 'abxbus.event.emitted_by_handler_id': event.event_emitted_by_handler_id,\n 'abxbus.event.path': event.event_path.join(' '),\n }),\n startTime: start_time,\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.event_spans.set(event.event_id, span)\n this.event_contexts.set(event.event_id, span_context)\n return span\n }\n\n private completeEventSpan(eventbus: EventBus, event: BaseEvent): void {\n const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event)\n if (event.event_errors.length > 0) {\n recordSpanError(span, event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n compactAttributes({\n 'abxbus.event.status': event.event_status,\n 'abxbus.event.result_count': event.event_results.size,\n 'abxbus.event.error_count': event.event_errors.length,\n 'abxbus.event.child_count': event.event_children.length,\n })\n )\n const start_time = dateFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at))\n span.end(end_time)\n this.event_spans.delete(event.event_id)\n this.event_contexts.delete(event.event_id)\n this.completeRootSpan(event.event_id, start_time, end_time)\n }\n\n private startHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): Span {\n const existing = this.handler_spans.get(event_result.id)\n if (existing) {\n return existing\n }\n\n const parent_context =\n this.event_contexts.get(event.event_id) ?? this.trace_api.setSpan(ROOT_CONTEXT, this.startEventSpan(eventbus, event))\n const span = this.tracer.startSpan(\n `abxbus.handler ${event.event_type} ${event_result.handler_name}`,\n {\n attributes: compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.handler.id': event_result.handler_id,\n 'abxbus.handler.name': event_result.handler_name,\n 'abxbus.handler.file_path': event_result.handler_file_path,\n 'abxbus.handler.event_pattern': event_result.handler.event_pattern,\n 'abxbus.event_result.id': event_result.id,\n }),\n startTime: dateFromIso(event_result.started_at),\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.handler_spans.set(event_result.id, span)\n this.handler_contexts.set(handlerSpanKey(event_result.event_id, event_result.handler_id), span_context)\n return span\n }\n\n private completeHandlerSpan(event_result: EventResult): void {\n const span = this.handler_spans.get(event_result.id)\n if (!span) {\n return\n }\n\n if (event_result.error !== undefined) {\n recordSpanError(span, event_result.error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n compactAttributes({\n 'abxbus.event_result.status': event_result.status,\n 'abxbus.handler.child_count': event_result.event_children.length,\n })\n )\n span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)))\n this.handler_spans.delete(event_result.id)\n this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id))\n }\n\n private startRootSpan(eventbus: EventBus, event: BaseEvent): Context {\n const existing = this.root_contexts.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const session_id = stringValue((event as { session_id?: unknown }).session_id)\n const root_attributes = resolveAttributes(this.root_span_attributes, eventbus, event)\n const root_span = this.tracer.startSpan(\n resolveRootSpanName(this.root_span_name, eventbus, event),\n {\n attributes: compactAttributes({\n ...root_attributes,\n 'abxbus.trace.root': true,\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.root_event.id': event.event_id,\n 'abxbus.root_event.type': event.event_type,\n 'abxbus.root_event.session_id': session_id,\n }),\n startTime: dateFromIso(event.event_started_at),\n },\n ROOT_CONTEXT\n )\n const root_context = this.trace_api.setSpan(ROOT_CONTEXT, root_span)\n this.root_spans.set(event.event_id, root_span)\n this.root_contexts.set(event.event_id, root_context)\n return root_context\n }\n\n private completeRootSpan(event_id: string, start_time: Date | undefined, end_time: Date | undefined): void {\n const root_span = this.root_spans.get(event_id)\n if (!root_span) {\n return\n }\n\n root_span.setStatus({ code: SpanStatusCode.OK })\n root_span.end(endTimeAfterStart(start_time, end_time))\n this.root_spans.delete(event_id)\n this.root_contexts.delete(event_id)\n }\n\n private parentContextForEvent(event: BaseEvent): Context | undefined {\n if (event.event_parent_id && event.event_emitted_by_handler_id) {\n const handler_context = this.handler_contexts.get(handlerSpanKey(event.event_parent_id, event.event_emitted_by_handler_id))\n if (handler_context) {\n return handler_context\n }\n }\n\n return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : undefined\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction dateFromIso(value: string | null | undefined): Date | undefined {\n if (value == null) {\n return undefined\n }\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? undefined : date\n}\n\nfunction endTimeAfterStart(start_time: Date | undefined, end_time: Date | undefined): Date | undefined {\n if (!start_time || !end_time) {\n return end_time\n }\n\n return end_time.getTime() > start_time.getTime() ? end_time : new Date(start_time.getTime() + 1)\n}\n\nfunction resolveRootSpanName(\n root_span_name: OtelTracingMiddlewareOptions['root_span_name'],\n eventbus: EventBus,\n event: BaseEvent\n): string {\n if (typeof root_span_name === 'function') {\n return root_span_name(eventbus, event)\n }\n return root_span_name ?? `abxbus.trace ${eventbus.name}`\n}\n\nfunction resolveAttributes(\n attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return typeof attributes === 'function' ? attributes(eventbus, event) : (attributes ?? {})\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction compactAttributes(attributes: Record<string, SpanAttributeValue | null | undefined>): SpanAttributes {\n const compacted: SpanAttributes = {}\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== null && value !== undefined) {\n compacted[key] = value\n }\n }\n return compacted\n}\n\nfunction recordSpanError(span: Span, error: unknown): void {\n if (error instanceof Error) {\n span.recordException(error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n return\n }\n\n const message = typeof error === 'string' ? error : 'Unknown abxbus handler error'\n span.recordException(message)\n span.setStatus({ code: SpanStatusCode.ERROR, message })\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n ROOT_CONTEXT,\n SpanStatusCode,\n trace,\n type Context,\n type Span,\n type SpanAttributeValue,\n type SpanAttributes,\n type SpanContext,\n type Tracer,\n} from '@opentelemetry/api'\n\nimport type { BaseEvent } from './base_event.js'\nimport type { EventBus } from './event_bus.js'\nimport type { EventResult } from './event_result.js'\nimport type { EventBusMiddleware } from './middlewares.js'\nimport type { EventStatus } from './types.js'\n\ntype OpenTelemetryTraceApi = Pick<typeof trace, 'getTracer' | 'setSpan'>\n\nexport type OtelTracingSpanFactoryInput = {\n name: string\n span_context: SpanContext\n parent_span_context?: SpanContext\n attributes: SpanAttributes\n start_time?: Date\n}\n\nexport type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n span_factory?: OtelTracingSpanFactory\n root_span_name?: string | ((eventbus: EventBus, event: BaseEvent) => string)\n root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes)\n}\n\nexport class OtelTracingMiddleware implements EventBusMiddleware {\n private readonly tracer: Tracer\n private readonly trace_api: OpenTelemetryTraceApi\n private readonly span_factory?: OtelTracingSpanFactory\n private readonly root_span_name: OtelTracingMiddlewareOptions['root_span_name']\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\n private readonly root_spans = new Map<string, Span>()\n private readonly root_contexts = new Map<string, Context>()\n private readonly event_spans = new Map<string, Span>()\n private readonly event_contexts = new Map<string, Context>()\n private readonly handler_spans = new Map<string, Span>()\n private readonly handler_contexts = new Map<string, Context>()\n\n constructor(options: OtelTracingMiddlewareOptions = {}) {\n this.trace_api = options.trace_api ?? trace\n this.tracer = options.tracer ?? this.trace_api.getTracer('abxbus')\n this.span_factory = options.span_factory\n this.root_span_name = options.root_span_name\n this.root_span_attributes = options.root_span_attributes\n }\n\n onEventChange(eventbus: EventBus, event: BaseEvent, status: EventStatus): void {\n if (status === 'started') {\n if (this.span_factory) {\n return\n }\n this.startEventSpan(eventbus, event)\n return\n }\n\n if (status === 'completed') {\n this.completeEventSpan(eventbus, event)\n }\n }\n\n onEventResultChange(eventbus: EventBus, event: BaseEvent, event_result: EventResult, status: EventStatus): void {\n if (status === 'started') {\n if (this.span_factory) {\n return\n }\n this.startHandlerSpan(eventbus, event, event_result)\n return\n }\n\n if (status === 'completed') {\n this.completeHandlerSpan(eventbus, event, event_result)\n }\n }\n\n private startEventSpan(eventbus: EventBus, event: BaseEvent): Span {\n const existing = this.event_spans.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const parent_context = this.parentContextForEvent(event) ?? this.startRootSpan(eventbus, event)\n const start_time = dateFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n `abxbus.event ${event.event_type}`,\n {\n attributes: compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.event.version': event.event_version,\n 'abxbus.event.session_id': stringValue((event as { session_id?: unknown }).session_id),\n 'abxbus.event.parent_id': event.event_parent_id,\n 'abxbus.event.emitted_by_handler_id': event.event_emitted_by_handler_id,\n 'abxbus.event.path': event.event_path.join(' '),\n }),\n startTime: start_time,\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.event_spans.set(event.event_id, span)\n this.event_contexts.set(event.event_id, span_context)\n return span\n }\n\n private completeEventSpan(eventbus: EventBus, event: BaseEvent): void {\n if (this.span_factory) {\n this.completeEventSpanWithFactory(eventbus, event)\n return\n }\n\n const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event)\n if (event.event_errors.length > 0) {\n recordSpanError(span, event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n compactAttributes({\n 'abxbus.event.status': event.event_status,\n 'abxbus.event.result_count': event.event_results.size,\n 'abxbus.event.error_count': event.event_errors.length,\n 'abxbus.event.child_count': event.event_children.length,\n })\n )\n const start_time = dateFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at))\n span.end(end_time)\n this.event_spans.delete(event.event_id)\n this.event_contexts.delete(event.event_id)\n this.completeRootSpan(event.event_id, start_time, end_time)\n }\n\n private startHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): Span {\n const existing = this.handler_spans.get(event_result.id)\n if (existing) {\n return existing\n }\n\n const parent_context =\n this.event_contexts.get(event.event_id) ?? this.trace_api.setSpan(ROOT_CONTEXT, this.startEventSpan(eventbus, event))\n const span = this.tracer.startSpan(\n `abxbus.handler ${event.event_type} ${event_result.handler_name}`,\n {\n attributes: compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.handler.id': event_result.handler_id,\n 'abxbus.handler.name': event_result.handler_name,\n 'abxbus.handler.file_path': event_result.handler_file_path,\n 'abxbus.handler.event_pattern': event_result.handler.event_pattern,\n 'abxbus.event_result.id': event_result.id,\n }),\n startTime: dateFromIso(event_result.started_at),\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.handler_spans.set(event_result.id, span)\n this.handler_contexts.set(handlerSpanKey(event_result.event_id, event_result.handler_id), span_context)\n return span\n }\n\n private completeHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): void {\n if (this.span_factory) {\n this.completeHandlerSpanWithFactory(eventbus, event, event_result)\n return\n }\n\n const span = this.handler_spans.get(event_result.id)\n if (!span) {\n return\n }\n\n if (event_result.error !== undefined) {\n recordSpanError(span, event_result.error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n compactAttributes({\n 'abxbus.event_result.status': event_result.status,\n 'abxbus.handler.child_count': event_result.event_children.length,\n })\n )\n span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)))\n this.handler_spans.delete(event_result.id)\n this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id))\n }\n\n private startRootSpan(eventbus: EventBus, event: BaseEvent): Context {\n const existing = this.root_contexts.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const session_id = stringValue((event as { session_id?: unknown }).session_id)\n const root_attributes = resolveAttributes(this.root_span_attributes, eventbus, event)\n const root_span = this.tracer.startSpan(\n resolveRootSpanName(this.root_span_name, eventbus, event),\n {\n attributes: compactAttributes({\n ...root_attributes,\n 'abxbus.trace.root': true,\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.root_event.id': event.event_id,\n 'abxbus.root_event.type': event.event_type,\n 'abxbus.root_event.session_id': session_id,\n }),\n startTime: dateFromIso(event.event_started_at),\n },\n ROOT_CONTEXT\n )\n const root_context = this.trace_api.setSpan(ROOT_CONTEXT, root_span)\n this.root_spans.set(event.event_id, root_span)\n this.root_contexts.set(event.event_id, root_context)\n return root_context\n }\n\n private completeRootSpan(event_id: string, start_time: Date | undefined, end_time: Date | undefined): void {\n const root_span = this.root_spans.get(event_id)\n if (!root_span) {\n return\n }\n\n root_span.setStatus({ code: SpanStatusCode.OK })\n root_span.end(endTimeAfterStart(start_time, end_time))\n this.root_spans.delete(event_id)\n this.root_contexts.delete(event_id)\n }\n\n private parentContextForEvent(event: BaseEvent): Context | undefined {\n if (event.event_parent_id && event.event_emitted_by_handler_id) {\n const handler_context = this.handler_contexts.get(handlerSpanKey(event.event_parent_id, event.event_emitted_by_handler_id))\n if (handler_context) {\n return handler_context\n }\n }\n\n return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : undefined\n }\n\n private completeEventSpanWithFactory(eventbus: EventBus, event: BaseEvent): void {\n const root_event = rootEventForEvent(eventbus, event)\n const trace_id = traceIdForRootEvent(root_event.event_id)\n const event_context = eventSpanContext(trace_id, event.event_id)\n const start_time = dateFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at))\n\n if (!event.event_parent_id) {\n const root_span = this.span_factory!({\n name: resolveRootSpanName(this.root_span_name, eventbus, event),\n span_context: rootSpanContext(trace_id, event.event_id),\n attributes: rootSpanAttributes(this.root_span_attributes, eventbus, event),\n start_time,\n })\n root_span.setStatus({ code: SpanStatusCode.OK })\n root_span.end(end_time)\n }\n\n const span = this.span_factory!({\n name: `abxbus.event ${event.event_type}`,\n span_context: event_context,\n parent_span_context: parentSpanContextForEvent(event, trace_id),\n attributes: eventSpanAttributes(eventbus, event),\n start_time,\n })\n if (event.event_errors.length > 0) {\n recordSpanError(span, event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(end_time)\n }\n\n private completeHandlerSpanWithFactory(eventbus: EventBus, event: BaseEvent, event_result: EventResult): void {\n const root_event = rootEventForEvent(eventbus, event)\n const trace_id = traceIdForRootEvent(root_event.event_id)\n const start_time = dateFromIso(event_result.started_at)\n const span = this.span_factory!({\n name: `abxbus.handler ${event.event_type} ${event_result.handler_name}`,\n span_context: handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id),\n parent_span_context: eventSpanContext(trace_id, event.event_id),\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n start_time,\n })\n\n if (event_result.error !== undefined) {\n recordSpanError(span, event_result.error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(endTimeAfterStart(start_time, dateFromIso(event_result.completed_at)))\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction eventSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.event.version': event.event_version,\n 'abxbus.event.session_id': stringValue((event as { session_id?: unknown }).session_id),\n 'abxbus.event.parent_id': event.event_parent_id,\n 'abxbus.event.emitted_by_handler_id': event.event_emitted_by_handler_id,\n 'abxbus.event.path': event.event_path.join(' '),\n 'abxbus.event.status': event.event_status,\n 'abxbus.event.result_count': event.event_results.size,\n 'abxbus.event.error_count': event.event_errors.length,\n 'abxbus.event.child_count': event.event_children.length,\n })\n}\n\nfunction handlerSpanAttributes(eventbus: EventBus, event: BaseEvent, event_result: EventResult): SpanAttributes {\n return compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.handler.id': event_result.handler_id,\n 'abxbus.handler.name': event_result.handler_name,\n 'abxbus.handler.file_path': event_result.handler_file_path,\n 'abxbus.handler.event_pattern': event_result.handler.event_pattern,\n 'abxbus.event_result.id': event_result.id,\n 'abxbus.event_result.status': event_result.status,\n 'abxbus.handler.child_count': event_result.event_children.length,\n })\n}\n\nfunction rootSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n const session_id = stringValue((event as { session_id?: unknown }).session_id)\n return compactAttributes({\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.root_event.id': event.event_id,\n 'abxbus.root_event.type': event.event_type,\n 'abxbus.root_event.session_id': session_id,\n 'abxbus.root_event.status': event.event_status,\n 'abxbus.root_event.error_count': event.event_errors.length,\n 'abxbus.root_event.child_count': event.event_children.length,\n })\n}\n\nfunction rootEventForEvent(eventbus: EventBus, event: BaseEvent): BaseEvent {\n let current = event._event_original ?? event\n const seen = new Set<string>()\n while (current.event_parent_id && !seen.has(current.event_id)) {\n seen.add(current.event_id)\n const parent = eventbus.findEventById(current.event_parent_id)\n if (!parent) {\n break\n }\n current = parent._event_original ?? parent\n }\n return current\n}\n\nfunction parentSpanContextForEvent(event: BaseEvent, trace_id: string): SpanContext {\n if (!event.event_parent_id) {\n return rootSpanContext(trace_id, event.event_id)\n }\n\n if (event.event_emitted_by_handler_id) {\n return handlerSpanContext(trace_id, event.event_parent_id, event.event_emitted_by_handler_id)\n }\n\n return eventSpanContext(trace_id, event.event_parent_id)\n}\n\nfunction rootSpanContext(trace_id: string, event_id: string): SpanContext {\n return {\n traceId: trace_id,\n spanId: deterministicSpanId(`abxbus.root:${event_id}`),\n traceFlags: 1,\n }\n}\n\nfunction eventSpanContext(trace_id: string, event_id: string): SpanContext {\n return {\n traceId: trace_id,\n spanId: deterministicSpanId(`abxbus.event:${event_id}`),\n traceFlags: 1,\n }\n}\n\nfunction handlerSpanContext(trace_id: string, event_id: string, handler_id: string): SpanContext {\n return {\n traceId: trace_id,\n spanId: deterministicSpanId(`abxbus.handler:${event_id}:${handler_id}`),\n traceFlags: 1,\n }\n}\n\nfunction traceIdForRootEvent(event_id: string): string {\n return `${fnv1a64Hex(`abxbus.trace.a:${event_id}`)}${fnv1a64Hex(`abxbus.trace.b:${event_id}`)}`\n}\n\nfunction deterministicSpanId(input: string): string {\n return fnv1a64Hex(input)\n}\n\nfunction fnv1a64Hex(input: string): string {\n let hash = 0xcbf29ce484222325n\n const prime = 0x100000001b3n\n const mask = 0xffffffffffffffffn\n for (let index = 0; index < input.length; index += 1) {\n hash ^= BigInt(input.charCodeAt(index))\n hash = (hash * prime) & mask\n }\n if (hash === 0n) {\n hash = 1n\n }\n return hash.toString(16).padStart(16, '0')\n}\n\nfunction dateFromIso(value: string | null | undefined): Date | undefined {\n if (value == null) {\n return undefined\n }\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? undefined : date\n}\n\nfunction endTimeAfterStart(start_time: Date | undefined, end_time: Date | undefined): Date | undefined {\n if (!start_time || !end_time) {\n return end_time\n }\n\n return end_time.getTime() > start_time.getTime() ? end_time : new Date(start_time.getTime() + 1)\n}\n\nfunction resolveRootSpanName(root_span_name: OtelTracingMiddlewareOptions['root_span_name'], eventbus: EventBus, event: BaseEvent): string {\n if (typeof root_span_name === 'function') {\n return root_span_name(eventbus, event)\n }\n return root_span_name ?? `abxbus.trace ${eventbus.name}`\n}\n\nfunction resolveAttributes(\n attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return typeof attributes === 'function' ? attributes(eventbus, event) : (attributes ?? {})\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction compactAttributes(attributes: Record<string, SpanAttributeValue | null | undefined>): SpanAttributes {\n const compacted: SpanAttributes = {}\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== null && value !== undefined) {\n compacted[key] = value\n }\n }\n return compacted\n}\n\nfunction recordSpanError(span: Span, error: unknown): void {\n if (error instanceof Error) {\n span.recordException(error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n return\n }\n\n const message = typeof error === 'string' ? error : 'Unknown abxbus handler error'\n span.recordException(message)\n span.setStatus({ code: SpanStatusCode.ERROR, message })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export { BaseEvent, BaseEventSchema } from './base_event.js'\nexport { EventHistory } from './event_history.js'\nexport type { EventHistoryFindOptions, EventHistoryTrimOptions } from './event_history.js'\nexport { EventResult } from './event_result.js'\nexport { EventBus } from './event_bus.js'\nexport type { EventBusJSON, EventBusOptions } from './event_bus.js'\nexport { monotonicDatetime } from './helpers.js'\nexport type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './middlewares.js'\nexport { OtelTracingMiddleware } from './middleware_otel_tracing.js'\nexport type { OtelTracingMiddlewareOptions } from './middleware_otel_tracing.js'\nexport {\n EventHandlerTimeoutError,\n EventHandlerCancelledError,\n EventHandlerAbortedError,\n EventHandlerResultSchemaError,\n} from './event_handler.js'\nexport type {\n EventConcurrencyMode,\n EventHandlerConcurrencyMode,\n EventHandlerCompletionMode,\n EventBusInterfaceForLockManager,\n} from './lock_manager.js'\nexport type { EventClass, EventHandlerCallable as EventHandler, EventPattern, EventStatus, FindOptions, FindWindow } from './types.js'\nexport { retry, clearSemaphoreRegistry, RetryTimeoutError, SemaphoreTimeoutError } from './retry.js'\nexport type { RetryOptions } from './retry.js'\nexport {\n HTTPEventBridge,\n SocketEventBridge,\n NATSEventBridge,\n RedisEventBridge,\n PostgresEventBridge,\n JSONLEventBridge,\n SQLiteEventBridge,\n} from './bridges.js'\nexport type { HTTPEventBridgeOptions } from './bridges.js'\nexport { events_suck } from './events_suck.js'\nexport type { EventsSuckClient, EventsSuckClientClass, GeneratedEvents } from './events_suck.js'\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,WAAW,uBAAuB;AAC3C,SAAS,oBAAoB;AAE7B,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AAEzB,SAAS,yBAAyB;AAElC,SAAS,6BAA6B;
|
|
4
|
+
"sourcesContent": ["export { BaseEvent, BaseEventSchema } from './base_event.js'\nexport { EventHistory } from './event_history.js'\nexport type { EventHistoryFindOptions, EventHistoryTrimOptions } from './event_history.js'\nexport { EventResult } from './event_result.js'\nexport { EventBus } from './event_bus.js'\nexport type { EventBusJSON, EventBusOptions } from './event_bus.js'\nexport { monotonicDatetime } from './helpers.js'\nexport type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './middlewares.js'\nexport { OtelTracingMiddleware } from './middleware_otel_tracing.js'\nexport type { OtelTracingMiddlewareOptions } from './middleware_otel_tracing.js'\nexport type { OtelTracingSpanFactory, OtelTracingSpanFactoryInput } from './middleware_otel_tracing.js'\nexport {\n EventHandlerTimeoutError,\n EventHandlerCancelledError,\n EventHandlerAbortedError,\n EventHandlerResultSchemaError,\n} from './event_handler.js'\nexport type {\n EventConcurrencyMode,\n EventHandlerConcurrencyMode,\n EventHandlerCompletionMode,\n EventBusInterfaceForLockManager,\n} from './lock_manager.js'\nexport type { EventClass, EventHandlerCallable as EventHandler, EventPattern, EventStatus, FindOptions, FindWindow } from './types.js'\nexport { retry, clearSemaphoreRegistry, RetryTimeoutError, SemaphoreTimeoutError } from './retry.js'\nexport type { RetryOptions } from './retry.js'\nexport {\n HTTPEventBridge,\n SocketEventBridge,\n NATSEventBridge,\n RedisEventBridge,\n PostgresEventBridge,\n JSONLEventBridge,\n SQLiteEventBridge,\n} from './bridges.js'\nexport type { HTTPEventBridgeOptions } from './bridges.js'\nexport { events_suck } from './events_suck.js'\nexport type { EventsSuckClient, EventsSuckClientClass, GeneratedEvents } from './events_suck.js'\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,WAAW,uBAAuB;AAC3C,SAAS,oBAAoB;AAE7B,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AAEzB,SAAS,yBAAyB;AAElC,SAAS,6BAA6B;AAGtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAQP,SAAS,OAAO,wBAAwB,mBAAmB,6BAA6B;AAExF;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,mBAAmB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
class OtelTracingMiddleware {
|
|
7
7
|
tracer;
|
|
8
8
|
trace_api;
|
|
9
|
+
span_factory;
|
|
9
10
|
root_span_name;
|
|
10
11
|
root_span_attributes;
|
|
11
12
|
root_spans = /* @__PURE__ */ new Map();
|
|
@@ -17,11 +18,15 @@ class OtelTracingMiddleware {
|
|
|
17
18
|
constructor(options = {}) {
|
|
18
19
|
this.trace_api = options.trace_api ?? trace;
|
|
19
20
|
this.tracer = options.tracer ?? this.trace_api.getTracer("abxbus");
|
|
21
|
+
this.span_factory = options.span_factory;
|
|
20
22
|
this.root_span_name = options.root_span_name;
|
|
21
23
|
this.root_span_attributes = options.root_span_attributes;
|
|
22
24
|
}
|
|
23
25
|
onEventChange(eventbus, event, status) {
|
|
24
26
|
if (status === "started") {
|
|
27
|
+
if (this.span_factory) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
25
30
|
this.startEventSpan(eventbus, event);
|
|
26
31
|
return;
|
|
27
32
|
}
|
|
@@ -31,11 +36,14 @@ class OtelTracingMiddleware {
|
|
|
31
36
|
}
|
|
32
37
|
onEventResultChange(eventbus, event, event_result, status) {
|
|
33
38
|
if (status === "started") {
|
|
39
|
+
if (this.span_factory) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
34
42
|
this.startHandlerSpan(eventbus, event, event_result);
|
|
35
43
|
return;
|
|
36
44
|
}
|
|
37
45
|
if (status === "completed") {
|
|
38
|
-
this.completeHandlerSpan(event_result);
|
|
46
|
+
this.completeHandlerSpan(eventbus, event, event_result);
|
|
39
47
|
}
|
|
40
48
|
}
|
|
41
49
|
startEventSpan(eventbus, event) {
|
|
@@ -69,6 +77,10 @@ class OtelTracingMiddleware {
|
|
|
69
77
|
return span;
|
|
70
78
|
}
|
|
71
79
|
completeEventSpan(eventbus, event) {
|
|
80
|
+
if (this.span_factory) {
|
|
81
|
+
this.completeEventSpanWithFactory(eventbus, event);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
72
84
|
const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event);
|
|
73
85
|
if (event.event_errors.length > 0) {
|
|
74
86
|
recordSpanError(span, event.event_errors[0]);
|
|
@@ -119,7 +131,11 @@ class OtelTracingMiddleware {
|
|
|
119
131
|
this.handler_contexts.set(handlerSpanKey(event_result.event_id, event_result.handler_id), span_context);
|
|
120
132
|
return span;
|
|
121
133
|
}
|
|
122
|
-
completeHandlerSpan(event_result) {
|
|
134
|
+
completeHandlerSpan(eventbus, event, event_result) {
|
|
135
|
+
if (this.span_factory) {
|
|
136
|
+
this.completeHandlerSpanWithFactory(eventbus, event, event_result);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
123
139
|
const span = this.handler_spans.get(event_result.id);
|
|
124
140
|
if (!span) {
|
|
125
141
|
return;
|
|
@@ -186,10 +202,167 @@ class OtelTracingMiddleware {
|
|
|
186
202
|
}
|
|
187
203
|
return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : void 0;
|
|
188
204
|
}
|
|
205
|
+
completeEventSpanWithFactory(eventbus, event) {
|
|
206
|
+
const root_event = rootEventForEvent(eventbus, event);
|
|
207
|
+
const trace_id = traceIdForRootEvent(root_event.event_id);
|
|
208
|
+
const event_context = eventSpanContext(trace_id, event.event_id);
|
|
209
|
+
const start_time = dateFromIso(event.event_started_at);
|
|
210
|
+
const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at));
|
|
211
|
+
if (!event.event_parent_id) {
|
|
212
|
+
const root_span = this.span_factory({
|
|
213
|
+
name: resolveRootSpanName(this.root_span_name, eventbus, event),
|
|
214
|
+
span_context: rootSpanContext(trace_id, event.event_id),
|
|
215
|
+
attributes: rootSpanAttributes(this.root_span_attributes, eventbus, event),
|
|
216
|
+
start_time
|
|
217
|
+
});
|
|
218
|
+
root_span.setStatus({ code: SpanStatusCode.OK });
|
|
219
|
+
root_span.end(end_time);
|
|
220
|
+
}
|
|
221
|
+
const span = this.span_factory({
|
|
222
|
+
name: `abxbus.event ${event.event_type}`,
|
|
223
|
+
span_context: event_context,
|
|
224
|
+
parent_span_context: parentSpanContextForEvent(event, trace_id),
|
|
225
|
+
attributes: eventSpanAttributes(eventbus, event),
|
|
226
|
+
start_time
|
|
227
|
+
});
|
|
228
|
+
if (event.event_errors.length > 0) {
|
|
229
|
+
recordSpanError(span, event.event_errors[0]);
|
|
230
|
+
} else {
|
|
231
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
232
|
+
}
|
|
233
|
+
span.end(end_time);
|
|
234
|
+
}
|
|
235
|
+
completeHandlerSpanWithFactory(eventbus, event, event_result) {
|
|
236
|
+
const root_event = rootEventForEvent(eventbus, event);
|
|
237
|
+
const trace_id = traceIdForRootEvent(root_event.event_id);
|
|
238
|
+
const start_time = dateFromIso(event_result.started_at);
|
|
239
|
+
const span = this.span_factory({
|
|
240
|
+
name: `abxbus.handler ${event.event_type} ${event_result.handler_name}`,
|
|
241
|
+
span_context: handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id),
|
|
242
|
+
parent_span_context: eventSpanContext(trace_id, event.event_id),
|
|
243
|
+
attributes: handlerSpanAttributes(eventbus, event, event_result),
|
|
244
|
+
start_time
|
|
245
|
+
});
|
|
246
|
+
if (event_result.error !== void 0) {
|
|
247
|
+
recordSpanError(span, event_result.error);
|
|
248
|
+
} else {
|
|
249
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
250
|
+
}
|
|
251
|
+
span.end(endTimeAfterStart(start_time, dateFromIso(event_result.completed_at)));
|
|
252
|
+
}
|
|
189
253
|
}
|
|
190
254
|
function handlerSpanKey(event_id, handler_id) {
|
|
191
255
|
return `${event_id}:${handler_id}`;
|
|
192
256
|
}
|
|
257
|
+
function eventSpanAttributes(eventbus, event) {
|
|
258
|
+
return compactAttributes({
|
|
259
|
+
"abxbus.bus.id": eventbus.id,
|
|
260
|
+
"abxbus.bus.name": eventbus.name,
|
|
261
|
+
"abxbus.event.id": event.event_id,
|
|
262
|
+
"abxbus.event.type": event.event_type,
|
|
263
|
+
"abxbus.event.version": event.event_version,
|
|
264
|
+
"abxbus.event.session_id": stringValue(event.session_id),
|
|
265
|
+
"abxbus.event.parent_id": event.event_parent_id,
|
|
266
|
+
"abxbus.event.emitted_by_handler_id": event.event_emitted_by_handler_id,
|
|
267
|
+
"abxbus.event.path": event.event_path.join(" "),
|
|
268
|
+
"abxbus.event.status": event.event_status,
|
|
269
|
+
"abxbus.event.result_count": event.event_results.size,
|
|
270
|
+
"abxbus.event.error_count": event.event_errors.length,
|
|
271
|
+
"abxbus.event.child_count": event.event_children.length
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function handlerSpanAttributes(eventbus, event, event_result) {
|
|
275
|
+
return compactAttributes({
|
|
276
|
+
"abxbus.bus.id": eventbus.id,
|
|
277
|
+
"abxbus.bus.name": eventbus.name,
|
|
278
|
+
"abxbus.event.id": event.event_id,
|
|
279
|
+
"abxbus.event.type": event.event_type,
|
|
280
|
+
"abxbus.handler.id": event_result.handler_id,
|
|
281
|
+
"abxbus.handler.name": event_result.handler_name,
|
|
282
|
+
"abxbus.handler.file_path": event_result.handler_file_path,
|
|
283
|
+
"abxbus.handler.event_pattern": event_result.handler.event_pattern,
|
|
284
|
+
"abxbus.event_result.id": event_result.id,
|
|
285
|
+
"abxbus.event_result.status": event_result.status,
|
|
286
|
+
"abxbus.handler.child_count": event_result.event_children.length
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
function rootSpanAttributes(root_span_attributes, eventbus, event) {
|
|
290
|
+
const session_id = stringValue(event.session_id);
|
|
291
|
+
return compactAttributes({
|
|
292
|
+
...resolveAttributes(root_span_attributes, eventbus, event),
|
|
293
|
+
"abxbus.trace.root": true,
|
|
294
|
+
"abxbus.bus.id": eventbus.id,
|
|
295
|
+
"abxbus.bus.name": eventbus.name,
|
|
296
|
+
"abxbus.root_event.id": event.event_id,
|
|
297
|
+
"abxbus.root_event.type": event.event_type,
|
|
298
|
+
"abxbus.root_event.session_id": session_id,
|
|
299
|
+
"abxbus.root_event.status": event.event_status,
|
|
300
|
+
"abxbus.root_event.error_count": event.event_errors.length,
|
|
301
|
+
"abxbus.root_event.child_count": event.event_children.length
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
function rootEventForEvent(eventbus, event) {
|
|
305
|
+
let current = event._event_original ?? event;
|
|
306
|
+
const seen = /* @__PURE__ */ new Set();
|
|
307
|
+
while (current.event_parent_id && !seen.has(current.event_id)) {
|
|
308
|
+
seen.add(current.event_id);
|
|
309
|
+
const parent = eventbus.findEventById(current.event_parent_id);
|
|
310
|
+
if (!parent) {
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
current = parent._event_original ?? parent;
|
|
314
|
+
}
|
|
315
|
+
return current;
|
|
316
|
+
}
|
|
317
|
+
function parentSpanContextForEvent(event, trace_id) {
|
|
318
|
+
if (!event.event_parent_id) {
|
|
319
|
+
return rootSpanContext(trace_id, event.event_id);
|
|
320
|
+
}
|
|
321
|
+
if (event.event_emitted_by_handler_id) {
|
|
322
|
+
return handlerSpanContext(trace_id, event.event_parent_id, event.event_emitted_by_handler_id);
|
|
323
|
+
}
|
|
324
|
+
return eventSpanContext(trace_id, event.event_parent_id);
|
|
325
|
+
}
|
|
326
|
+
function rootSpanContext(trace_id, event_id) {
|
|
327
|
+
return {
|
|
328
|
+
traceId: trace_id,
|
|
329
|
+
spanId: deterministicSpanId(`abxbus.root:${event_id}`),
|
|
330
|
+
traceFlags: 1
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
function eventSpanContext(trace_id, event_id) {
|
|
334
|
+
return {
|
|
335
|
+
traceId: trace_id,
|
|
336
|
+
spanId: deterministicSpanId(`abxbus.event:${event_id}`),
|
|
337
|
+
traceFlags: 1
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
function handlerSpanContext(trace_id, event_id, handler_id) {
|
|
341
|
+
return {
|
|
342
|
+
traceId: trace_id,
|
|
343
|
+
spanId: deterministicSpanId(`abxbus.handler:${event_id}:${handler_id}`),
|
|
344
|
+
traceFlags: 1
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function traceIdForRootEvent(event_id) {
|
|
348
|
+
return `${fnv1a64Hex(`abxbus.trace.a:${event_id}`)}${fnv1a64Hex(`abxbus.trace.b:${event_id}`)}`;
|
|
349
|
+
}
|
|
350
|
+
function deterministicSpanId(input) {
|
|
351
|
+
return fnv1a64Hex(input);
|
|
352
|
+
}
|
|
353
|
+
function fnv1a64Hex(input) {
|
|
354
|
+
let hash = 0xcbf29ce484222325n;
|
|
355
|
+
const prime = 0x100000001b3n;
|
|
356
|
+
const mask = 0xffffffffffffffffn;
|
|
357
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
358
|
+
hash ^= BigInt(input.charCodeAt(index));
|
|
359
|
+
hash = hash * prime & mask;
|
|
360
|
+
}
|
|
361
|
+
if (hash === 0n) {
|
|
362
|
+
hash = 1n;
|
|
363
|
+
}
|
|
364
|
+
return hash.toString(16).padStart(16, "0");
|
|
365
|
+
}
|
|
193
366
|
function dateFromIso(value) {
|
|
194
367
|
if (value == null) {
|
|
195
368
|
return void 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/middleware_otel_tracing.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n ROOT_CONTEXT,\n SpanStatusCode,\n trace,\n type Context,\n type Span,\n type SpanAttributeValue,\n type SpanAttributes,\n type Tracer,\n} from '@opentelemetry/api'\n\nimport type { BaseEvent } from './base_event.js'\nimport type { EventBus } from './event_bus.js'\nimport type { EventResult } from './event_result.js'\nimport type { EventBusMiddleware } from './middlewares.js'\nimport type { EventStatus } from './types.js'\n\ntype OpenTelemetryTraceApi = Pick<typeof trace, 'getTracer' | 'setSpan'>\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n root_span_name?: string | ((eventbus: EventBus, event: BaseEvent) => string)\n root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes)\n}\n\nexport class OtelTracingMiddleware implements EventBusMiddleware {\n private readonly tracer: Tracer\n private readonly trace_api: OpenTelemetryTraceApi\n private readonly root_span_name: OtelTracingMiddlewareOptions['root_span_name']\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\n private readonly root_spans = new Map<string, Span>()\n private readonly root_contexts = new Map<string, Context>()\n private readonly event_spans = new Map<string, Span>()\n private readonly event_contexts = new Map<string, Context>()\n private readonly handler_spans = new Map<string, Span>()\n private readonly handler_contexts = new Map<string, Context>()\n\n constructor(options: OtelTracingMiddlewareOptions = {}) {\n this.trace_api = options.trace_api ?? trace\n this.tracer = options.tracer ?? this.trace_api.getTracer('abxbus')\n this.root_span_name = options.root_span_name\n this.root_span_attributes = options.root_span_attributes\n }\n\n onEventChange(eventbus: EventBus, event: BaseEvent, status: EventStatus): void {\n if (status === 'started') {\n this.startEventSpan(eventbus, event)\n return\n }\n\n if (status === 'completed') {\n this.completeEventSpan(eventbus, event)\n }\n }\n\n onEventResultChange(eventbus: EventBus, event: BaseEvent, event_result: EventResult, status: EventStatus): void {\n if (status === 'started') {\n this.startHandlerSpan(eventbus, event, event_result)\n return\n }\n\n if (status === 'completed') {\n this.completeHandlerSpan(event_result)\n }\n }\n\n private startEventSpan(eventbus: EventBus, event: BaseEvent): Span {\n const existing = this.event_spans.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const parent_context = this.parentContextForEvent(event) ?? this.startRootSpan(eventbus, event)\n const start_time = dateFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n `abxbus.event ${event.event_type}`,\n {\n attributes: compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.event.version': event.event_version,\n 'abxbus.event.session_id': stringValue((event as { session_id?: unknown }).session_id),\n 'abxbus.event.parent_id': event.event_parent_id,\n 'abxbus.event.emitted_by_handler_id': event.event_emitted_by_handler_id,\n 'abxbus.event.path': event.event_path.join(' '),\n }),\n startTime: start_time,\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.event_spans.set(event.event_id, span)\n this.event_contexts.set(event.event_id, span_context)\n return span\n }\n\n private completeEventSpan(eventbus: EventBus, event: BaseEvent): void {\n const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event)\n if (event.event_errors.length > 0) {\n recordSpanError(span, event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n compactAttributes({\n 'abxbus.event.status': event.event_status,\n 'abxbus.event.result_count': event.event_results.size,\n 'abxbus.event.error_count': event.event_errors.length,\n 'abxbus.event.child_count': event.event_children.length,\n })\n )\n const start_time = dateFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at))\n span.end(end_time)\n this.event_spans.delete(event.event_id)\n this.event_contexts.delete(event.event_id)\n this.completeRootSpan(event.event_id, start_time, end_time)\n }\n\n private startHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): Span {\n const existing = this.handler_spans.get(event_result.id)\n if (existing) {\n return existing\n }\n\n const parent_context =\n this.event_contexts.get(event.event_id) ?? this.trace_api.setSpan(ROOT_CONTEXT, this.startEventSpan(eventbus, event))\n const span = this.tracer.startSpan(\n `abxbus.handler ${event.event_type} ${event_result.handler_name}`,\n {\n attributes: compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.handler.id': event_result.handler_id,\n 'abxbus.handler.name': event_result.handler_name,\n 'abxbus.handler.file_path': event_result.handler_file_path,\n 'abxbus.handler.event_pattern': event_result.handler.event_pattern,\n 'abxbus.event_result.id': event_result.id,\n }),\n startTime: dateFromIso(event_result.started_at),\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.handler_spans.set(event_result.id, span)\n this.handler_contexts.set(handlerSpanKey(event_result.event_id, event_result.handler_id), span_context)\n return span\n }\n\n private completeHandlerSpan(event_result: EventResult): void {\n const span = this.handler_spans.get(event_result.id)\n if (!span) {\n return\n }\n\n if (event_result.error !== undefined) {\n recordSpanError(span, event_result.error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n compactAttributes({\n 'abxbus.event_result.status': event_result.status,\n 'abxbus.handler.child_count': event_result.event_children.length,\n })\n )\n span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)))\n this.handler_spans.delete(event_result.id)\n this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id))\n }\n\n private startRootSpan(eventbus: EventBus, event: BaseEvent): Context {\n const existing = this.root_contexts.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const session_id = stringValue((event as { session_id?: unknown }).session_id)\n const root_attributes = resolveAttributes(this.root_span_attributes, eventbus, event)\n const root_span = this.tracer.startSpan(\n resolveRootSpanName(this.root_span_name, eventbus, event),\n {\n attributes: compactAttributes({\n ...root_attributes,\n 'abxbus.trace.root': true,\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.root_event.id': event.event_id,\n 'abxbus.root_event.type': event.event_type,\n 'abxbus.root_event.session_id': session_id,\n }),\n startTime: dateFromIso(event.event_started_at),\n },\n ROOT_CONTEXT\n )\n const root_context = this.trace_api.setSpan(ROOT_CONTEXT, root_span)\n this.root_spans.set(event.event_id, root_span)\n this.root_contexts.set(event.event_id, root_context)\n return root_context\n }\n\n private completeRootSpan(event_id: string, start_time: Date | undefined, end_time: Date | undefined): void {\n const root_span = this.root_spans.get(event_id)\n if (!root_span) {\n return\n }\n\n root_span.setStatus({ code: SpanStatusCode.OK })\n root_span.end(endTimeAfterStart(start_time, end_time))\n this.root_spans.delete(event_id)\n this.root_contexts.delete(event_id)\n }\n\n private parentContextForEvent(event: BaseEvent): Context | undefined {\n if (event.event_parent_id && event.event_emitted_by_handler_id) {\n const handler_context = this.handler_contexts.get(handlerSpanKey(event.event_parent_id, event.event_emitted_by_handler_id))\n if (handler_context) {\n return handler_context\n }\n }\n\n return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : undefined\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction dateFromIso(value: string | null | undefined): Date | undefined {\n if (value == null) {\n return undefined\n }\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? undefined : date\n}\n\nfunction endTimeAfterStart(start_time: Date | undefined, end_time: Date | undefined): Date | undefined {\n if (!start_time || !end_time) {\n return end_time\n }\n\n return end_time.getTime() > start_time.getTime() ? end_time : new Date(start_time.getTime() + 1)\n}\n\nfunction resolveRootSpanName(\n root_span_name: OtelTracingMiddlewareOptions['root_span_name'],\n eventbus: EventBus,\n event: BaseEvent\n): string {\n if (typeof root_span_name === 'function') {\n return root_span_name(eventbus, event)\n }\n return root_span_name ?? `abxbus.trace ${eventbus.name}`\n}\n\nfunction resolveAttributes(\n attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return typeof attributes === 'function' ? attributes(eventbus, event) : (attributes ?? {})\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction compactAttributes(attributes: Record<string, SpanAttributeValue | null | undefined>): SpanAttributes {\n const compacted: SpanAttributes = {}\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== null && value !== undefined) {\n compacted[key] = value\n }\n }\n return compacted\n}\n\nfunction recordSpanError(span: Span, error: unknown): void {\n if (error instanceof Error) {\n span.recordException(error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n return\n }\n\n const message = typeof error === 'string' ? error : 'Unknown abxbus handler error'\n span.recordException(message)\n span.setStatus({ code: SpanStatusCode.ERROR, message })\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n ROOT_CONTEXT,\n SpanStatusCode,\n trace,\n type Context,\n type Span,\n type SpanAttributeValue,\n type SpanAttributes,\n type SpanContext,\n type Tracer,\n} from '@opentelemetry/api'\n\nimport type { BaseEvent } from './base_event.js'\nimport type { EventBus } from './event_bus.js'\nimport type { EventResult } from './event_result.js'\nimport type { EventBusMiddleware } from './middlewares.js'\nimport type { EventStatus } from './types.js'\n\ntype OpenTelemetryTraceApi = Pick<typeof trace, 'getTracer' | 'setSpan'>\n\nexport type OtelTracingSpanFactoryInput = {\n name: string\n span_context: SpanContext\n parent_span_context?: SpanContext\n attributes: SpanAttributes\n start_time?: Date\n}\n\nexport type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n span_factory?: OtelTracingSpanFactory\n root_span_name?: string | ((eventbus: EventBus, event: BaseEvent) => string)\n root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes)\n}\n\nexport class OtelTracingMiddleware implements EventBusMiddleware {\n private readonly tracer: Tracer\n private readonly trace_api: OpenTelemetryTraceApi\n private readonly span_factory?: OtelTracingSpanFactory\n private readonly root_span_name: OtelTracingMiddlewareOptions['root_span_name']\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\n private readonly root_spans = new Map<string, Span>()\n private readonly root_contexts = new Map<string, Context>()\n private readonly event_spans = new Map<string, Span>()\n private readonly event_contexts = new Map<string, Context>()\n private readonly handler_spans = new Map<string, Span>()\n private readonly handler_contexts = new Map<string, Context>()\n\n constructor(options: OtelTracingMiddlewareOptions = {}) {\n this.trace_api = options.trace_api ?? trace\n this.tracer = options.tracer ?? this.trace_api.getTracer('abxbus')\n this.span_factory = options.span_factory\n this.root_span_name = options.root_span_name\n this.root_span_attributes = options.root_span_attributes\n }\n\n onEventChange(eventbus: EventBus, event: BaseEvent, status: EventStatus): void {\n if (status === 'started') {\n if (this.span_factory) {\n return\n }\n this.startEventSpan(eventbus, event)\n return\n }\n\n if (status === 'completed') {\n this.completeEventSpan(eventbus, event)\n }\n }\n\n onEventResultChange(eventbus: EventBus, event: BaseEvent, event_result: EventResult, status: EventStatus): void {\n if (status === 'started') {\n if (this.span_factory) {\n return\n }\n this.startHandlerSpan(eventbus, event, event_result)\n return\n }\n\n if (status === 'completed') {\n this.completeHandlerSpan(eventbus, event, event_result)\n }\n }\n\n private startEventSpan(eventbus: EventBus, event: BaseEvent): Span {\n const existing = this.event_spans.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const parent_context = this.parentContextForEvent(event) ?? this.startRootSpan(eventbus, event)\n const start_time = dateFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n `abxbus.event ${event.event_type}`,\n {\n attributes: compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.event.version': event.event_version,\n 'abxbus.event.session_id': stringValue((event as { session_id?: unknown }).session_id),\n 'abxbus.event.parent_id': event.event_parent_id,\n 'abxbus.event.emitted_by_handler_id': event.event_emitted_by_handler_id,\n 'abxbus.event.path': event.event_path.join(' '),\n }),\n startTime: start_time,\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.event_spans.set(event.event_id, span)\n this.event_contexts.set(event.event_id, span_context)\n return span\n }\n\n private completeEventSpan(eventbus: EventBus, event: BaseEvent): void {\n if (this.span_factory) {\n this.completeEventSpanWithFactory(eventbus, event)\n return\n }\n\n const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event)\n if (event.event_errors.length > 0) {\n recordSpanError(span, event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n compactAttributes({\n 'abxbus.event.status': event.event_status,\n 'abxbus.event.result_count': event.event_results.size,\n 'abxbus.event.error_count': event.event_errors.length,\n 'abxbus.event.child_count': event.event_children.length,\n })\n )\n const start_time = dateFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at))\n span.end(end_time)\n this.event_spans.delete(event.event_id)\n this.event_contexts.delete(event.event_id)\n this.completeRootSpan(event.event_id, start_time, end_time)\n }\n\n private startHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): Span {\n const existing = this.handler_spans.get(event_result.id)\n if (existing) {\n return existing\n }\n\n const parent_context =\n this.event_contexts.get(event.event_id) ?? this.trace_api.setSpan(ROOT_CONTEXT, this.startEventSpan(eventbus, event))\n const span = this.tracer.startSpan(\n `abxbus.handler ${event.event_type} ${event_result.handler_name}`,\n {\n attributes: compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.handler.id': event_result.handler_id,\n 'abxbus.handler.name': event_result.handler_name,\n 'abxbus.handler.file_path': event_result.handler_file_path,\n 'abxbus.handler.event_pattern': event_result.handler.event_pattern,\n 'abxbus.event_result.id': event_result.id,\n }),\n startTime: dateFromIso(event_result.started_at),\n },\n parent_context\n )\n const span_context = this.trace_api.setSpan(parent_context, span)\n this.handler_spans.set(event_result.id, span)\n this.handler_contexts.set(handlerSpanKey(event_result.event_id, event_result.handler_id), span_context)\n return span\n }\n\n private completeHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): void {\n if (this.span_factory) {\n this.completeHandlerSpanWithFactory(eventbus, event, event_result)\n return\n }\n\n const span = this.handler_spans.get(event_result.id)\n if (!span) {\n return\n }\n\n if (event_result.error !== undefined) {\n recordSpanError(span, event_result.error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.setAttributes(\n compactAttributes({\n 'abxbus.event_result.status': event_result.status,\n 'abxbus.handler.child_count': event_result.event_children.length,\n })\n )\n span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)))\n this.handler_spans.delete(event_result.id)\n this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id))\n }\n\n private startRootSpan(eventbus: EventBus, event: BaseEvent): Context {\n const existing = this.root_contexts.get(event.event_id)\n if (existing) {\n return existing\n }\n\n const session_id = stringValue((event as { session_id?: unknown }).session_id)\n const root_attributes = resolveAttributes(this.root_span_attributes, eventbus, event)\n const root_span = this.tracer.startSpan(\n resolveRootSpanName(this.root_span_name, eventbus, event),\n {\n attributes: compactAttributes({\n ...root_attributes,\n 'abxbus.trace.root': true,\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.root_event.id': event.event_id,\n 'abxbus.root_event.type': event.event_type,\n 'abxbus.root_event.session_id': session_id,\n }),\n startTime: dateFromIso(event.event_started_at),\n },\n ROOT_CONTEXT\n )\n const root_context = this.trace_api.setSpan(ROOT_CONTEXT, root_span)\n this.root_spans.set(event.event_id, root_span)\n this.root_contexts.set(event.event_id, root_context)\n return root_context\n }\n\n private completeRootSpan(event_id: string, start_time: Date | undefined, end_time: Date | undefined): void {\n const root_span = this.root_spans.get(event_id)\n if (!root_span) {\n return\n }\n\n root_span.setStatus({ code: SpanStatusCode.OK })\n root_span.end(endTimeAfterStart(start_time, end_time))\n this.root_spans.delete(event_id)\n this.root_contexts.delete(event_id)\n }\n\n private parentContextForEvent(event: BaseEvent): Context | undefined {\n if (event.event_parent_id && event.event_emitted_by_handler_id) {\n const handler_context = this.handler_contexts.get(handlerSpanKey(event.event_parent_id, event.event_emitted_by_handler_id))\n if (handler_context) {\n return handler_context\n }\n }\n\n return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : undefined\n }\n\n private completeEventSpanWithFactory(eventbus: EventBus, event: BaseEvent): void {\n const root_event = rootEventForEvent(eventbus, event)\n const trace_id = traceIdForRootEvent(root_event.event_id)\n const event_context = eventSpanContext(trace_id, event.event_id)\n const start_time = dateFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at))\n\n if (!event.event_parent_id) {\n const root_span = this.span_factory!({\n name: resolveRootSpanName(this.root_span_name, eventbus, event),\n span_context: rootSpanContext(trace_id, event.event_id),\n attributes: rootSpanAttributes(this.root_span_attributes, eventbus, event),\n start_time,\n })\n root_span.setStatus({ code: SpanStatusCode.OK })\n root_span.end(end_time)\n }\n\n const span = this.span_factory!({\n name: `abxbus.event ${event.event_type}`,\n span_context: event_context,\n parent_span_context: parentSpanContextForEvent(event, trace_id),\n attributes: eventSpanAttributes(eventbus, event),\n start_time,\n })\n if (event.event_errors.length > 0) {\n recordSpanError(span, event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(end_time)\n }\n\n private completeHandlerSpanWithFactory(eventbus: EventBus, event: BaseEvent, event_result: EventResult): void {\n const root_event = rootEventForEvent(eventbus, event)\n const trace_id = traceIdForRootEvent(root_event.event_id)\n const start_time = dateFromIso(event_result.started_at)\n const span = this.span_factory!({\n name: `abxbus.handler ${event.event_type} ${event_result.handler_name}`,\n span_context: handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id),\n parent_span_context: eventSpanContext(trace_id, event.event_id),\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n start_time,\n })\n\n if (event_result.error !== undefined) {\n recordSpanError(span, event_result.error)\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(endTimeAfterStart(start_time, dateFromIso(event_result.completed_at)))\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction eventSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.event.version': event.event_version,\n 'abxbus.event.session_id': stringValue((event as { session_id?: unknown }).session_id),\n 'abxbus.event.parent_id': event.event_parent_id,\n 'abxbus.event.emitted_by_handler_id': event.event_emitted_by_handler_id,\n 'abxbus.event.path': event.event_path.join(' '),\n 'abxbus.event.status': event.event_status,\n 'abxbus.event.result_count': event.event_results.size,\n 'abxbus.event.error_count': event.event_errors.length,\n 'abxbus.event.child_count': event.event_children.length,\n })\n}\n\nfunction handlerSpanAttributes(eventbus: EventBus, event: BaseEvent, event_result: EventResult): SpanAttributes {\n return compactAttributes({\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.event.id': event.event_id,\n 'abxbus.event.type': event.event_type,\n 'abxbus.handler.id': event_result.handler_id,\n 'abxbus.handler.name': event_result.handler_name,\n 'abxbus.handler.file_path': event_result.handler_file_path,\n 'abxbus.handler.event_pattern': event_result.handler.event_pattern,\n 'abxbus.event_result.id': event_result.id,\n 'abxbus.event_result.status': event_result.status,\n 'abxbus.handler.child_count': event_result.event_children.length,\n })\n}\n\nfunction rootSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n const session_id = stringValue((event as { session_id?: unknown }).session_id)\n return compactAttributes({\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\n 'abxbus.bus.id': eventbus.id,\n 'abxbus.bus.name': eventbus.name,\n 'abxbus.root_event.id': event.event_id,\n 'abxbus.root_event.type': event.event_type,\n 'abxbus.root_event.session_id': session_id,\n 'abxbus.root_event.status': event.event_status,\n 'abxbus.root_event.error_count': event.event_errors.length,\n 'abxbus.root_event.child_count': event.event_children.length,\n })\n}\n\nfunction rootEventForEvent(eventbus: EventBus, event: BaseEvent): BaseEvent {\n let current = event._event_original ?? event\n const seen = new Set<string>()\n while (current.event_parent_id && !seen.has(current.event_id)) {\n seen.add(current.event_id)\n const parent = eventbus.findEventById(current.event_parent_id)\n if (!parent) {\n break\n }\n current = parent._event_original ?? parent\n }\n return current\n}\n\nfunction parentSpanContextForEvent(event: BaseEvent, trace_id: string): SpanContext {\n if (!event.event_parent_id) {\n return rootSpanContext(trace_id, event.event_id)\n }\n\n if (event.event_emitted_by_handler_id) {\n return handlerSpanContext(trace_id, event.event_parent_id, event.event_emitted_by_handler_id)\n }\n\n return eventSpanContext(trace_id, event.event_parent_id)\n}\n\nfunction rootSpanContext(trace_id: string, event_id: string): SpanContext {\n return {\n traceId: trace_id,\n spanId: deterministicSpanId(`abxbus.root:${event_id}`),\n traceFlags: 1,\n }\n}\n\nfunction eventSpanContext(trace_id: string, event_id: string): SpanContext {\n return {\n traceId: trace_id,\n spanId: deterministicSpanId(`abxbus.event:${event_id}`),\n traceFlags: 1,\n }\n}\n\nfunction handlerSpanContext(trace_id: string, event_id: string, handler_id: string): SpanContext {\n return {\n traceId: trace_id,\n spanId: deterministicSpanId(`abxbus.handler:${event_id}:${handler_id}`),\n traceFlags: 1,\n }\n}\n\nfunction traceIdForRootEvent(event_id: string): string {\n return `${fnv1a64Hex(`abxbus.trace.a:${event_id}`)}${fnv1a64Hex(`abxbus.trace.b:${event_id}`)}`\n}\n\nfunction deterministicSpanId(input: string): string {\n return fnv1a64Hex(input)\n}\n\nfunction fnv1a64Hex(input: string): string {\n let hash = 0xcbf29ce484222325n\n const prime = 0x100000001b3n\n const mask = 0xffffffffffffffffn\n for (let index = 0; index < input.length; index += 1) {\n hash ^= BigInt(input.charCodeAt(index))\n hash = (hash * prime) & mask\n }\n if (hash === 0n) {\n hash = 1n\n }\n return hash.toString(16).padStart(16, '0')\n}\n\nfunction dateFromIso(value: string | null | undefined): Date | undefined {\n if (value == null) {\n return undefined\n }\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? undefined : date\n}\n\nfunction endTimeAfterStart(start_time: Date | undefined, end_time: Date | undefined): Date | undefined {\n if (!start_time || !end_time) {\n return end_time\n }\n\n return end_time.getTime() > start_time.getTime() ? end_time : new Date(start_time.getTime() + 1)\n}\n\nfunction resolveRootSpanName(root_span_name: OtelTracingMiddlewareOptions['root_span_name'], eventbus: EventBus, event: BaseEvent): string {\n if (typeof root_span_name === 'function') {\n return root_span_name(eventbus, event)\n }\n return root_span_name ?? `abxbus.trace ${eventbus.name}`\n}\n\nfunction resolveAttributes(\n attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return typeof attributes === 'function' ? attributes(eventbus, event) : (attributes ?? {})\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction compactAttributes(attributes: Record<string, SpanAttributeValue | null | undefined>): SpanAttributes {\n const compacted: SpanAttributes = {}\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== null && value !== undefined) {\n compacted[key] = value\n }\n }\n return compacted\n}\n\nfunction recordSpanError(span: Span, error: unknown): void {\n if (error instanceof Error) {\n span.recordException(error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n return\n }\n\n const message = typeof error === 'string' ? error : 'Unknown abxbus handler error'\n span.recordException(message)\n span.setStatus({ code: SpanStatusCode.ERROR, message })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { monotonicDatetime } from './helpers.js';
|
|
|
8
8
|
export type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './middlewares.js';
|
|
9
9
|
export { OtelTracingMiddleware } from './middleware_otel_tracing.js';
|
|
10
10
|
export type { OtelTracingMiddlewareOptions } from './middleware_otel_tracing.js';
|
|
11
|
+
export type { OtelTracingSpanFactory, OtelTracingSpanFactoryInput } from './middleware_otel_tracing.js';
|
|
11
12
|
export { EventHandlerTimeoutError, EventHandlerCancelledError, EventHandlerAbortedError, EventHandlerResultSchemaError, } from './event_handler.js';
|
|
12
13
|
export type { EventConcurrencyMode, EventHandlerConcurrencyMode, EventHandlerCompletionMode, EventBusInterfaceForLockManager, } from './lock_manager.js';
|
|
13
14
|
export type { EventClass, EventHandlerCallable as EventHandler, EventPattern, EventStatus, FindOptions, FindWindow } from './types.js';
|
|
@@ -1,19 +1,29 @@
|
|
|
1
|
-
import { trace, type SpanAttributes, type Tracer } from '@opentelemetry/api';
|
|
1
|
+
import { trace, type Span, type SpanAttributes, type SpanContext, type Tracer } from '@opentelemetry/api';
|
|
2
2
|
import type { BaseEvent } from './base_event.js';
|
|
3
3
|
import type { EventBus } from './event_bus.js';
|
|
4
4
|
import type { EventResult } from './event_result.js';
|
|
5
5
|
import type { EventBusMiddleware } from './middlewares.js';
|
|
6
6
|
import type { EventStatus } from './types.js';
|
|
7
7
|
type OpenTelemetryTraceApi = Pick<typeof trace, 'getTracer' | 'setSpan'>;
|
|
8
|
+
export type OtelTracingSpanFactoryInput = {
|
|
9
|
+
name: string;
|
|
10
|
+
span_context: SpanContext;
|
|
11
|
+
parent_span_context?: SpanContext;
|
|
12
|
+
attributes: SpanAttributes;
|
|
13
|
+
start_time?: Date;
|
|
14
|
+
};
|
|
15
|
+
export type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span;
|
|
8
16
|
export type OtelTracingMiddlewareOptions = {
|
|
9
17
|
tracer?: Tracer;
|
|
10
18
|
trace_api?: OpenTelemetryTraceApi;
|
|
19
|
+
span_factory?: OtelTracingSpanFactory;
|
|
11
20
|
root_span_name?: string | ((eventbus: EventBus, event: BaseEvent) => string);
|
|
12
21
|
root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes);
|
|
13
22
|
};
|
|
14
23
|
export declare class OtelTracingMiddleware implements EventBusMiddleware {
|
|
15
24
|
private readonly tracer;
|
|
16
25
|
private readonly trace_api;
|
|
26
|
+
private readonly span_factory?;
|
|
17
27
|
private readonly root_span_name;
|
|
18
28
|
private readonly root_span_attributes;
|
|
19
29
|
private readonly root_spans;
|
|
@@ -32,5 +42,7 @@ export declare class OtelTracingMiddleware implements EventBusMiddleware {
|
|
|
32
42
|
private startRootSpan;
|
|
33
43
|
private completeRootSpan;
|
|
34
44
|
private parentContextForEvent;
|
|
45
|
+
private completeEventSpanWithFactory;
|
|
46
|
+
private completeHandlerSpanWithFactory;
|
|
35
47
|
}
|
|
36
48
|
export {};
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { monotonicDatetime } from './helpers.js'
|
|
|
8
8
|
export type { EventBusMiddleware, EventBusMiddlewareCtor, EventBusMiddlewareInput } from './middlewares.js'
|
|
9
9
|
export { OtelTracingMiddleware } from './middleware_otel_tracing.js'
|
|
10
10
|
export type { OtelTracingMiddlewareOptions } from './middleware_otel_tracing.js'
|
|
11
|
+
export type { OtelTracingSpanFactory, OtelTracingSpanFactoryInput } from './middleware_otel_tracing.js'
|
|
11
12
|
export {
|
|
12
13
|
EventHandlerTimeoutError,
|
|
13
14
|
EventHandlerCancelledError,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type Span,
|
|
7
7
|
type SpanAttributeValue,
|
|
8
8
|
type SpanAttributes,
|
|
9
|
+
type SpanContext,
|
|
9
10
|
type Tracer,
|
|
10
11
|
} from '@opentelemetry/api'
|
|
11
12
|
|
|
@@ -17,9 +18,20 @@ import type { EventStatus } from './types.js'
|
|
|
17
18
|
|
|
18
19
|
type OpenTelemetryTraceApi = Pick<typeof trace, 'getTracer' | 'setSpan'>
|
|
19
20
|
|
|
21
|
+
export type OtelTracingSpanFactoryInput = {
|
|
22
|
+
name: string
|
|
23
|
+
span_context: SpanContext
|
|
24
|
+
parent_span_context?: SpanContext
|
|
25
|
+
attributes: SpanAttributes
|
|
26
|
+
start_time?: Date
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span
|
|
30
|
+
|
|
20
31
|
export type OtelTracingMiddlewareOptions = {
|
|
21
32
|
tracer?: Tracer
|
|
22
33
|
trace_api?: OpenTelemetryTraceApi
|
|
34
|
+
span_factory?: OtelTracingSpanFactory
|
|
23
35
|
root_span_name?: string | ((eventbus: EventBus, event: BaseEvent) => string)
|
|
24
36
|
root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes)
|
|
25
37
|
}
|
|
@@ -27,6 +39,7 @@ export type OtelTracingMiddlewareOptions = {
|
|
|
27
39
|
export class OtelTracingMiddleware implements EventBusMiddleware {
|
|
28
40
|
private readonly tracer: Tracer
|
|
29
41
|
private readonly trace_api: OpenTelemetryTraceApi
|
|
42
|
+
private readonly span_factory?: OtelTracingSpanFactory
|
|
30
43
|
private readonly root_span_name: OtelTracingMiddlewareOptions['root_span_name']
|
|
31
44
|
private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']
|
|
32
45
|
private readonly root_spans = new Map<string, Span>()
|
|
@@ -39,12 +52,16 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
|
|
|
39
52
|
constructor(options: OtelTracingMiddlewareOptions = {}) {
|
|
40
53
|
this.trace_api = options.trace_api ?? trace
|
|
41
54
|
this.tracer = options.tracer ?? this.trace_api.getTracer('abxbus')
|
|
55
|
+
this.span_factory = options.span_factory
|
|
42
56
|
this.root_span_name = options.root_span_name
|
|
43
57
|
this.root_span_attributes = options.root_span_attributes
|
|
44
58
|
}
|
|
45
59
|
|
|
46
60
|
onEventChange(eventbus: EventBus, event: BaseEvent, status: EventStatus): void {
|
|
47
61
|
if (status === 'started') {
|
|
62
|
+
if (this.span_factory) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
48
65
|
this.startEventSpan(eventbus, event)
|
|
49
66
|
return
|
|
50
67
|
}
|
|
@@ -56,12 +73,15 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
|
|
|
56
73
|
|
|
57
74
|
onEventResultChange(eventbus: EventBus, event: BaseEvent, event_result: EventResult, status: EventStatus): void {
|
|
58
75
|
if (status === 'started') {
|
|
76
|
+
if (this.span_factory) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
59
79
|
this.startHandlerSpan(eventbus, event, event_result)
|
|
60
80
|
return
|
|
61
81
|
}
|
|
62
82
|
|
|
63
83
|
if (status === 'completed') {
|
|
64
|
-
this.completeHandlerSpan(event_result)
|
|
84
|
+
this.completeHandlerSpan(eventbus, event, event_result)
|
|
65
85
|
}
|
|
66
86
|
}
|
|
67
87
|
|
|
@@ -98,6 +118,11 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
|
|
|
98
118
|
}
|
|
99
119
|
|
|
100
120
|
private completeEventSpan(eventbus: EventBus, event: BaseEvent): void {
|
|
121
|
+
if (this.span_factory) {
|
|
122
|
+
this.completeEventSpanWithFactory(eventbus, event)
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
101
126
|
const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event)
|
|
102
127
|
if (event.event_errors.length > 0) {
|
|
103
128
|
recordSpanError(span, event.event_errors[0])
|
|
@@ -152,7 +177,12 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
|
|
|
152
177
|
return span
|
|
153
178
|
}
|
|
154
179
|
|
|
155
|
-
private completeHandlerSpan(event_result: EventResult): void {
|
|
180
|
+
private completeHandlerSpan(eventbus: EventBus, event: BaseEvent, event_result: EventResult): void {
|
|
181
|
+
if (this.span_factory) {
|
|
182
|
+
this.completeHandlerSpanWithFactory(eventbus, event, event_result)
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
|
|
156
186
|
const span = this.handler_spans.get(event_result.id)
|
|
157
187
|
if (!span) {
|
|
158
188
|
return
|
|
@@ -226,12 +256,191 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
|
|
|
226
256
|
|
|
227
257
|
return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : undefined
|
|
228
258
|
}
|
|
259
|
+
|
|
260
|
+
private completeEventSpanWithFactory(eventbus: EventBus, event: BaseEvent): void {
|
|
261
|
+
const root_event = rootEventForEvent(eventbus, event)
|
|
262
|
+
const trace_id = traceIdForRootEvent(root_event.event_id)
|
|
263
|
+
const event_context = eventSpanContext(trace_id, event.event_id)
|
|
264
|
+
const start_time = dateFromIso(event.event_started_at)
|
|
265
|
+
const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at))
|
|
266
|
+
|
|
267
|
+
if (!event.event_parent_id) {
|
|
268
|
+
const root_span = this.span_factory!({
|
|
269
|
+
name: resolveRootSpanName(this.root_span_name, eventbus, event),
|
|
270
|
+
span_context: rootSpanContext(trace_id, event.event_id),
|
|
271
|
+
attributes: rootSpanAttributes(this.root_span_attributes, eventbus, event),
|
|
272
|
+
start_time,
|
|
273
|
+
})
|
|
274
|
+
root_span.setStatus({ code: SpanStatusCode.OK })
|
|
275
|
+
root_span.end(end_time)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const span = this.span_factory!({
|
|
279
|
+
name: `abxbus.event ${event.event_type}`,
|
|
280
|
+
span_context: event_context,
|
|
281
|
+
parent_span_context: parentSpanContextForEvent(event, trace_id),
|
|
282
|
+
attributes: eventSpanAttributes(eventbus, event),
|
|
283
|
+
start_time,
|
|
284
|
+
})
|
|
285
|
+
if (event.event_errors.length > 0) {
|
|
286
|
+
recordSpanError(span, event.event_errors[0])
|
|
287
|
+
} else {
|
|
288
|
+
span.setStatus({ code: SpanStatusCode.OK })
|
|
289
|
+
}
|
|
290
|
+
span.end(end_time)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private completeHandlerSpanWithFactory(eventbus: EventBus, event: BaseEvent, event_result: EventResult): void {
|
|
294
|
+
const root_event = rootEventForEvent(eventbus, event)
|
|
295
|
+
const trace_id = traceIdForRootEvent(root_event.event_id)
|
|
296
|
+
const start_time = dateFromIso(event_result.started_at)
|
|
297
|
+
const span = this.span_factory!({
|
|
298
|
+
name: `abxbus.handler ${event.event_type} ${event_result.handler_name}`,
|
|
299
|
+
span_context: handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id),
|
|
300
|
+
parent_span_context: eventSpanContext(trace_id, event.event_id),
|
|
301
|
+
attributes: handlerSpanAttributes(eventbus, event, event_result),
|
|
302
|
+
start_time,
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
if (event_result.error !== undefined) {
|
|
306
|
+
recordSpanError(span, event_result.error)
|
|
307
|
+
} else {
|
|
308
|
+
span.setStatus({ code: SpanStatusCode.OK })
|
|
309
|
+
}
|
|
310
|
+
span.end(endTimeAfterStart(start_time, dateFromIso(event_result.completed_at)))
|
|
311
|
+
}
|
|
229
312
|
}
|
|
230
313
|
|
|
231
314
|
function handlerSpanKey(event_id: string, handler_id: string): string {
|
|
232
315
|
return `${event_id}:${handler_id}`
|
|
233
316
|
}
|
|
234
317
|
|
|
318
|
+
function eventSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {
|
|
319
|
+
return compactAttributes({
|
|
320
|
+
'abxbus.bus.id': eventbus.id,
|
|
321
|
+
'abxbus.bus.name': eventbus.name,
|
|
322
|
+
'abxbus.event.id': event.event_id,
|
|
323
|
+
'abxbus.event.type': event.event_type,
|
|
324
|
+
'abxbus.event.version': event.event_version,
|
|
325
|
+
'abxbus.event.session_id': stringValue((event as { session_id?: unknown }).session_id),
|
|
326
|
+
'abxbus.event.parent_id': event.event_parent_id,
|
|
327
|
+
'abxbus.event.emitted_by_handler_id': event.event_emitted_by_handler_id,
|
|
328
|
+
'abxbus.event.path': event.event_path.join(' '),
|
|
329
|
+
'abxbus.event.status': event.event_status,
|
|
330
|
+
'abxbus.event.result_count': event.event_results.size,
|
|
331
|
+
'abxbus.event.error_count': event.event_errors.length,
|
|
332
|
+
'abxbus.event.child_count': event.event_children.length,
|
|
333
|
+
})
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function handlerSpanAttributes(eventbus: EventBus, event: BaseEvent, event_result: EventResult): SpanAttributes {
|
|
337
|
+
return compactAttributes({
|
|
338
|
+
'abxbus.bus.id': eventbus.id,
|
|
339
|
+
'abxbus.bus.name': eventbus.name,
|
|
340
|
+
'abxbus.event.id': event.event_id,
|
|
341
|
+
'abxbus.event.type': event.event_type,
|
|
342
|
+
'abxbus.handler.id': event_result.handler_id,
|
|
343
|
+
'abxbus.handler.name': event_result.handler_name,
|
|
344
|
+
'abxbus.handler.file_path': event_result.handler_file_path,
|
|
345
|
+
'abxbus.handler.event_pattern': event_result.handler.event_pattern,
|
|
346
|
+
'abxbus.event_result.id': event_result.id,
|
|
347
|
+
'abxbus.event_result.status': event_result.status,
|
|
348
|
+
'abxbus.handler.child_count': event_result.event_children.length,
|
|
349
|
+
})
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function rootSpanAttributes(
|
|
353
|
+
root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],
|
|
354
|
+
eventbus: EventBus,
|
|
355
|
+
event: BaseEvent
|
|
356
|
+
): SpanAttributes {
|
|
357
|
+
const session_id = stringValue((event as { session_id?: unknown }).session_id)
|
|
358
|
+
return compactAttributes({
|
|
359
|
+
...resolveAttributes(root_span_attributes, eventbus, event),
|
|
360
|
+
'abxbus.trace.root': true,
|
|
361
|
+
'abxbus.bus.id': eventbus.id,
|
|
362
|
+
'abxbus.bus.name': eventbus.name,
|
|
363
|
+
'abxbus.root_event.id': event.event_id,
|
|
364
|
+
'abxbus.root_event.type': event.event_type,
|
|
365
|
+
'abxbus.root_event.session_id': session_id,
|
|
366
|
+
'abxbus.root_event.status': event.event_status,
|
|
367
|
+
'abxbus.root_event.error_count': event.event_errors.length,
|
|
368
|
+
'abxbus.root_event.child_count': event.event_children.length,
|
|
369
|
+
})
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function rootEventForEvent(eventbus: EventBus, event: BaseEvent): BaseEvent {
|
|
373
|
+
let current = event._event_original ?? event
|
|
374
|
+
const seen = new Set<string>()
|
|
375
|
+
while (current.event_parent_id && !seen.has(current.event_id)) {
|
|
376
|
+
seen.add(current.event_id)
|
|
377
|
+
const parent = eventbus.findEventById(current.event_parent_id)
|
|
378
|
+
if (!parent) {
|
|
379
|
+
break
|
|
380
|
+
}
|
|
381
|
+
current = parent._event_original ?? parent
|
|
382
|
+
}
|
|
383
|
+
return current
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function parentSpanContextForEvent(event: BaseEvent, trace_id: string): SpanContext {
|
|
387
|
+
if (!event.event_parent_id) {
|
|
388
|
+
return rootSpanContext(trace_id, event.event_id)
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (event.event_emitted_by_handler_id) {
|
|
392
|
+
return handlerSpanContext(trace_id, event.event_parent_id, event.event_emitted_by_handler_id)
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return eventSpanContext(trace_id, event.event_parent_id)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function rootSpanContext(trace_id: string, event_id: string): SpanContext {
|
|
399
|
+
return {
|
|
400
|
+
traceId: trace_id,
|
|
401
|
+
spanId: deterministicSpanId(`abxbus.root:${event_id}`),
|
|
402
|
+
traceFlags: 1,
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function eventSpanContext(trace_id: string, event_id: string): SpanContext {
|
|
407
|
+
return {
|
|
408
|
+
traceId: trace_id,
|
|
409
|
+
spanId: deterministicSpanId(`abxbus.event:${event_id}`),
|
|
410
|
+
traceFlags: 1,
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function handlerSpanContext(trace_id: string, event_id: string, handler_id: string): SpanContext {
|
|
415
|
+
return {
|
|
416
|
+
traceId: trace_id,
|
|
417
|
+
spanId: deterministicSpanId(`abxbus.handler:${event_id}:${handler_id}`),
|
|
418
|
+
traceFlags: 1,
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function traceIdForRootEvent(event_id: string): string {
|
|
423
|
+
return `${fnv1a64Hex(`abxbus.trace.a:${event_id}`)}${fnv1a64Hex(`abxbus.trace.b:${event_id}`)}`
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function deterministicSpanId(input: string): string {
|
|
427
|
+
return fnv1a64Hex(input)
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function fnv1a64Hex(input: string): string {
|
|
431
|
+
let hash = 0xcbf29ce484222325n
|
|
432
|
+
const prime = 0x100000001b3n
|
|
433
|
+
const mask = 0xffffffffffffffffn
|
|
434
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
435
|
+
hash ^= BigInt(input.charCodeAt(index))
|
|
436
|
+
hash = (hash * prime) & mask
|
|
437
|
+
}
|
|
438
|
+
if (hash === 0n) {
|
|
439
|
+
hash = 1n
|
|
440
|
+
}
|
|
441
|
+
return hash.toString(16).padStart(16, '0')
|
|
442
|
+
}
|
|
443
|
+
|
|
235
444
|
function dateFromIso(value: string | null | undefined): Date | undefined {
|
|
236
445
|
if (value == null) {
|
|
237
446
|
return undefined
|