abxbus 2.4.24 → 2.4.26

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,4 +1,4 @@
1
- import { trace, type Span, type SpanAttributes, type SpanContext, type Tracer } from '@opentelemetry/api';
1
+ import { trace, type Span, type SpanAttributes, type SpanContext, type TimeInput, 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';
@@ -10,7 +10,7 @@ export type OtelTracingSpanFactoryInput = {
10
10
  span_context: SpanContext;
11
11
  parent_span_context?: SpanContext;
12
12
  attributes: SpanAttributes;
13
- start_time?: Date;
13
+ start_time?: TimeInput;
14
14
  };
15
15
  export type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span;
16
16
  export type OtelTracingSpanProvider = object;
@@ -73,7 +73,7 @@ class OtelTracingMiddleware {
73
73
  return existing;
74
74
  }
75
75
  const parent_context = this.parentContextForEvent(event) ?? import_api.ROOT_CONTEXT;
76
- const start_time = dateFromIso(event.event_started_at);
76
+ const start_time = timeInputFromIso(event.event_started_at);
77
77
  const span = this.tracer.startSpan(
78
78
  eventSpanName(eventbus, event),
79
79
  {
@@ -101,8 +101,8 @@ class OtelTracingMiddleware {
101
101
  span.setAttributes(
102
102
  event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)
103
103
  );
104
- const start_time = dateFromIso(event.event_started_at);
105
- const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at));
104
+ const start_time = epochNsFromIso(event.event_started_at);
105
+ const end_time = endTimeAfterStart(start_time, epochNsFromIso(event.event_completed_at));
106
106
  span.end(end_time);
107
107
  this.event_spans.delete(event.event_id);
108
108
  this.event_contexts.delete(event.event_id);
@@ -117,7 +117,7 @@ class OtelTracingMiddleware {
117
117
  handlerSpanName(event, event_result),
118
118
  {
119
119
  attributes: handlerSpanAttributes(eventbus, event, event_result),
120
- startTime: dateFromIso(event_result.started_at)
120
+ startTime: timeInputFromIso(event_result.started_at)
121
121
  },
122
122
  parent_context
123
123
  );
@@ -139,10 +139,8 @@ class OtelTracingMiddleware {
139
139
  } else {
140
140
  span.setStatus({ code: import_api.SpanStatusCode.OK });
141
141
  }
142
- span.setAttributes(
143
- handlerSpanAttributes(eventbus, event, event_result)
144
- );
145
- span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)));
142
+ span.setAttributes(handlerSpanAttributes(eventbus, event, event_result));
143
+ span.end(endTimeAfterStart(epochNsFromIso(event_result.started_at), epochNsFromIso(event_result.completed_at)));
146
144
  this.handler_spans.delete(event_result.id);
147
145
  this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id));
148
146
  }
@@ -169,21 +167,21 @@ class OtelTracingMiddleware {
169
167
  return;
170
168
  }
171
169
  visited_event_ids.add(original_event.event_id);
172
- const start_time = dateFromIso(original_event.event_started_at);
170
+ const start_time = epochNsFromIso(original_event.event_started_at);
173
171
  const span_context = eventSpanContext(trace_id, original_event.event_id);
174
172
  const span = this.span_factory({
175
173
  name: eventSpanName(eventbus, original_event),
176
174
  span_context,
177
175
  parent_span_context,
178
176
  attributes: original_event.event_parent_id ? eventSpanAttributes(eventbus, original_event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),
179
- start_time
177
+ start_time: timeInputFromEpochNs(start_time)
180
178
  });
181
179
  if (original_event.event_errors.length > 0) {
182
180
  recordSpanError(span, original_event.event_errors[0]);
183
181
  } else {
184
182
  span.setStatus({ code: import_api.SpanStatusCode.OK });
185
183
  }
186
- span.end(endTimeAfterStart(start_time, dateFromIso(original_event.event_completed_at)));
184
+ span.end(endTimeAfterStart(start_time, epochNsFromIso(original_event.event_completed_at)));
187
185
  for (const event_result of original_event.event_results.values()) {
188
186
  const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context);
189
187
  for (const child of event_result.event_children) {
@@ -192,21 +190,21 @@ class OtelTracingMiddleware {
192
190
  }
193
191
  }
194
192
  exportHandlerSpanWithFactory(eventbus, event, event_result, trace_id, parent_span_context) {
195
- const start_time = dateFromIso(event_result.started_at);
193
+ const start_time = epochNsFromIso(event_result.started_at);
196
194
  const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id);
197
195
  const span = this.span_factory({
198
196
  name: handlerSpanName(event, event_result),
199
197
  span_context,
200
198
  parent_span_context,
201
199
  attributes: handlerSpanAttributes(eventbus, event, event_result),
202
- start_time
200
+ start_time: timeInputFromEpochNs(start_time)
203
201
  });
204
202
  if (event_result.error !== void 0) {
205
203
  recordSpanError(span, event_result.error);
206
204
  } else {
207
205
  span.setStatus({ code: import_api.SpanStatusCode.OK });
208
206
  }
209
- span.end(endTimeAfterStart(start_time, dateFromIso(event_result.completed_at)));
207
+ span.end(endTimeAfterStart(start_time, epochNsFromIso(event_result.completed_at)));
210
208
  return span_context;
211
209
  }
212
210
  }
@@ -225,10 +223,13 @@ function createOtlpSpanProvider(options) {
225
223
  "service.name": options.service_name ?? "abxbus"
226
224
  }),
227
225
  spanProcessors: [
228
- new import_sdk_trace_base.SimpleSpanProcessor(
226
+ new import_sdk_trace_base.BatchSpanProcessor(
229
227
  new import_exporter_trace_otlp_http.OTLPTraceExporter({
230
228
  url: normalizeOtlpTracesEndpoint(options.otlp_endpoint)
231
- })
229
+ }),
230
+ {
231
+ scheduledDelayMillis: 100
232
+ }
232
233
  )
233
234
  ]
234
235
  });
@@ -342,18 +343,40 @@ function fnv1a64Hex(input) {
342
343
  }
343
344
  return hash.toString(16).padStart(16, "0");
344
345
  }
345
- function dateFromIso(value) {
346
+ const ISO_EPOCH_NS_REGEX = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/;
347
+ const NS_PER_SECOND = 1000000000n;
348
+ const NS_PER_MS = 1000000n;
349
+ function epochNsFromIso(value) {
346
350
  if (value == null) {
347
351
  return void 0;
348
352
  }
349
- const date = new Date(value);
350
- return Number.isNaN(date.getTime()) ? void 0 : date;
353
+ const match = ISO_EPOCH_NS_REGEX.exec(value);
354
+ if (!match) {
355
+ return void 0;
356
+ }
357
+ const [, base, fraction = "", timezone] = match;
358
+ const base_ms = Date.parse(`${base}.000${timezone}`);
359
+ if (Number.isNaN(base_ms)) {
360
+ return void 0;
361
+ }
362
+ return BigInt(base_ms) * NS_PER_MS + BigInt(fraction.padEnd(9, "0"));
363
+ }
364
+ function timeInputFromIso(value) {
365
+ return timeInputFromEpochNs(epochNsFromIso(value));
366
+ }
367
+ function timeInputFromEpochNs(epoch_ns) {
368
+ if (epoch_ns === void 0) {
369
+ return void 0;
370
+ }
371
+ const seconds = epoch_ns / NS_PER_SECOND;
372
+ const nanos = epoch_ns % NS_PER_SECOND;
373
+ return [Number(seconds), Number(nanos)];
351
374
  }
352
375
  function endTimeAfterStart(start_time, end_time) {
353
- if (!start_time || !end_time) {
354
- return end_time;
376
+ if (start_time === void 0 || end_time === void 0) {
377
+ return timeInputFromEpochNs(end_time);
355
378
  }
356
- return end_time.getTime() > start_time.getTime() ? end_time : new Date(start_time.getTime() + 1);
379
+ return timeInputFromEpochNs(end_time > start_time ? end_time : start_time + 1n);
357
380
  }
358
381
  function resolveAttributes(attributes, eventbus, event) {
359
382
  return typeof attributes === "function" ? attributes(eventbus, event) : attributes ?? {};
@@ -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 SpanKind,\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'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport { resourceFromAttributes } from '@opentelemetry/resources'\nimport { BasicTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport type { SpanLimits, SpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport { SpanImpl } from '@opentelemetry/sdk-trace-base/build/src/Span.js'\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'> & Partial<Pick<typeof trace, 'setSpanContext'>>\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\ntype OtelTracingSpanProviderInternals = {\n _activeSpanProcessor?: SpanProcessor\n _config?: {\n resource?: unknown\n spanLimits?: SpanLimits\n }\n _resource?: unknown\n}\n\nexport type OtelTracingSpanProvider = object\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n span_provider?: OtelTracingSpanProvider\n span_factory?: OtelTracingSpanFactory\n otlp_endpoint?: string\n service_name?: string\n instrumentation_name?: 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 span_provider?: OtelTracingSpanProvider\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\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_provider = options.span_provider ?? (options.otlp_endpoint ? createOtlpSpanProvider(options) : undefined)\n this.span_factory =\n options.span_factory ??\n (this.span_provider\n ? createProviderSpanFactory(this.trace_api, this.span_provider, options.instrumentation_name ?? 'abxbus')\n : undefined)\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) ?? ROOT_CONTEXT\n const start_time = dateFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n eventSpanName(eventbus, event),\n {\n attributes: event.event_parent_id ? eventStartedSpanAttributes(eventbus, event) : topLevelEventStartedSpanAttributes(this.root_span_attributes, eventbus, event),\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 event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)\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 }\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 handlerSpanName(event, event_result),\n {\n attributes: handlerSpanAttributes(eventbus, event, event_result),\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 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 handlerSpanAttributes(eventbus, event, event_result)\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 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 if (event.event_parent_id) {\n return\n }\n\n const top_level_event = event._event_original ?? event\n const trace_id = traceIdForRootEvent(top_level_event.event_id)\n this.exportEventTreeWithFactory(eventbus, top_level_event, trace_id, undefined, new Set<string>())\n }\n\n private exportEventTreeWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n trace_id: string,\n parent_span_context: SpanContext | undefined,\n visited_event_ids: Set<string>\n ): void {\n const original_event = event._event_original ?? event\n if (visited_event_ids.has(original_event.event_id)) {\n return\n }\n visited_event_ids.add(original_event.event_id)\n\n const start_time = dateFromIso(original_event.event_started_at)\n const span_context = eventSpanContext(trace_id, original_event.event_id)\n const span = this.span_factory!({\n name: eventSpanName(eventbus, original_event),\n span_context,\n parent_span_context,\n attributes: original_event.event_parent_id\n ? eventSpanAttributes(eventbus, original_event)\n : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),\n start_time,\n })\n if (original_event.event_errors.length > 0) {\n recordSpanError(span, original_event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(endTimeAfterStart(start_time, dateFromIso(original_event.event_completed_at)))\n\n for (const event_result of original_event.event_results.values()) {\n const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context)\n for (const child of event_result.event_children) {\n this.exportEventTreeWithFactory(eventbus, child, trace_id, handler_context, visited_event_ids)\n }\n }\n }\n\n private exportHandlerSpanWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n event_result: EventResult,\n trace_id: string,\n parent_span_context: SpanContext\n ): SpanContext {\n const start_time = dateFromIso(event_result.started_at)\n const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id)\n const span = this.span_factory!({\n name: handlerSpanName(event, event_result),\n span_context,\n parent_span_context,\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n start_time,\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 return span_context\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction eventSpanName(eventbus: EventBus, event: BaseEvent): string {\n return `${eventbus.name}.emit(${event.event_type})`\n}\n\nfunction handlerSpanName(event: BaseEvent, event_result: EventResult): string {\n return `${event_result.handler_name}(${event.event_type})`\n}\n\nfunction createOtlpSpanProvider(options: OtelTracingMiddlewareOptions): OtelTracingSpanProvider {\n return new BasicTracerProvider({\n resource: resourceFromAttributes({\n 'service.name': options.service_name ?? 'abxbus',\n }),\n spanProcessors: [\n new SimpleSpanProcessor(\n new OTLPTraceExporter({\n url: normalizeOtlpTracesEndpoint(options.otlp_endpoint!),\n })\n ),\n ],\n })\n}\n\nfunction createProviderSpanFactory(\n trace_api: OpenTelemetryTraceApi,\n provider: OtelTracingSpanProvider,\n instrumentation_name: string\n): OtelTracingSpanFactory {\n const provider_internals = provider as OtelTracingSpanProviderInternals\n return (input: OtelTracingSpanFactoryInput): Span => {\n const span_processor = provider_internals._activeSpanProcessor\n const span_limits = provider_internals._config?.spanLimits\n const resource = provider_internals._resource ?? provider_internals._config?.resource\n if (!span_processor || !span_limits || !resource) {\n throw new Error('OtelTracingMiddleware span_provider must be an OpenTelemetry SDK trace provider with active span internals')\n }\n\n const parent_context = input.parent_span_context\n ? (trace_api.setSpanContext ?? trace.setSpanContext)(ROOT_CONTEXT, input.parent_span_context)\n : ROOT_CONTEXT\n return new SpanImpl({\n resource,\n scope: { name: instrumentation_name },\n context: parent_context,\n spanContext: input.span_context,\n parentSpanContext: input.parent_span_context,\n name: input.name,\n kind: SpanKind.INTERNAL,\n attributes: input.attributes,\n startTime: input.start_time,\n spanProcessor: span_processor,\n spanLimits: span_limits,\n } as ConstructorParameters<typeof SpanImpl>[0])\n }\n}\n\nfunction normalizeOtlpTracesEndpoint(endpoint: string): string {\n const trimmed = endpoint.replace(/\\/+$/, '')\n return trimmed.endsWith('/v1/traces') ? trimmed : `${trimmed}/v1/traces`\n}\n\nfunction eventStartedSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_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.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}\n\nfunction eventSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n 'abxbus.event_status': event.event_status,\n })\n}\n\nfunction handlerSpanAttributes(eventbus: EventBus, event: BaseEvent, event_result: EventResult): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_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 })\n}\n\nfunction topLevelEventStartedSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\n })\n}\n\nfunction topLevelEventSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\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 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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",
4
+ "sourcesContent": ["import {\n ROOT_CONTEXT,\n SpanKind,\n SpanStatusCode,\n trace,\n type Context,\n type Span,\n type SpanAttributeValue,\n type SpanAttributes,\n type SpanContext,\n type TimeInput,\n type Tracer,\n} from '@opentelemetry/api'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport { resourceFromAttributes } from '@opentelemetry/resources'\nimport { BasicTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport type { SpanLimits, SpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport { SpanImpl } from '@opentelemetry/sdk-trace-base/build/src/Span.js'\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'> & Partial<Pick<typeof trace, 'setSpanContext'>>\n\nexport type OtelTracingSpanFactoryInput = {\n name: string\n span_context: SpanContext\n parent_span_context?: SpanContext\n attributes: SpanAttributes\n start_time?: TimeInput\n}\n\nexport type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span\n\ntype OtelTracingSpanProviderInternals = {\n _activeSpanProcessor?: SpanProcessor\n _config?: {\n resource?: unknown\n spanLimits?: SpanLimits\n }\n _resource?: unknown\n}\n\nexport type OtelTracingSpanProvider = object\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n span_provider?: OtelTracingSpanProvider\n span_factory?: OtelTracingSpanFactory\n otlp_endpoint?: string\n service_name?: string\n instrumentation_name?: 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 span_provider?: OtelTracingSpanProvider\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\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_provider = options.span_provider ?? (options.otlp_endpoint ? createOtlpSpanProvider(options) : undefined)\n this.span_factory =\n options.span_factory ??\n (this.span_provider\n ? createProviderSpanFactory(this.trace_api, this.span_provider, options.instrumentation_name ?? 'abxbus')\n : undefined)\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) ?? ROOT_CONTEXT\n const start_time = timeInputFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n eventSpanName(eventbus, event),\n {\n attributes: event.event_parent_id\n ? eventStartedSpanAttributes(eventbus, event)\n : topLevelEventStartedSpanAttributes(this.root_span_attributes, eventbus, event),\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 event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)\n )\n const start_time = epochNsFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, epochNsFromIso(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 }\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 handlerSpanName(event, event_result),\n {\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n startTime: timeInputFromIso(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 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(handlerSpanAttributes(eventbus, event, event_result))\n span.end(endTimeAfterStart(epochNsFromIso(event_result.started_at), epochNsFromIso(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 private completeEventSpanWithFactory(eventbus: EventBus, event: BaseEvent): void {\n if (event.event_parent_id) {\n return\n }\n\n const top_level_event = event._event_original ?? event\n const trace_id = traceIdForRootEvent(top_level_event.event_id)\n this.exportEventTreeWithFactory(eventbus, top_level_event, trace_id, undefined, new Set<string>())\n }\n\n private exportEventTreeWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n trace_id: string,\n parent_span_context: SpanContext | undefined,\n visited_event_ids: Set<string>\n ): void {\n const original_event = event._event_original ?? event\n if (visited_event_ids.has(original_event.event_id)) {\n return\n }\n visited_event_ids.add(original_event.event_id)\n\n const start_time = epochNsFromIso(original_event.event_started_at)\n const span_context = eventSpanContext(trace_id, original_event.event_id)\n const span = this.span_factory!({\n name: eventSpanName(eventbus, original_event),\n span_context,\n parent_span_context,\n attributes: original_event.event_parent_id\n ? eventSpanAttributes(eventbus, original_event)\n : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),\n start_time: timeInputFromEpochNs(start_time),\n })\n if (original_event.event_errors.length > 0) {\n recordSpanError(span, original_event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(endTimeAfterStart(start_time, epochNsFromIso(original_event.event_completed_at)))\n\n for (const event_result of original_event.event_results.values()) {\n const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context)\n for (const child of event_result.event_children) {\n this.exportEventTreeWithFactory(eventbus, child, trace_id, handler_context, visited_event_ids)\n }\n }\n }\n\n private exportHandlerSpanWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n event_result: EventResult,\n trace_id: string,\n parent_span_context: SpanContext\n ): SpanContext {\n const start_time = epochNsFromIso(event_result.started_at)\n const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id)\n const span = this.span_factory!({\n name: handlerSpanName(event, event_result),\n span_context,\n parent_span_context,\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n start_time: timeInputFromEpochNs(start_time),\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, epochNsFromIso(event_result.completed_at)))\n return span_context\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction eventSpanName(eventbus: EventBus, event: BaseEvent): string {\n return `${eventbus.name}.emit(${event.event_type})`\n}\n\nfunction handlerSpanName(event: BaseEvent, event_result: EventResult): string {\n return `${event_result.handler_name}(${event.event_type})`\n}\n\nfunction createOtlpSpanProvider(options: OtelTracingMiddlewareOptions): OtelTracingSpanProvider {\n return new BasicTracerProvider({\n resource: resourceFromAttributes({\n 'service.name': options.service_name ?? 'abxbus',\n }),\n spanProcessors: [\n new BatchSpanProcessor(\n new OTLPTraceExporter({\n url: normalizeOtlpTracesEndpoint(options.otlp_endpoint!),\n }),\n {\n scheduledDelayMillis: 100,\n }\n ),\n ],\n })\n}\n\nfunction createProviderSpanFactory(\n trace_api: OpenTelemetryTraceApi,\n provider: OtelTracingSpanProvider,\n instrumentation_name: string\n): OtelTracingSpanFactory {\n const provider_internals = provider as OtelTracingSpanProviderInternals\n return (input: OtelTracingSpanFactoryInput): Span => {\n const span_processor = provider_internals._activeSpanProcessor\n const span_limits = provider_internals._config?.spanLimits\n const resource = provider_internals._resource ?? provider_internals._config?.resource\n if (!span_processor || !span_limits || !resource) {\n throw new Error('OtelTracingMiddleware span_provider must be an OpenTelemetry SDK trace provider with active span internals')\n }\n\n const parent_context = input.parent_span_context\n ? (trace_api.setSpanContext ?? trace.setSpanContext)(ROOT_CONTEXT, input.parent_span_context)\n : ROOT_CONTEXT\n return new SpanImpl({\n resource,\n scope: { name: instrumentation_name },\n context: parent_context,\n spanContext: input.span_context,\n parentSpanContext: input.parent_span_context,\n name: input.name,\n kind: SpanKind.INTERNAL,\n attributes: input.attributes,\n startTime: input.start_time,\n spanProcessor: span_processor,\n spanLimits: span_limits,\n } as ConstructorParameters<typeof SpanImpl>[0])\n }\n}\n\nfunction normalizeOtlpTracesEndpoint(endpoint: string): string {\n const trimmed = endpoint.replace(/\\/+$/, '')\n return trimmed.endsWith('/v1/traces') ? trimmed : `${trimmed}/v1/traces`\n}\n\nfunction eventStartedSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_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.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}\n\nfunction eventSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n 'abxbus.event_status': event.event_status,\n })\n}\n\nfunction handlerSpanAttributes(eventbus: EventBus, event: BaseEvent, event_result: EventResult): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_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 })\n}\n\nfunction topLevelEventStartedSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\n })\n}\n\nfunction topLevelEventSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\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\nconst ISO_EPOCH_NS_REGEX = /^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})(?:\\.(\\d{1,9}))?(Z|[+-]\\d{2}:\\d{2})$/\nconst NS_PER_SECOND = 1_000_000_000n\nconst NS_PER_MS = 1_000_000n\n\nfunction epochNsFromIso(value: string | null | undefined): bigint | undefined {\n if (value == null) {\n return undefined\n }\n const match = ISO_EPOCH_NS_REGEX.exec(value)\n if (!match) {\n return undefined\n }\n const [, base, fraction = '', timezone] = match\n const base_ms = Date.parse(`${base}.000${timezone}`)\n if (Number.isNaN(base_ms)) {\n return undefined\n }\n return BigInt(base_ms) * NS_PER_MS + BigInt(fraction.padEnd(9, '0'))\n}\n\nfunction timeInputFromIso(value: string | null | undefined): TimeInput | undefined {\n return timeInputFromEpochNs(epochNsFromIso(value))\n}\n\nfunction timeInputFromEpochNs(epoch_ns: bigint | undefined): TimeInput | undefined {\n if (epoch_ns === undefined) {\n return undefined\n }\n const seconds = epoch_ns / NS_PER_SECOND\n const nanos = epoch_ns % NS_PER_SECOND\n return [Number(seconds), Number(nanos)]\n}\n\nfunction endTimeAfterStart(start_time: bigint | undefined, end_time: bigint | undefined): TimeInput | undefined {\n if (start_time === undefined || end_time === undefined) {\n return timeInputFromEpochNs(end_time)\n }\n\n return timeInputFromEpochNs(end_time > start_time ? end_time : start_time + 1n)\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
  }
@@ -6,7 +6,7 @@ import {
6
6
  } from "@opentelemetry/api";
7
7
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
8
8
  import { resourceFromAttributes } from "@opentelemetry/resources";
9
- import { BasicTracerProvider, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
9
+ import { BasicTracerProvider, BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
10
10
  import { SpanImpl } from "@opentelemetry/sdk-trace-base/build/src/Span.js";
11
11
  class OtelTracingMiddleware {
12
12
  tracer;
@@ -55,7 +55,7 @@ class OtelTracingMiddleware {
55
55
  return existing;
56
56
  }
57
57
  const parent_context = this.parentContextForEvent(event) ?? ROOT_CONTEXT;
58
- const start_time = dateFromIso(event.event_started_at);
58
+ const start_time = timeInputFromIso(event.event_started_at);
59
59
  const span = this.tracer.startSpan(
60
60
  eventSpanName(eventbus, event),
61
61
  {
@@ -83,8 +83,8 @@ class OtelTracingMiddleware {
83
83
  span.setAttributes(
84
84
  event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)
85
85
  );
86
- const start_time = dateFromIso(event.event_started_at);
87
- const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at));
86
+ const start_time = epochNsFromIso(event.event_started_at);
87
+ const end_time = endTimeAfterStart(start_time, epochNsFromIso(event.event_completed_at));
88
88
  span.end(end_time);
89
89
  this.event_spans.delete(event.event_id);
90
90
  this.event_contexts.delete(event.event_id);
@@ -99,7 +99,7 @@ class OtelTracingMiddleware {
99
99
  handlerSpanName(event, event_result),
100
100
  {
101
101
  attributes: handlerSpanAttributes(eventbus, event, event_result),
102
- startTime: dateFromIso(event_result.started_at)
102
+ startTime: timeInputFromIso(event_result.started_at)
103
103
  },
104
104
  parent_context
105
105
  );
@@ -121,10 +121,8 @@ class OtelTracingMiddleware {
121
121
  } else {
122
122
  span.setStatus({ code: SpanStatusCode.OK });
123
123
  }
124
- span.setAttributes(
125
- handlerSpanAttributes(eventbus, event, event_result)
126
- );
127
- span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)));
124
+ span.setAttributes(handlerSpanAttributes(eventbus, event, event_result));
125
+ span.end(endTimeAfterStart(epochNsFromIso(event_result.started_at), epochNsFromIso(event_result.completed_at)));
128
126
  this.handler_spans.delete(event_result.id);
129
127
  this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id));
130
128
  }
@@ -151,21 +149,21 @@ class OtelTracingMiddleware {
151
149
  return;
152
150
  }
153
151
  visited_event_ids.add(original_event.event_id);
154
- const start_time = dateFromIso(original_event.event_started_at);
152
+ const start_time = epochNsFromIso(original_event.event_started_at);
155
153
  const span_context = eventSpanContext(trace_id, original_event.event_id);
156
154
  const span = this.span_factory({
157
155
  name: eventSpanName(eventbus, original_event),
158
156
  span_context,
159
157
  parent_span_context,
160
158
  attributes: original_event.event_parent_id ? eventSpanAttributes(eventbus, original_event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),
161
- start_time
159
+ start_time: timeInputFromEpochNs(start_time)
162
160
  });
163
161
  if (original_event.event_errors.length > 0) {
164
162
  recordSpanError(span, original_event.event_errors[0]);
165
163
  } else {
166
164
  span.setStatus({ code: SpanStatusCode.OK });
167
165
  }
168
- span.end(endTimeAfterStart(start_time, dateFromIso(original_event.event_completed_at)));
166
+ span.end(endTimeAfterStart(start_time, epochNsFromIso(original_event.event_completed_at)));
169
167
  for (const event_result of original_event.event_results.values()) {
170
168
  const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context);
171
169
  for (const child of event_result.event_children) {
@@ -174,21 +172,21 @@ class OtelTracingMiddleware {
174
172
  }
175
173
  }
176
174
  exportHandlerSpanWithFactory(eventbus, event, event_result, trace_id, parent_span_context) {
177
- const start_time = dateFromIso(event_result.started_at);
175
+ const start_time = epochNsFromIso(event_result.started_at);
178
176
  const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id);
179
177
  const span = this.span_factory({
180
178
  name: handlerSpanName(event, event_result),
181
179
  span_context,
182
180
  parent_span_context,
183
181
  attributes: handlerSpanAttributes(eventbus, event, event_result),
184
- start_time
182
+ start_time: timeInputFromEpochNs(start_time)
185
183
  });
186
184
  if (event_result.error !== void 0) {
187
185
  recordSpanError(span, event_result.error);
188
186
  } else {
189
187
  span.setStatus({ code: SpanStatusCode.OK });
190
188
  }
191
- span.end(endTimeAfterStart(start_time, dateFromIso(event_result.completed_at)));
189
+ span.end(endTimeAfterStart(start_time, epochNsFromIso(event_result.completed_at)));
192
190
  return span_context;
193
191
  }
194
192
  }
@@ -207,10 +205,13 @@ function createOtlpSpanProvider(options) {
207
205
  "service.name": options.service_name ?? "abxbus"
208
206
  }),
209
207
  spanProcessors: [
210
- new SimpleSpanProcessor(
208
+ new BatchSpanProcessor(
211
209
  new OTLPTraceExporter({
212
210
  url: normalizeOtlpTracesEndpoint(options.otlp_endpoint)
213
- })
211
+ }),
212
+ {
213
+ scheduledDelayMillis: 100
214
+ }
214
215
  )
215
216
  ]
216
217
  });
@@ -324,18 +325,40 @@ function fnv1a64Hex(input) {
324
325
  }
325
326
  return hash.toString(16).padStart(16, "0");
326
327
  }
327
- function dateFromIso(value) {
328
+ const ISO_EPOCH_NS_REGEX = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/;
329
+ const NS_PER_SECOND = 1000000000n;
330
+ const NS_PER_MS = 1000000n;
331
+ function epochNsFromIso(value) {
328
332
  if (value == null) {
329
333
  return void 0;
330
334
  }
331
- const date = new Date(value);
332
- return Number.isNaN(date.getTime()) ? void 0 : date;
335
+ const match = ISO_EPOCH_NS_REGEX.exec(value);
336
+ if (!match) {
337
+ return void 0;
338
+ }
339
+ const [, base, fraction = "", timezone] = match;
340
+ const base_ms = Date.parse(`${base}.000${timezone}`);
341
+ if (Number.isNaN(base_ms)) {
342
+ return void 0;
343
+ }
344
+ return BigInt(base_ms) * NS_PER_MS + BigInt(fraction.padEnd(9, "0"));
345
+ }
346
+ function timeInputFromIso(value) {
347
+ return timeInputFromEpochNs(epochNsFromIso(value));
348
+ }
349
+ function timeInputFromEpochNs(epoch_ns) {
350
+ if (epoch_ns === void 0) {
351
+ return void 0;
352
+ }
353
+ const seconds = epoch_ns / NS_PER_SECOND;
354
+ const nanos = epoch_ns % NS_PER_SECOND;
355
+ return [Number(seconds), Number(nanos)];
333
356
  }
334
357
  function endTimeAfterStart(start_time, end_time) {
335
- if (!start_time || !end_time) {
336
- return end_time;
358
+ if (start_time === void 0 || end_time === void 0) {
359
+ return timeInputFromEpochNs(end_time);
337
360
  }
338
- return end_time.getTime() > start_time.getTime() ? end_time : new Date(start_time.getTime() + 1);
361
+ return timeInputFromEpochNs(end_time > start_time ? end_time : start_time + 1n);
339
362
  }
340
363
  function resolveAttributes(attributes, eventbus, event) {
341
364
  return typeof attributes === "function" ? attributes(eventbus, event) : attributes ?? {};
@@ -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 SpanKind,\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'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport { resourceFromAttributes } from '@opentelemetry/resources'\nimport { BasicTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport type { SpanLimits, SpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport { SpanImpl } from '@opentelemetry/sdk-trace-base/build/src/Span.js'\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'> & Partial<Pick<typeof trace, 'setSpanContext'>>\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\ntype OtelTracingSpanProviderInternals = {\n _activeSpanProcessor?: SpanProcessor\n _config?: {\n resource?: unknown\n spanLimits?: SpanLimits\n }\n _resource?: unknown\n}\n\nexport type OtelTracingSpanProvider = object\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n span_provider?: OtelTracingSpanProvider\n span_factory?: OtelTracingSpanFactory\n otlp_endpoint?: string\n service_name?: string\n instrumentation_name?: 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 span_provider?: OtelTracingSpanProvider\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\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_provider = options.span_provider ?? (options.otlp_endpoint ? createOtlpSpanProvider(options) : undefined)\n this.span_factory =\n options.span_factory ??\n (this.span_provider\n ? createProviderSpanFactory(this.trace_api, this.span_provider, options.instrumentation_name ?? 'abxbus')\n : undefined)\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) ?? ROOT_CONTEXT\n const start_time = dateFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n eventSpanName(eventbus, event),\n {\n attributes: event.event_parent_id ? eventStartedSpanAttributes(eventbus, event) : topLevelEventStartedSpanAttributes(this.root_span_attributes, eventbus, event),\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 event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)\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 }\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 handlerSpanName(event, event_result),\n {\n attributes: handlerSpanAttributes(eventbus, event, event_result),\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 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 handlerSpanAttributes(eventbus, event, event_result)\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 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 if (event.event_parent_id) {\n return\n }\n\n const top_level_event = event._event_original ?? event\n const trace_id = traceIdForRootEvent(top_level_event.event_id)\n this.exportEventTreeWithFactory(eventbus, top_level_event, trace_id, undefined, new Set<string>())\n }\n\n private exportEventTreeWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n trace_id: string,\n parent_span_context: SpanContext | undefined,\n visited_event_ids: Set<string>\n ): void {\n const original_event = event._event_original ?? event\n if (visited_event_ids.has(original_event.event_id)) {\n return\n }\n visited_event_ids.add(original_event.event_id)\n\n const start_time = dateFromIso(original_event.event_started_at)\n const span_context = eventSpanContext(trace_id, original_event.event_id)\n const span = this.span_factory!({\n name: eventSpanName(eventbus, original_event),\n span_context,\n parent_span_context,\n attributes: original_event.event_parent_id\n ? eventSpanAttributes(eventbus, original_event)\n : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),\n start_time,\n })\n if (original_event.event_errors.length > 0) {\n recordSpanError(span, original_event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(endTimeAfterStart(start_time, dateFromIso(original_event.event_completed_at)))\n\n for (const event_result of original_event.event_results.values()) {\n const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context)\n for (const child of event_result.event_children) {\n this.exportEventTreeWithFactory(eventbus, child, trace_id, handler_context, visited_event_ids)\n }\n }\n }\n\n private exportHandlerSpanWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n event_result: EventResult,\n trace_id: string,\n parent_span_context: SpanContext\n ): SpanContext {\n const start_time = dateFromIso(event_result.started_at)\n const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id)\n const span = this.span_factory!({\n name: handlerSpanName(event, event_result),\n span_context,\n parent_span_context,\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n start_time,\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 return span_context\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction eventSpanName(eventbus: EventBus, event: BaseEvent): string {\n return `${eventbus.name}.emit(${event.event_type})`\n}\n\nfunction handlerSpanName(event: BaseEvent, event_result: EventResult): string {\n return `${event_result.handler_name}(${event.event_type})`\n}\n\nfunction createOtlpSpanProvider(options: OtelTracingMiddlewareOptions): OtelTracingSpanProvider {\n return new BasicTracerProvider({\n resource: resourceFromAttributes({\n 'service.name': options.service_name ?? 'abxbus',\n }),\n spanProcessors: [\n new SimpleSpanProcessor(\n new OTLPTraceExporter({\n url: normalizeOtlpTracesEndpoint(options.otlp_endpoint!),\n })\n ),\n ],\n })\n}\n\nfunction createProviderSpanFactory(\n trace_api: OpenTelemetryTraceApi,\n provider: OtelTracingSpanProvider,\n instrumentation_name: string\n): OtelTracingSpanFactory {\n const provider_internals = provider as OtelTracingSpanProviderInternals\n return (input: OtelTracingSpanFactoryInput): Span => {\n const span_processor = provider_internals._activeSpanProcessor\n const span_limits = provider_internals._config?.spanLimits\n const resource = provider_internals._resource ?? provider_internals._config?.resource\n if (!span_processor || !span_limits || !resource) {\n throw new Error('OtelTracingMiddleware span_provider must be an OpenTelemetry SDK trace provider with active span internals')\n }\n\n const parent_context = input.parent_span_context\n ? (trace_api.setSpanContext ?? trace.setSpanContext)(ROOT_CONTEXT, input.parent_span_context)\n : ROOT_CONTEXT\n return new SpanImpl({\n resource,\n scope: { name: instrumentation_name },\n context: parent_context,\n spanContext: input.span_context,\n parentSpanContext: input.parent_span_context,\n name: input.name,\n kind: SpanKind.INTERNAL,\n attributes: input.attributes,\n startTime: input.start_time,\n spanProcessor: span_processor,\n spanLimits: span_limits,\n } as ConstructorParameters<typeof SpanImpl>[0])\n }\n}\n\nfunction normalizeOtlpTracesEndpoint(endpoint: string): string {\n const trimmed = endpoint.replace(/\\/+$/, '')\n return trimmed.endsWith('/v1/traces') ? trimmed : `${trimmed}/v1/traces`\n}\n\nfunction eventStartedSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_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.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}\n\nfunction eventSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n 'abxbus.event_status': event.event_status,\n })\n}\n\nfunction handlerSpanAttributes(eventbus: EventBus, event: BaseEvent, event_result: EventResult): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_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 })\n}\n\nfunction topLevelEventStartedSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\n })\n}\n\nfunction topLevelEventSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\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 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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",
4
+ "sourcesContent": ["import {\n ROOT_CONTEXT,\n SpanKind,\n SpanStatusCode,\n trace,\n type Context,\n type Span,\n type SpanAttributeValue,\n type SpanAttributes,\n type SpanContext,\n type TimeInput,\n type Tracer,\n} from '@opentelemetry/api'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport { resourceFromAttributes } from '@opentelemetry/resources'\nimport { BasicTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport type { SpanLimits, SpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport { SpanImpl } from '@opentelemetry/sdk-trace-base/build/src/Span.js'\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'> & Partial<Pick<typeof trace, 'setSpanContext'>>\n\nexport type OtelTracingSpanFactoryInput = {\n name: string\n span_context: SpanContext\n parent_span_context?: SpanContext\n attributes: SpanAttributes\n start_time?: TimeInput\n}\n\nexport type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span\n\ntype OtelTracingSpanProviderInternals = {\n _activeSpanProcessor?: SpanProcessor\n _config?: {\n resource?: unknown\n spanLimits?: SpanLimits\n }\n _resource?: unknown\n}\n\nexport type OtelTracingSpanProvider = object\n\nexport type OtelTracingMiddlewareOptions = {\n tracer?: Tracer\n trace_api?: OpenTelemetryTraceApi\n span_provider?: OtelTracingSpanProvider\n span_factory?: OtelTracingSpanFactory\n otlp_endpoint?: string\n service_name?: string\n instrumentation_name?: 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 span_provider?: OtelTracingSpanProvider\n private readonly root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes']\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_provider = options.span_provider ?? (options.otlp_endpoint ? createOtlpSpanProvider(options) : undefined)\n this.span_factory =\n options.span_factory ??\n (this.span_provider\n ? createProviderSpanFactory(this.trace_api, this.span_provider, options.instrumentation_name ?? 'abxbus')\n : undefined)\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) ?? ROOT_CONTEXT\n const start_time = timeInputFromIso(event.event_started_at)\n const span = this.tracer.startSpan(\n eventSpanName(eventbus, event),\n {\n attributes: event.event_parent_id\n ? eventStartedSpanAttributes(eventbus, event)\n : topLevelEventStartedSpanAttributes(this.root_span_attributes, eventbus, event),\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 event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)\n )\n const start_time = epochNsFromIso(event.event_started_at)\n const end_time = endTimeAfterStart(start_time, epochNsFromIso(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 }\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 handlerSpanName(event, event_result),\n {\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n startTime: timeInputFromIso(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 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(handlerSpanAttributes(eventbus, event, event_result))\n span.end(endTimeAfterStart(epochNsFromIso(event_result.started_at), epochNsFromIso(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 private completeEventSpanWithFactory(eventbus: EventBus, event: BaseEvent): void {\n if (event.event_parent_id) {\n return\n }\n\n const top_level_event = event._event_original ?? event\n const trace_id = traceIdForRootEvent(top_level_event.event_id)\n this.exportEventTreeWithFactory(eventbus, top_level_event, trace_id, undefined, new Set<string>())\n }\n\n private exportEventTreeWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n trace_id: string,\n parent_span_context: SpanContext | undefined,\n visited_event_ids: Set<string>\n ): void {\n const original_event = event._event_original ?? event\n if (visited_event_ids.has(original_event.event_id)) {\n return\n }\n visited_event_ids.add(original_event.event_id)\n\n const start_time = epochNsFromIso(original_event.event_started_at)\n const span_context = eventSpanContext(trace_id, original_event.event_id)\n const span = this.span_factory!({\n name: eventSpanName(eventbus, original_event),\n span_context,\n parent_span_context,\n attributes: original_event.event_parent_id\n ? eventSpanAttributes(eventbus, original_event)\n : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),\n start_time: timeInputFromEpochNs(start_time),\n })\n if (original_event.event_errors.length > 0) {\n recordSpanError(span, original_event.event_errors[0])\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n span.end(endTimeAfterStart(start_time, epochNsFromIso(original_event.event_completed_at)))\n\n for (const event_result of original_event.event_results.values()) {\n const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context)\n for (const child of event_result.event_children) {\n this.exportEventTreeWithFactory(eventbus, child, trace_id, handler_context, visited_event_ids)\n }\n }\n }\n\n private exportHandlerSpanWithFactory(\n eventbus: EventBus,\n event: BaseEvent,\n event_result: EventResult,\n trace_id: string,\n parent_span_context: SpanContext\n ): SpanContext {\n const start_time = epochNsFromIso(event_result.started_at)\n const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id)\n const span = this.span_factory!({\n name: handlerSpanName(event, event_result),\n span_context,\n parent_span_context,\n attributes: handlerSpanAttributes(eventbus, event, event_result),\n start_time: timeInputFromEpochNs(start_time),\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, epochNsFromIso(event_result.completed_at)))\n return span_context\n }\n}\n\nfunction handlerSpanKey(event_id: string, handler_id: string): string {\n return `${event_id}:${handler_id}`\n}\n\nfunction eventSpanName(eventbus: EventBus, event: BaseEvent): string {\n return `${eventbus.name}.emit(${event.event_type})`\n}\n\nfunction handlerSpanName(event: BaseEvent, event_result: EventResult): string {\n return `${event_result.handler_name}(${event.event_type})`\n}\n\nfunction createOtlpSpanProvider(options: OtelTracingMiddlewareOptions): OtelTracingSpanProvider {\n return new BasicTracerProvider({\n resource: resourceFromAttributes({\n 'service.name': options.service_name ?? 'abxbus',\n }),\n spanProcessors: [\n new BatchSpanProcessor(\n new OTLPTraceExporter({\n url: normalizeOtlpTracesEndpoint(options.otlp_endpoint!),\n }),\n {\n scheduledDelayMillis: 100,\n }\n ),\n ],\n })\n}\n\nfunction createProviderSpanFactory(\n trace_api: OpenTelemetryTraceApi,\n provider: OtelTracingSpanProvider,\n instrumentation_name: string\n): OtelTracingSpanFactory {\n const provider_internals = provider as OtelTracingSpanProviderInternals\n return (input: OtelTracingSpanFactoryInput): Span => {\n const span_processor = provider_internals._activeSpanProcessor\n const span_limits = provider_internals._config?.spanLimits\n const resource = provider_internals._resource ?? provider_internals._config?.resource\n if (!span_processor || !span_limits || !resource) {\n throw new Error('OtelTracingMiddleware span_provider must be an OpenTelemetry SDK trace provider with active span internals')\n }\n\n const parent_context = input.parent_span_context\n ? (trace_api.setSpanContext ?? trace.setSpanContext)(ROOT_CONTEXT, input.parent_span_context)\n : ROOT_CONTEXT\n return new SpanImpl({\n resource,\n scope: { name: instrumentation_name },\n context: parent_context,\n spanContext: input.span_context,\n parentSpanContext: input.parent_span_context,\n name: input.name,\n kind: SpanKind.INTERNAL,\n attributes: input.attributes,\n startTime: input.start_time,\n spanProcessor: span_processor,\n spanLimits: span_limits,\n } as ConstructorParameters<typeof SpanImpl>[0])\n }\n}\n\nfunction normalizeOtlpTracesEndpoint(endpoint: string): string {\n const trimmed = endpoint.replace(/\\/+$/, '')\n return trimmed.endsWith('/v1/traces') ? trimmed : `${trimmed}/v1/traces`\n}\n\nfunction eventStartedSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_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.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}\n\nfunction eventSpanAttributes(eventbus: EventBus, event: BaseEvent): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n 'abxbus.event_status': event.event_status,\n })\n}\n\nfunction handlerSpanAttributes(eventbus: EventBus, event: BaseEvent, event_result: EventResult): SpanAttributes {\n return compactAttributes({\n 'abxbus.event_bus.id': eventbus.id,\n 'abxbus.event_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 })\n}\n\nfunction topLevelEventStartedSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventStartedSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\n })\n}\n\nfunction topLevelEventSpanAttributes(\n root_span_attributes: OtelTracingMiddlewareOptions['root_span_attributes'],\n eventbus: EventBus,\n event: BaseEvent\n): SpanAttributes {\n return compactAttributes({\n ...eventSpanAttributes(eventbus, event),\n ...resolveAttributes(root_span_attributes, eventbus, event),\n 'abxbus.trace.root': true,\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\nconst ISO_EPOCH_NS_REGEX = /^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})(?:\\.(\\d{1,9}))?(Z|[+-]\\d{2}:\\d{2})$/\nconst NS_PER_SECOND = 1_000_000_000n\nconst NS_PER_MS = 1_000_000n\n\nfunction epochNsFromIso(value: string | null | undefined): bigint | undefined {\n if (value == null) {\n return undefined\n }\n const match = ISO_EPOCH_NS_REGEX.exec(value)\n if (!match) {\n return undefined\n }\n const [, base, fraction = '', timezone] = match\n const base_ms = Date.parse(`${base}.000${timezone}`)\n if (Number.isNaN(base_ms)) {\n return undefined\n }\n return BigInt(base_ms) * NS_PER_MS + BigInt(fraction.padEnd(9, '0'))\n}\n\nfunction timeInputFromIso(value: string | null | undefined): TimeInput | undefined {\n return timeInputFromEpochNs(epochNsFromIso(value))\n}\n\nfunction timeInputFromEpochNs(epoch_ns: bigint | undefined): TimeInput | undefined {\n if (epoch_ns === undefined) {\n return undefined\n }\n const seconds = epoch_ns / NS_PER_SECOND\n const nanos = epoch_ns % NS_PER_SECOND\n return [Number(seconds), Number(nanos)]\n}\n\nfunction endTimeAfterStart(start_time: bigint | undefined, end_time: bigint | undefined): TimeInput | undefined {\n if (start_time === undefined || end_time === undefined) {\n return timeInputFromEpochNs(end_time)\n }\n\n return timeInputFromEpochNs(end_time > start_time ? end_time : start_time + 1n)\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
  }
@@ -1,4 +1,4 @@
1
- import { trace, type Span, type SpanAttributes, type SpanContext, type Tracer } from '@opentelemetry/api';
1
+ import { trace, type Span, type SpanAttributes, type SpanContext, type TimeInput, 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';
@@ -10,7 +10,7 @@ export type OtelTracingSpanFactoryInput = {
10
10
  span_context: SpanContext;
11
11
  parent_span_context?: SpanContext;
12
12
  attributes: SpanAttributes;
13
- start_time?: Date;
13
+ start_time?: TimeInput;
14
14
  };
15
15
  export type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span;
16
16
  export type OtelTracingSpanProvider = object;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abxbus",
3
- "version": "2.4.24",
3
+ "version": "2.4.26",
4
4
  "description": "Event bus library for browsers and ESM Node.js",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -8,11 +8,12 @@ import {
8
8
  type SpanAttributeValue,
9
9
  type SpanAttributes,
10
10
  type SpanContext,
11
+ type TimeInput,
11
12
  type Tracer,
12
13
  } from '@opentelemetry/api'
13
14
  import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
14
15
  import { resourceFromAttributes } from '@opentelemetry/resources'
15
- import { BasicTracerProvider, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'
16
+ import { BasicTracerProvider, BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'
16
17
  import type { SpanLimits, SpanProcessor } from '@opentelemetry/sdk-trace-base'
17
18
  import { SpanImpl } from '@opentelemetry/sdk-trace-base/build/src/Span.js'
18
19
 
@@ -29,7 +30,7 @@ export type OtelTracingSpanFactoryInput = {
29
30
  span_context: SpanContext
30
31
  parent_span_context?: SpanContext
31
32
  attributes: SpanAttributes
32
- start_time?: Date
33
+ start_time?: TimeInput
33
34
  }
34
35
 
35
36
  export type OtelTracingSpanFactory = (input: OtelTracingSpanFactoryInput) => Span
@@ -114,7 +115,7 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
114
115
  }
115
116
 
116
117
  const parent_context = this.parentContextForEvent(event) ?? ROOT_CONTEXT
117
- const start_time = dateFromIso(event.event_started_at)
118
+ const start_time = timeInputFromIso(event.event_started_at)
118
119
  const span = this.tracer.startSpan(
119
120
  eventSpanName(eventbus, event),
120
121
  {
@@ -146,8 +147,8 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
146
147
  span.setAttributes(
147
148
  event.event_parent_id ? eventSpanAttributes(eventbus, event) : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, event)
148
149
  )
149
- const start_time = dateFromIso(event.event_started_at)
150
- const end_time = endTimeAfterStart(start_time, dateFromIso(event.event_completed_at))
150
+ const start_time = epochNsFromIso(event.event_started_at)
151
+ const end_time = endTimeAfterStart(start_time, epochNsFromIso(event.event_completed_at))
151
152
  span.end(end_time)
152
153
  this.event_spans.delete(event.event_id)
153
154
  this.event_contexts.delete(event.event_id)
@@ -165,7 +166,7 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
165
166
  handlerSpanName(event, event_result),
166
167
  {
167
168
  attributes: handlerSpanAttributes(eventbus, event, event_result),
168
- startTime: dateFromIso(event_result.started_at),
169
+ startTime: timeInputFromIso(event_result.started_at),
169
170
  },
170
171
  parent_context
171
172
  )
@@ -191,7 +192,7 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
191
192
  span.setStatus({ code: SpanStatusCode.OK })
192
193
  }
193
194
  span.setAttributes(handlerSpanAttributes(eventbus, event, event_result))
194
- span.end(endTimeAfterStart(dateFromIso(event_result.started_at), dateFromIso(event_result.completed_at)))
195
+ span.end(endTimeAfterStart(epochNsFromIso(event_result.started_at), epochNsFromIso(event_result.completed_at)))
195
196
  this.handler_spans.delete(event_result.id)
196
197
  this.handler_contexts.delete(handlerSpanKey(event_result.event_id, event_result.handler_id))
197
198
  }
@@ -230,7 +231,7 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
230
231
  }
231
232
  visited_event_ids.add(original_event.event_id)
232
233
 
233
- const start_time = dateFromIso(original_event.event_started_at)
234
+ const start_time = epochNsFromIso(original_event.event_started_at)
234
235
  const span_context = eventSpanContext(trace_id, original_event.event_id)
235
236
  const span = this.span_factory!({
236
237
  name: eventSpanName(eventbus, original_event),
@@ -239,14 +240,14 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
239
240
  attributes: original_event.event_parent_id
240
241
  ? eventSpanAttributes(eventbus, original_event)
241
242
  : topLevelEventSpanAttributes(this.root_span_attributes, eventbus, original_event),
242
- start_time,
243
+ start_time: timeInputFromEpochNs(start_time),
243
244
  })
244
245
  if (original_event.event_errors.length > 0) {
245
246
  recordSpanError(span, original_event.event_errors[0])
246
247
  } else {
247
248
  span.setStatus({ code: SpanStatusCode.OK })
248
249
  }
249
- span.end(endTimeAfterStart(start_time, dateFromIso(original_event.event_completed_at)))
250
+ span.end(endTimeAfterStart(start_time, epochNsFromIso(original_event.event_completed_at)))
250
251
 
251
252
  for (const event_result of original_event.event_results.values()) {
252
253
  const handler_context = this.exportHandlerSpanWithFactory(eventbus, original_event, event_result, trace_id, span_context)
@@ -263,21 +264,21 @@ export class OtelTracingMiddleware implements EventBusMiddleware {
263
264
  trace_id: string,
264
265
  parent_span_context: SpanContext
265
266
  ): SpanContext {
266
- const start_time = dateFromIso(event_result.started_at)
267
+ const start_time = epochNsFromIso(event_result.started_at)
267
268
  const span_context = handlerSpanContext(trace_id, event_result.event_id, event_result.handler_id)
268
269
  const span = this.span_factory!({
269
270
  name: handlerSpanName(event, event_result),
270
271
  span_context,
271
272
  parent_span_context,
272
273
  attributes: handlerSpanAttributes(eventbus, event, event_result),
273
- start_time,
274
+ start_time: timeInputFromEpochNs(start_time),
274
275
  })
275
276
  if (event_result.error !== undefined) {
276
277
  recordSpanError(span, event_result.error)
277
278
  } else {
278
279
  span.setStatus({ code: SpanStatusCode.OK })
279
280
  }
280
- span.end(endTimeAfterStart(start_time, dateFromIso(event_result.completed_at)))
281
+ span.end(endTimeAfterStart(start_time, epochNsFromIso(event_result.completed_at)))
281
282
  return span_context
282
283
  }
283
284
  }
@@ -300,10 +301,13 @@ function createOtlpSpanProvider(options: OtelTracingMiddlewareOptions): OtelTrac
300
301
  'service.name': options.service_name ?? 'abxbus',
301
302
  }),
302
303
  spanProcessors: [
303
- new SimpleSpanProcessor(
304
+ new BatchSpanProcessor(
304
305
  new OTLPTraceExporter({
305
306
  url: normalizeOtlpTracesEndpoint(options.otlp_endpoint!),
306
- })
307
+ }),
308
+ {
309
+ scheduledDelayMillis: 100,
310
+ }
307
311
  ),
308
312
  ],
309
313
  })
@@ -445,20 +449,45 @@ function fnv1a64Hex(input: string): string {
445
449
  return hash.toString(16).padStart(16, '0')
446
450
  }
447
451
 
448
- function dateFromIso(value: string | null | undefined): Date | undefined {
452
+ const ISO_EPOCH_NS_REGEX = /^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d{1,9}))?(Z|[+-]\d{2}:\d{2})$/
453
+ const NS_PER_SECOND = 1_000_000_000n
454
+ const NS_PER_MS = 1_000_000n
455
+
456
+ function epochNsFromIso(value: string | null | undefined): bigint | undefined {
449
457
  if (value == null) {
450
458
  return undefined
451
459
  }
452
- const date = new Date(value)
453
- return Number.isNaN(date.getTime()) ? undefined : date
460
+ const match = ISO_EPOCH_NS_REGEX.exec(value)
461
+ if (!match) {
462
+ return undefined
463
+ }
464
+ const [, base, fraction = '', timezone] = match
465
+ const base_ms = Date.parse(`${base}.000${timezone}`)
466
+ if (Number.isNaN(base_ms)) {
467
+ return undefined
468
+ }
469
+ return BigInt(base_ms) * NS_PER_MS + BigInt(fraction.padEnd(9, '0'))
470
+ }
471
+
472
+ function timeInputFromIso(value: string | null | undefined): TimeInput | undefined {
473
+ return timeInputFromEpochNs(epochNsFromIso(value))
474
+ }
475
+
476
+ function timeInputFromEpochNs(epoch_ns: bigint | undefined): TimeInput | undefined {
477
+ if (epoch_ns === undefined) {
478
+ return undefined
479
+ }
480
+ const seconds = epoch_ns / NS_PER_SECOND
481
+ const nanos = epoch_ns % NS_PER_SECOND
482
+ return [Number(seconds), Number(nanos)]
454
483
  }
455
484
 
456
- function endTimeAfterStart(start_time: Date | undefined, end_time: Date | undefined): Date | undefined {
457
- if (!start_time || !end_time) {
458
- return end_time
485
+ function endTimeAfterStart(start_time: bigint | undefined, end_time: bigint | undefined): TimeInput | undefined {
486
+ if (start_time === undefined || end_time === undefined) {
487
+ return timeInputFromEpochNs(end_time)
459
488
  }
460
489
 
461
- return end_time.getTime() > start_time.getTime() ? end_time : new Date(start_time.getTime() + 1)
490
+ return timeInputFromEpochNs(end_time > start_time ? end_time : start_time + 1n)
462
491
  }
463
492
 
464
493
  function resolveAttributes(