abxbus 2.4.18 → 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.
@@ -1,7 +1,16 @@
1
- import { ROOT_CONTEXT, SpanStatusCode, trace } from "@opentelemetry/api";
1
+ import {
2
+ ROOT_CONTEXT,
3
+ SpanStatusCode,
4
+ trace
5
+ } from "@opentelemetry/api";
2
6
  class OtelTracingMiddleware {
3
7
  tracer;
4
8
  trace_api;
9
+ span_factory;
10
+ root_span_name;
11
+ root_span_attributes;
12
+ root_spans = /* @__PURE__ */ new Map();
13
+ root_contexts = /* @__PURE__ */ new Map();
5
14
  event_spans = /* @__PURE__ */ new Map();
6
15
  event_contexts = /* @__PURE__ */ new Map();
7
16
  handler_spans = /* @__PURE__ */ new Map();
@@ -9,9 +18,15 @@ class OtelTracingMiddleware {
9
18
  constructor(options = {}) {
10
19
  this.trace_api = options.trace_api ?? trace;
11
20
  this.tracer = options.tracer ?? this.trace_api.getTracer("abxbus");
21
+ this.span_factory = options.span_factory;
22
+ this.root_span_name = options.root_span_name;
23
+ this.root_span_attributes = options.root_span_attributes;
12
24
  }
13
25
  onEventChange(eventbus, event, status) {
14
26
  if (status === "started") {
27
+ if (this.span_factory) {
28
+ return;
29
+ }
15
30
  this.startEventSpan(eventbus, event);
16
31
  return;
17
32
  }
@@ -21,11 +36,14 @@ class OtelTracingMiddleware {
21
36
  }
22
37
  onEventResultChange(eventbus, event, event_result, status) {
23
38
  if (status === "started") {
39
+ if (this.span_factory) {
40
+ return;
41
+ }
24
42
  this.startHandlerSpan(eventbus, event, event_result);
25
43
  return;
26
44
  }
27
45
  if (status === "completed") {
28
- this.completeHandlerSpan(event_result);
46
+ this.completeHandlerSpan(eventbus, event, event_result);
29
47
  }
30
48
  }
31
49
  startEventSpan(eventbus, event) {
@@ -33,7 +51,8 @@ class OtelTracingMiddleware {
33
51
  if (existing) {
34
52
  return existing;
35
53
  }
36
- const parent_context = this.parentContextForEvent(event) ?? ROOT_CONTEXT;
54
+ const parent_context = this.parentContextForEvent(event) ?? this.startRootSpan(eventbus, event);
55
+ const start_time = dateFromIso(event.event_started_at);
37
56
  const span = this.tracer.startSpan(
38
57
  `abxbus.event ${event.event_type}`,
39
58
  {
@@ -43,11 +62,12 @@ class OtelTracingMiddleware {
43
62
  "abxbus.event.id": event.event_id,
44
63
  "abxbus.event.type": event.event_type,
45
64
  "abxbus.event.version": event.event_version,
65
+ "abxbus.event.session_id": stringValue(event.session_id),
46
66
  "abxbus.event.parent_id": event.event_parent_id,
47
67
  "abxbus.event.emitted_by_handler_id": event.event_emitted_by_handler_id,
48
68
  "abxbus.event.path": event.event_path.join(" ")
49
69
  }),
50
- startTime: dateFromIso(event.event_started_at)
70
+ startTime: start_time
51
71
  },
52
72
  parent_context
53
73
  );
@@ -57,6 +77,10 @@ class OtelTracingMiddleware {
57
77
  return span;
58
78
  }
59
79
  completeEventSpan(eventbus, event) {
80
+ if (this.span_factory) {
81
+ this.completeEventSpanWithFactory(eventbus, event);
82
+ return;
83
+ }
60
84
  const span = this.event_spans.get(event.event_id) ?? this.startEventSpan(eventbus, event);
61
85
  if (event.event_errors.length > 0) {
62
86
  recordSpanError(span, event.event_errors[0]);
@@ -71,9 +95,12 @@ class OtelTracingMiddleware {
71
95
  "abxbus.event.child_count": event.event_children.length
72
96
  })
73
97
  );
74
- span.end(dateFromIso(event.event_completed_at));
98
+ const start_time = dateFromIso(event.event_started_at);
99
+ const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at));
100
+ span.end(end_time);
75
101
  this.event_spans.delete(event.event_id);
76
102
  this.event_contexts.delete(event.event_id);
103
+ this.completeRootSpan(event.event_id, start_time, end_time);
77
104
  }
78
105
  startHandlerSpan(eventbus, event, event_result) {
79
106
  const existing = this.handler_spans.get(event_result.id);
@@ -104,7 +131,11 @@ class OtelTracingMiddleware {
104
131
  this.handler_contexts.set(handlerSpanKey(event_result.event_id, event_result.handler_id), span_context);
105
132
  return span;
106
133
  }
107
- completeHandlerSpan(event_result) {
134
+ completeHandlerSpan(eventbus, event, event_result) {
135
+ if (this.span_factory) {
136
+ this.completeHandlerSpanWithFactory(eventbus, event, event_result);
137
+ return;
138
+ }
108
139
  const span = this.handler_spans.get(event_result.id);
109
140
  if (!span) {
110
141
  return;
@@ -120,10 +151,48 @@ class OtelTracingMiddleware {
120
151
  "abxbus.handler.child_count": event_result.event_children.length
121
152
  })
122
153
  );
123
- span.end(dateFromIso(event_result.completed_at));
154
+ span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)));
124
155
  this.handler_spans.delete(event_result.id);
125
156
  this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id));
126
157
  }
158
+ startRootSpan(eventbus, event) {
159
+ const existing = this.root_contexts.get(event.event_id);
160
+ if (existing) {
161
+ return existing;
162
+ }
163
+ const session_id = stringValue(event.session_id);
164
+ const root_attributes = resolveAttributes(this.root_span_attributes, eventbus, event);
165
+ const root_span = this.tracer.startSpan(
166
+ resolveRootSpanName(this.root_span_name, eventbus, event),
167
+ {
168
+ attributes: compactAttributes({
169
+ ...root_attributes,
170
+ "abxbus.trace.root": true,
171
+ "abxbus.bus.id": eventbus.id,
172
+ "abxbus.bus.name": eventbus.name,
173
+ "abxbus.root_event.id": event.event_id,
174
+ "abxbus.root_event.type": event.event_type,
175
+ "abxbus.root_event.session_id": session_id
176
+ }),
177
+ startTime: dateFromIso(event.event_started_at)
178
+ },
179
+ ROOT_CONTEXT
180
+ );
181
+ const root_context = this.trace_api.setSpan(ROOT_CONTEXT, root_span);
182
+ this.root_spans.set(event.event_id, root_span);
183
+ this.root_contexts.set(event.event_id, root_context);
184
+ return root_context;
185
+ }
186
+ completeRootSpan(event_id, start_time, end_time) {
187
+ const root_span = this.root_spans.get(event_id);
188
+ if (!root_span) {
189
+ return;
190
+ }
191
+ root_span.setStatus({ code: SpanStatusCode.OK });
192
+ root_span.end(endTimeAfterStart(start_time, end_time));
193
+ this.root_spans.delete(event_id);
194
+ this.root_contexts.delete(event_id);
195
+ }
127
196
  parentContextForEvent(event) {
128
197
  if (event.event_parent_id && event.event_emitted_by_handler_id) {
129
198
  const handler_context = this.handler_contexts.get(handlerSpanKey(event.event_parent_id, event.event_emitted_by_handler_id));
@@ -133,10 +202,167 @@ class OtelTracingMiddleware {
133
202
  }
134
203
  return event.event_parent_id ? this.event_contexts.get(event.event_parent_id) : void 0;
135
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
+ }
136
253
  }
137
254
  function handlerSpanKey(event_id, handler_id) {
138
255
  return `${event_id}:${handler_id}`;
139
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
+ }
140
366
  function dateFromIso(value) {
141
367
  if (value == null) {
142
368
  return void 0;
@@ -144,6 +370,24 @@ function dateFromIso(value) {
144
370
  const date = new Date(value);
145
371
  return Number.isNaN(date.getTime()) ? void 0 : date;
146
372
  }
373
+ function endTimeAfterStart(start_time, end_time) {
374
+ if (!start_time || !end_time) {
375
+ return end_time;
376
+ }
377
+ return end_time.getTime() > start_time.getTime() ? end_time : new Date(start_time.getTime() + 1);
378
+ }
379
+ function resolveRootSpanName(root_span_name, eventbus, event) {
380
+ if (typeof root_span_name === "function") {
381
+ return root_span_name(eventbus, event);
382
+ }
383
+ return root_span_name ?? `abxbus.trace ${eventbus.name}`;
384
+ }
385
+ function resolveAttributes(attributes, eventbus, event) {
386
+ return typeof attributes === "function" ? attributes(eventbus, event) : attributes ?? {};
387
+ }
388
+ function stringValue(value) {
389
+ return typeof value === "string" && value.length > 0 ? value : void 0;
390
+ }
147
391
  function compactAttributes(attributes) {
148
392
  const compacted = {};
149
393
  for (const [key, value] of Object.entries(attributes)) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/middleware_otel_tracing.ts"],
4
- "sourcesContent": ["import { ROOT_CONTEXT, SpanStatusCode, trace, type Context, type Span, type Tracer } 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}\n\nexport class OtelTracingMiddleware implements EventBusMiddleware {\n private readonly tracer: Tracer\n private readonly trace_api: OpenTelemetryTraceApi\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 }\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) ?? ROOT_CONTEXT\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.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: dateFromIso(event.event_started_at),\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 span.end(dateFromIso(event.event_completed_at))\n this.event_spans.delete(event.event_id)\n this.event_contexts.delete(event.event_id)\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(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 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 compactAttributes(\n attributes: Record<string, string | number | boolean | null | undefined>\n): Record<string, string | number | boolean> {\n const compacted: Record<string, string | number | boolean> = {}\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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",
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
  }
@@ -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,17 +1,33 @@
1
- import { trace, 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;
20
+ root_span_name?: string | ((eventbus: EventBus, event: BaseEvent) => string);
21
+ root_span_attributes?: SpanAttributes | ((eventbus: EventBus, event: BaseEvent) => SpanAttributes);
11
22
  };
12
23
  export declare class OtelTracingMiddleware implements EventBusMiddleware {
13
24
  private readonly tracer;
14
25
  private readonly trace_api;
26
+ private readonly span_factory?;
27
+ private readonly root_span_name;
28
+ private readonly root_span_attributes;
29
+ private readonly root_spans;
30
+ private readonly root_contexts;
15
31
  private readonly event_spans;
16
32
  private readonly event_contexts;
17
33
  private readonly handler_spans;
@@ -23,6 +39,10 @@ export declare class OtelTracingMiddleware implements EventBusMiddleware {
23
39
  private completeEventSpan;
24
40
  private startHandlerSpan;
25
41
  private completeHandlerSpan;
42
+ private startRootSpan;
43
+ private completeRootSpan;
26
44
  private parentContextForEvent;
45
+ private completeEventSpanWithFactory;
46
+ private completeHandlerSpanWithFactory;
27
47
  }
28
48
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abxbus",
3
- "version": "2.4.18",
3
+ "version": "2.4.20",
4
4
  "description": "Event bus library for browsers and ESM Node.js",
5
5
  "type": "module",
6
6
  "sideEffects": false,
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,