@sebspark/otel 4.1.16 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @sebspark/otel
2
2
 
3
+ ## 4.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ad1e80f: Upgraded to OpenTelemetry 3.0 (`@opentelemetry/api` 1.10).
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [ad1e80f]
12
+ - @sebspark/opentelemetry-instrumentation-opensearch@0.4.0
13
+
14
+ ## 4.1.17
15
+
16
+ ### Patch Changes
17
+
18
+ - 9f44fbd: Updated dependencies
19
+ - Updated dependencies [9f44fbd]
20
+ - @sebspark/opentelemetry-instrumentation-opensearch@0.3.15
21
+
3
22
  ## 4.1.16
4
23
 
5
24
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -9,10 +9,7 @@ import { SocketIoInstrumentationConfig } from "@opentelemetry/instrumentation-so
9
9
  import { OpenSearchInstrumentationConfig } from "@sebspark/opentelemetry-instrumentation-opensearch";
10
10
  import "@opentelemetry/instrumentation-http";
11
11
  import "@opentelemetry/instrumentation-undici";
12
- //#region src/enrichments/outgoing-http/consts.d.ts
13
12
  declare const PROTOCOLS: readonly ['https', 'http'];
14
- //#endregion
15
- //#region src/enrichments/outgoing-http/types.d.ts
16
13
  type Protocol = (typeof PROTOCOLS)[number];
17
14
  interface NormalisedRequest {
18
15
  method: string;
@@ -49,8 +46,6 @@ interface OutgoingHttpEnrichmentConfig extends InstrumentationConfig {
49
46
  */
50
47
  ignoreOutgoingPaths?: string[];
51
48
  }
52
- //#endregion
53
- //#region src/instrumentations.d.ts
54
49
  export declare const instrumentations: {
55
50
  readonly http: (config?: OutgoingHttpEnrichmentConfig) => Promise<Instrumentation<InstrumentationConfig>>;
56
51
  readonly express: (config?: ExpressInstrumentationConfig) => Promise<Instrumentation<InstrumentationConfig>>;
@@ -63,8 +58,6 @@ export declare const instrumentations: {
63
58
  readonly socketIo: (config?: SocketIoInstrumentationConfig) => Promise<Instrumentation<InstrumentationConfig>>;
64
59
  readonly opensearch: (config?: OpenSearchInstrumentationConfig) => Promise<Instrumentation<InstrumentationConfig>>;
65
60
  };
66
- //#endregion
67
- //#region src/logger.d.ts
68
61
  type Attrs = Record<string, any>;
69
62
  export type Logger = ReturnType<typeof getLogger>;
70
63
  export declare function getLogger(serviceOverride?: string, extraAttrs?: Attrs): {
@@ -109,16 +102,10 @@ export declare function getLogger(serviceOverride?: string, extraAttrs?: Attrs):
109
102
  (error: Error, attrs?: Attrs): void;
110
103
  };
111
104
  };
112
- //#endregion
113
- //#region src/metrics.d.ts
114
105
  export declare function getMeter(componentNameOverride?: string): import("@opentelemetry/api").Meter;
115
- //#endregion
116
- //#region src/otel.d.ts
117
106
  export declare function initialize(...instrumentations: Promise<Instrumentation>[]): Promise<void>;
118
107
  export declare function isInitialized(): boolean;
119
108
  export declare const dispose: () => Promise<void>;
120
- //#endregion
121
- //#region src/tracer.d.ts
122
109
  type OtelTracer = ReturnType<typeof trace.getTracer>;
123
110
  type Span$2 = ReturnType<OtelTracer['startSpan']>;
124
111
  type Func<T> = (span: Span$2) => Promise<T> | T;
@@ -150,6 +137,5 @@ interface Tracer extends OtelTracer {
150
137
  * @returns Tracer with helpers
151
138
  */
152
139
  export declare function getTracer(componentNameOverride?: string): Tracer;
153
- //#endregion
154
140
  export { type Context, type Counter, type Gauge, type Histogram, type Meter, type ObservableCounter, type ObservableGauge, type ObservableUpDownCounter, type Span, type SpanStatus, SpanStatusCode, type UpDownCounter, context };
155
141
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/enrichments/outgoing-http/consts.ts","../src/enrichments/outgoing-http/types.ts","../src/instrumentations.ts","../src/logger.ts","../src/metrics.ts","../src/otel.ts","../src/tracer.ts"],"mappings":";;;;;;;;;;;;cA0Ba;;;KCtBD,mBAAmB;UASd;EACf;EACA;EACA;;EAEA;EACA,UAAU;;EAEV,UAAU;;UAeK,qCAAqC;;;;;EAKpD;;EAGA;;;;;;EAOA,cAAc,MAAM,QAAM,SAAS;;;;;EAMnC;;;;;EAMA;;;;qBCpCW;WACX,OAAI,SAAU,iCAA4B,QAAA,gBAAA;WAe1C,UAAO,SAAU,iCAA4B,QAAA,gBAAA;WAc7C,OAAI,SAAU,8BAAyB,QAAA,gBAAA;WAcvC,QAAK,SAAU,+BAA0B,QAAA,gBAAA;WAczC,MAAG,SAAU,6BAAwB,QAAA,gBAAA;WAcrC,MAAG,SAAU,0BAAqB,QAAA,gBAAA;WAclC,KAAE,SAAU,4BAAuB,QAAA,gBAAA;WAcnC,SAAM,SAAU,iCAA4B,QAAA,gBAAA;WAe5C,WAAQ,SAAU,kCAA6B,QAAA,gBAAA;WAc/C,aAAU,SAAU,oCAA+B,QAAA,gBAAA;;;;KCrJhD,QAAQ;YAED,SAAS,kBAAkB;wBACvB,UAAU,0BAA0B,aAAY;EAkF5D;KAjBM,aAAM,QAAU;KAChB,aAAM,OAAS,OAAK,QAAU;KAC5B,OAAA,OAAK,QAAU;;EAgBvB;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;;;;wBC/FY,SAAS,8DAA8B;;;wBC0BjC,cACjB,kBAAkB,QAAQ,qBAAkB;wBAejC;qBAsCH,eAAO;;;KC3Ef,aAAa,kBAAkB,MAAM;KACrC,SAAO,WAAW;KAElB,KAAK,MAAM,MAAM,WAAS,QAAQ,KAAK;KACvC,SAAS,MAAM,MAAM,WAAS;KAE9B;GACF,GAAG,cAAc,IAAI,KAAK,KAAK,QAAQ;GACvC,GAAG,cAAc,SAAS,aAAa,IAAI,KAAK,KAAK,QAAQ;GAC7D,GAAG,cAAc,QAAQ,QAAM,IAAI,KAAK,KAAK,QAAQ;GACrD,GAAG,cAAc,SAAS,aAAa,QAAQ,QAAM,IAAI,KAAK,KAAK,QAAQ;;KAEzE;GACF,GAAG,cAAc,IAAI,SAAS,KAAK;GACnC,GAAG,cAAc,SAAS,aAAa,IAAI,SAAS,KAAK;GACzD,GAAG,cAAc,QAAQ,QAAM,IAAI,SAAS,KAAK;GACjD,GAAG,cAAc,SAAS,aAAa,QAAQ,QAAM,IAAI,SAAS,KAAK;;;;;UAMhE,eAAe;EACvB,WAAW;EACX,eAAe;;;;;;;;;wBAUD,UAAU,iCAAiC"}
1
+ {"version":3,"file":"index.d.mts","names":["Span","Span"],"sources":["../src/enrichments/outgoing-http/consts.ts","../src/enrichments/outgoing-http/types.ts","../src/instrumentations.ts","../src/logger.ts","../src/metrics.ts","../src/otel.ts","../src/tracer.ts"],"mappings":";;;;;;;;;;;cA0Ba;KCtBD,mBAAmB;UASd;EACf;EACA;EACA;;EAEA;EACA,UAAU;;EAEV,UAAU;;UAeK,qCAAqC;;;;;EAKpD;;EAGA;;;;;;EAOA,cAAc,MAAMA,QAAM,SAAS;;;;;EAMnC;;;;;EAMA;;qBCpCW;WACX,OAAI,SAAU,iCAA4B,QAAA,gBAAA;WAe1C,UAAO,SAAU,iCAA4B,QAAA,gBAAA;WAc7C,OAAI,SAAU,8BAAyB,QAAA,gBAAA;WAcvC,QAAK,SAAU,+BAA0B,QAAA,gBAAA;WAczC,MAAG,SAAU,6BAAwB,QAAA,gBAAA;WAcrC,MAAG,SAAU,0BAAqB,QAAA,gBAAA;WAclC,KAAE,SAAU,4BAAuB,QAAA,gBAAA;WAcnC,SAAM,SAAU,iCAA4B,QAAA,gBAAA;WAe5C,WAAQ,SAAU,kCAA6B,QAAA,gBAAA;WAc/C,aAAU,SAAU,oCAA+B,QAAA,gBAAA;;KCtJhD,QAAQ;YAED,SAAS,kBAAkB;wBACvB,UAAU,0BAA0B,aAAY;EAkF5D;KAjBM,aAAM,QAAU;KAChB,aAAM,OAAS,OAAK,QAAU;KAC5B,OAAA,OAAK,QAAU;;EAgBvB;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;EACA;;;;;;wBC9FY,SAAS,8DAA8B;wBC0BjC,cACjB,kBAAkB,QAAQ,qBAAkB;wBAejC;qBAsCH,eAAO;KC3Ef,aAAa,kBAAkB,MAAM;KACrCC,SAAO,WAAW;KAElB,KAAK,MAAM,MAAMA,WAAS,QAAQ,KAAK;KACvC,SAAS,MAAM,MAAMA,WAAS;KAE9B;GACF,GAAG,cAAc,IAAI,KAAK,KAAK,QAAQ;GACvC,GAAG,cAAc,SAAS,aAAa,IAAI,KAAK,KAAK,QAAQ;GAC7D,GAAG,cAAc,QAAQA,QAAM,IAAI,KAAK,KAAK,QAAQ;GACrD,GAAG,cAAc,SAAS,aAAa,QAAQA,QAAM,IAAI,KAAK,KAAK,QAAQ;;KAEzE;GACF,GAAG,cAAc,IAAI,SAAS,KAAK;GACnC,GAAG,cAAc,SAAS,aAAa,IAAI,SAAS,KAAK;GACzD,GAAG,cAAc,QAAQA,QAAM,IAAI,SAAS,KAAK;GACjD,GAAG,cAAc,SAAS,aAAa,QAAQA,QAAM,IAAI,SAAS,KAAK;;;;;UAMhE,eAAe;EACvB,WAAW;EACX,eAAe;;;;;;;;;wBAUD,UAAU,iCAAiC"}
package/dist/index.mjs CHANGED
@@ -1,20 +1,19 @@
1
- import { DiagConsoleLogger, DiagLogLevel, SpanStatusCode, SpanStatusCode as SpanStatusCode$1, context, context as context$1, diag, metrics, trace } from "@opentelemetry/api";
1
+ import { DiagConsoleLogger, DiagLogLevel, SeverityNumber, SpanStatusCode, SpanStatusCode as SpanStatusCode$1, context, context as context$1, diag, logs, metrics, trace } from "@opentelemetry/api";
2
2
  import { ATTR_ERROR_TYPE, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_NETWORK_PEER_ADDRESS, ATTR_NETWORK_PEER_PORT, ATTR_NETWORK_PROTOCOL_VERSION, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT, ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, ATTR_URL_FULL, ATTR_URL_PATH, ATTR_URL_QUERY, ATTR_URL_SCHEME } from "@opentelemetry/semantic-conventions";
3
- import { SeverityNumber, logs } from "@opentelemetry/api-logs";
4
3
  import { NodeSDK } from "@opentelemetry/sdk-node";
5
4
  import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
6
5
  import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
7
6
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
8
7
  import { BatchLogRecordProcessor, LoggerProvider, SimpleLogRecordProcessor } from "@opentelemetry/sdk-logs";
9
8
  import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
10
- import { BatchSpanProcessor, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-node";
9
+ import { BatchSpanProcessor, SimpleSpanProcessor } from "@opentelemetry/sdk-trace";
11
10
  import { ExportResultCode } from "@opentelemetry/core";
12
11
  import fss from "fast-safe-stringify";
13
12
  import kleur from "kleur";
14
13
  import { containerDetector } from "@opentelemetry/resource-detector-container";
15
14
  import { gcpDetector } from "@opentelemetry/resource-detector-gcp";
16
15
  import { detectResources, envDetector, osDetector, processDetector, resourceFromAttributes, serviceInstanceIdDetector } from "@opentelemetry/resources";
17
- //#region src/enrichments/outgoing-http/consts.ts
16
+ // src/enrichments/outgoing-http/consts.ts
18
17
  const ATTR_HTTP_REQUEST_BODY_SIZE = "http.request.body.size";
19
18
  const ATTR_HTTP_RESPONSE_BODY_SIZE = "http.response.body.size";
20
19
  const DEFAULT_REQUEST_HEADERS = [
@@ -34,8 +33,7 @@ const DEFAULT_RESPONSE_HEADERS = [
34
33
  "x-ratelimit-reset",
35
34
  "retry-after"
36
35
  ];
37
- //#endregion
38
- //#region src/enrichments/outgoing-http/apply-attributes.ts
36
+ // src/enrichments/outgoing-http/apply-attributes.ts
39
37
  const requestHeaderAttr = (h) => `http.request.header.${h.toLowerCase().replace(/-/g, "_")}`;
40
38
  const responseHeaderAttr = (h) => `http.response.header.${h.toLowerCase().replace(/-/g, "_")}`;
41
39
  const applyRequestAttributes = (span, req, cfg) => {
@@ -82,8 +80,7 @@ const applyResponseAttributes = (span, res, cfg) => {
82
80
  if (res.remoteAddress) span.setAttribute(ATTR_NETWORK_PEER_ADDRESS, res.remoteAddress);
83
81
  if (res.remotePort) span.setAttribute(ATTR_NETWORK_PEER_PORT, res.remotePort);
84
82
  };
85
- //#endregion
86
- //#region src/enrichments/outgoing-http/helpers.ts
83
+ // src/enrichments/outgoing-http/helpers.ts
87
84
  const resolve = (opts) => ({
88
85
  captureRequestHeaders: opts.captureRequestHeaders ?? DEFAULT_REQUEST_HEADERS,
89
86
  captureResponseHeaders: opts.captureResponseHeaders ?? DEFAULT_RESPONSE_HEADERS,
@@ -93,8 +90,7 @@ const resolve = (opts) => ({
93
90
  });
94
91
  const isClientRequest = (req) => typeof req.getHeader === "function";
95
92
  const isIncomingMessage = (res) => res != null && typeof res === "object" && "statusCode" in res && "headers" in res;
96
- //#endregion
97
- //#region src/enrichments/outgoing-http/normalize-http.ts
93
+ // src/enrichments/outgoing-http/normalize-http.ts
98
94
  const normHttpRequest = (req) => {
99
95
  const hostname = String(req.hostname ?? req.host ?? "").split(":")[0];
100
96
  const port = Number(req.port ?? req.defaultPort ?? 80);
@@ -137,13 +133,12 @@ const getHeaderFromObject = (headers, name) => {
137
133
  return;
138
134
  }
139
135
  };
140
- //#endregion
141
- //#region src/enrichments/outgoing-http/build-http-config.ts
136
+ // src/enrichments/outgoing-http/build-http-config.ts
142
137
  /**
143
138
  * Build an HttpInstrumentationConfig that applies shared enrichment logic.
144
139
  *
145
140
  * The returned config can be spread with your own additional options:
146
- * new HttpInstrumentation({ ...buildHttpConfig(opts), serverName: 'gateway' })
141
+ * new HttpInstrumentation({ ...buildHttpConfig(opts), requireParentforOutgoingSpans: true })
147
142
  */
148
143
  const buildHttpConfig = (opts = {}) => {
149
144
  const cfg = resolve(opts);
@@ -195,8 +190,7 @@ const buildHttpConfig = (opts = {}) => {
195
190
  }
196
191
  };
197
192
  };
198
- //#endregion
199
- //#region src/enrichments/outgoing-http/normalize-undici.ts
193
+ // src/enrichments/outgoing-http/normalize-undici.ts
200
194
  const normUndiciRequest = (req) => {
201
195
  const origin = new URL(req.origin);
202
196
  const protocol = origin.protocol.replace(":", "");
@@ -249,8 +243,7 @@ const parseUndiciRequestHeaders = (headers) => {
249
243
  }
250
244
  return result;
251
245
  };
252
- //#endregion
253
- //#region src/enrichments/outgoing-http/build-undici-config.ts
246
+ // src/enrichments/outgoing-http/build-undici-config.ts
254
247
  /**
255
248
  * Build an UndiciInstrumentationConfig that applies shared enrichment logic.
256
249
  *
@@ -273,11 +266,9 @@ function buildUndiciConfig(opts = {}) {
273
266
  }
274
267
  };
275
268
  }
276
- //#endregion
277
- //#region src/enrichments/outgoing-http/index.ts
269
+ // src/enrichments/outgoing-http/index.ts
278
270
  /* istanbul ignore file */
279
- //#endregion
280
- //#region src/instrumentations.ts
271
+ // src/instrumentations.ts
281
272
  const cache = /* @__PURE__ */ new Map();
282
273
  const cacheKey = (instrumentationName, config) => {
283
274
  return config ? `${instrumentationName}:${JSON.stringify(config)}` : instrumentationName;
@@ -337,8 +328,7 @@ const instrumentations = {
337
328
  return cache.get(key);
338
329
  }
339
330
  };
340
- //#endregion
341
- //#region src/consts.ts
331
+ // src/consts.ts
342
332
  const LOG_SEVERITY_MAP = {
343
333
  TRACE: 1,
344
334
  DEBUG: 5,
@@ -352,8 +342,7 @@ const LOG_SEVERITY_MAP = {
352
342
  ALERT: 22,
353
343
  EMERGENCY: 23
354
344
  };
355
- //#endregion
356
- //#region src/loggers/formatters/style.ts
345
+ // src/loggers/formatters/style.ts
357
346
  const colors = {
358
347
  gray: kleur.gray,
359
348
  dim: kleur.dim,
@@ -389,8 +378,7 @@ const statusColorMap = {
389
378
  2: colors.red
390
379
  };
391
380
  colors.white, colors.cyan, colors.yellow, colors.magenta, colors.green;
392
- //#endregion
393
- //#region src/loggers/formatters/shared.ts
381
+ // src/loggers/formatters/shared.ts
394
382
  const stringify = fss.default.stableStringify;
395
383
  function formatTimestamp(time) {
396
384
  const date = new Date(hrTimeToMillis(time));
@@ -433,14 +421,12 @@ function calculateDuration(span) {
433
421
  const end = hrTimeToMillis(span.endTime);
434
422
  return Math.max(0, Math.round(end - start));
435
423
  }
436
- //#endregion
437
- //#region src/loggers/formatters/log-record.ts
424
+ // src/loggers/formatters/log-record.ts
438
425
  function formatLogRecord(record) {
439
426
  const timestamp = formatTimestamp(record.hrTime);
440
427
  return `${formatService(record.resource)} ${timestamp} ${formatLevel(record)} ${formatScope(record.resource, record.instrumentationScope)}${formatMessage(record)}${formatAttributes(record.attributes)}`;
441
428
  }
442
- //#endregion
443
- //#region src/loggers/formatters/metrics.ts
429
+ // src/loggers/formatters/metrics.ts
444
430
  function formatMetrics(resourceMetrics) {
445
431
  const { resource, scopeMetrics } = resourceMetrics;
446
432
  return scopeMetrics.map((scopeMetric) => formatScopeMetric(scopeMetric, resource)).join("\n");
@@ -469,8 +455,7 @@ function extractMetricValue(dp) {
469
455
  function isHistogramLike(val) {
470
456
  return typeof val === "object" && val !== null && "sum" in val && typeof val.sum === "number";
471
457
  }
472
- //#endregion
473
- //#region src/loggers/formatters/span.ts
458
+ // src/loggers/formatters/span.ts
474
459
  const LABEL_WIDTH = 20;
475
460
  const DESCRIPTION_MAX_WIDTH = 16;
476
461
  const BAR_MIN_WIDTH = 1;
@@ -571,11 +556,9 @@ function computeDepth(span, allSpans) {
571
556
  }
572
557
  return depth;
573
558
  }
574
- //#endregion
575
- //#region src/loggers/formatters/index.ts
559
+ // src/loggers/formatters/index.ts
576
560
  /* istanbul ignore file */
577
- //#endregion
578
- //#region src/loggers/console-metric-pretty-exporter.ts
561
+ // src/loggers/console-metric-pretty-exporter.ts
579
562
  var ConsoleMetricPrettyExporter = class {
580
563
  patterns;
581
564
  constructor() {
@@ -614,8 +597,7 @@ function globToRegex(glob) {
614
597
  const regex = `^${glob.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*")}$`;
615
598
  return new RegExp(regex);
616
599
  }
617
- //#endregion
618
- //#region src/loggers/console-log-pretty-exporter.ts
600
+ // src/loggers/console-log-pretty-exporter.ts
619
601
  var ConsoleLogPrettyExporter = class {
620
602
  logThreshold;
621
603
  constructor() {
@@ -646,8 +628,7 @@ var ConsoleLogPrettyExporter = class {
646
628
  done?.({ code: ExportResultCode.SUCCESS });
647
629
  }
648
630
  };
649
- //#endregion
650
- //#region src/loggers/console-span-pretty-exporter.ts
631
+ // src/loggers/console-span-pretty-exporter.ts
651
632
  var ConsoleSpanPrettyExporter = class {
652
633
  allowedStatuses;
653
634
  constructor() {
@@ -678,11 +659,9 @@ var ConsoleSpanPrettyExporter = class {
678
659
  return Promise.resolve();
679
660
  }
680
661
  };
681
- //#endregion
682
- //#region src/loggers/index.ts
662
+ // src/loggers/index.ts
683
663
  /* istanbul ignore file */
684
- //#endregion
685
- //#region src/loggers/tree-span-processor.ts
664
+ // src/loggers/tree-span-processor.ts
686
665
  var TreeSpanProcessor = class {
687
666
  exporter;
688
667
  orphans = /* @__PURE__ */ new Map();
@@ -720,8 +699,7 @@ var TreeSpanProcessor = class {
720
699
  await this.exporter.forceFlush?.();
721
700
  }
722
701
  };
723
- //#endregion
724
- //#region src/providers.ts
702
+ // src/providers.ts
725
703
  const getLogProvider = (resource, otlpEndpoint) => {
726
704
  if (otlpEndpoint) {
727
705
  const otlpExporter = new OTLPLogExporter({ url: `${otlpEndpoint}/v1/logs` });
@@ -747,16 +725,15 @@ const getSpanProcessor = (otlpEndpoint) => {
747
725
  if (!otlpEndpoint) return new TreeSpanProcessor(exporter);
748
726
  if (process.env.OTEL_SIMPLE_SPAN_PROCESSOR === "true") {
749
727
  console.log("[otel] Using SimpleSpanProcessor (OTEL_SIMPLE_SPAN_PROCESSOR=true)");
750
- return new SimpleSpanProcessor(exporter);
728
+ return new SimpleSpanProcessor({ exporter });
751
729
  }
752
- return new BatchSpanProcessor(exporter);
730
+ return new BatchSpanProcessor({ exporter });
753
731
  };
754
732
  const getMetricReader = (otlpEndpoint) => {
755
733
  const metricExporter = otlpEndpoint ? new OTLPMetricExporter({ url: `${otlpEndpoint}/v1/metrics` }) : new ConsoleMetricPrettyExporter();
756
734
  return new PeriodicExportingMetricReader({ exporter: metricExporter });
757
735
  };
758
- //#endregion
759
- //#region src/otel-context.ts
736
+ // src/otel-context.ts
760
737
  /**
761
738
  * Extracts telemetry context from environment (cloud/k8s aware),
762
739
  * with support for subservice/component override.
@@ -787,8 +764,7 @@ function detectTelemetryContext(componentNameOverride) {
787
764
  }
788
765
  };
789
766
  }
790
- //#endregion
791
- //#region src/resource.ts
767
+ // src/resource.ts
792
768
  const isOnGcp = () => !!(process.env.K_SERVICE || process.env.GAE_APPLICATION || process.env.KUBERNETES_SERVICE_HOST);
793
769
  const getResource = async () => {
794
770
  const baseRes = detectResources({ detectors: [
@@ -806,8 +782,7 @@ const getResource = async () => {
806
782
  if (resource.waitForAsyncAttributes) await resource.waitForAsyncAttributes();
807
783
  return resource;
808
784
  };
809
- //#endregion
810
- //#region src/otel.ts
785
+ // src/otel.ts
811
786
  diag.disable();
812
787
  diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR);
813
788
  const OTEL_INIT_KEY = Symbol.for("@sebspark/otel:initialized");
@@ -844,8 +819,8 @@ async function _initialize(instrumentations) {
844
819
  const spanProcessor = getSpanProcessor(otlpEndpoint);
845
820
  const metricReader = getMetricReader(otlpEndpoint);
846
821
  sdk = new NodeSDK({
847
- spanProcessor,
848
- metricReader,
822
+ spanProcessors: [spanProcessor],
823
+ metricReaders: [metricReader],
849
824
  instrumentations,
850
825
  resource
851
826
  });
@@ -865,8 +840,7 @@ const dispose = async () => {
865
840
  console.log("[otel] Shutdown complete.");
866
841
  }
867
842
  };
868
- //#endregion
869
- //#region src/logger.ts
843
+ // src/logger.ts
870
844
  function getLogger(serviceOverride, extraAttrs = {}) {
871
845
  const { systemName, systemVersion, resourceAttributes } = detectTelemetryContext(serviceOverride);
872
846
  const defaultAttrs = {
@@ -927,15 +901,13 @@ function getLogger(serviceOverride, extraAttrs = {}) {
927
901
  emergency: createLogFn("EMERGENCY")
928
902
  };
929
903
  }
930
- //#endregion
931
- //#region src/metrics.ts
904
+ // src/metrics.ts
932
905
  function getMeter(componentNameOverride) {
933
906
  if (!isInitialized() && process.env.NODE_ENV !== "test") console.warn("OTEL must be initialized before using getMeter()");
934
907
  const { componentName, systemName, systemVersion } = detectTelemetryContext(componentNameOverride);
935
908
  return metrics.getMeter(componentName ?? systemName, systemVersion);
936
909
  }
937
- //#endregion
938
- //#region src/tracer.ts
910
+ // src/tracer.ts
939
911
  /**
940
912
  * Returns an OpenTelemetry tracer bound to the current service.
941
913
  * Includes `withTrace()` and `withTraceSync()` helpers for span-wrapped execution.
@@ -1046,10 +1018,8 @@ const isFunction = (value) => typeof value === "function";
1046
1018
  const isSpan = (value) => value !== null && value !== void 0 && isFunction(value.spanContext) && isFunction(value.end);
1047
1019
  /* istanbul ignore next */
1048
1020
  const isSpanOptions = (value) => value !== null && value !== void 0 && (!!value.startTime || !!value.attributes || !!value.kind) && !isSpan(value);
1049
- //#endregion
1050
- //#region src/index.ts
1021
+ // src/index.ts
1051
1022
  /* istanbul ignore file */
1052
- //#endregion
1053
1023
  export { SpanStatusCode, context, dispose, getLogger, getMeter, getTracer, initialize, instrumentations, isInitialized };
1054
1024
 
1055
1025
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["SpanStatusCode","SpanStatusCode","SpanStatusCode","context","context","SpanStatusCode"],"sources":["../src/enrichments/outgoing-http/consts.ts","../src/enrichments/outgoing-http/apply-attributes.ts","../src/enrichments/outgoing-http/helpers.ts","../src/enrichments/outgoing-http/normalize-http.ts","../src/enrichments/outgoing-http/build-http-config.ts","../src/enrichments/outgoing-http/normalize-undici.ts","../src/enrichments/outgoing-http/build-undici-config.ts","../src/enrichments/outgoing-http/index.ts","../src/instrumentations.ts","../src/consts.ts","../src/loggers/formatters/style.ts","../src/loggers/formatters/shared.ts","../src/loggers/formatters/log-record.ts","../src/loggers/formatters/metrics.ts","../src/loggers/formatters/span.ts","../src/loggers/formatters/index.ts","../src/loggers/console-metric-pretty-exporter.ts","../src/loggers/console-log-pretty-exporter.ts","../src/loggers/console-span-pretty-exporter.ts","../src/loggers/index.ts","../src/loggers/tree-span-processor.ts","../src/providers.ts","../src/otel-context.ts","../src/resource.ts","../src/otel.ts","../src/logger.ts","../src/metrics.ts","../src/tracer.ts","../src/index.ts"],"sourcesContent":["// Incubating attrs — copied as string literals per OTel JS team recommendation:\n// importing from /incubating at runtime is explicitly discouraged because that\n// entry-point is NOT subject to semver and may break in minor releases.\n// https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-semantic-conventions#unstable-semconv\nexport const ATTR_HTTP_REQUEST_BODY_SIZE = 'http.request.body.size'\nexport const ATTR_HTTP_RESPONSE_BODY_SIZE = 'http.response.body.size'\n\nexport const DEFAULT_REQUEST_HEADERS: string[] = [\n 'content-type',\n 'accept',\n 'x-request-id',\n 'x-correlation-id',\n 'traceparent',\n 'tracestate',\n] as const\n\nexport const DEFAULT_RESPONSE_HEADERS: string[] = [\n 'content-type',\n 'x-request-id',\n 'x-correlation-id',\n 'x-ratelimit-limit',\n 'x-ratelimit-remaining',\n 'x-ratelimit-reset',\n 'retry-after',\n] as const\n\nexport const PROTOCOLS = ['https', 'http'] as const\n","import { type Span, SpanStatusCode } from '@opentelemetry/api'\nimport {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_QUERY,\n ATTR_URL_SCHEME,\n} from '@opentelemetry/semantic-conventions'\nimport {\n ATTR_HTTP_REQUEST_BODY_SIZE,\n ATTR_HTTP_RESPONSE_BODY_SIZE,\n} from './consts'\nimport type {\n NormalisedRequest,\n NormalisedResponse,\n ResolvedConfig,\n} from './types'\n\nconst requestHeaderAttr = (h: string) =>\n `http.request.header.${h.toLowerCase().replace(/-/g, '_')}`\nconst responseHeaderAttr = (h: string) =>\n `http.response.header.${h.toLowerCase().replace(/-/g, '_')}`\n\nexport const applyRequestAttributes = (\n span: Span,\n req: NormalisedRequest,\n cfg: ResolvedConfig\n): void => {\n const { method, hostname, port, path, protocol } = req\n const [urlPath, urlQuery] = path.split('?')\n /* istanbul ignore next */\n const defaultPort = protocol === 'https' ? 443 : 80\n /* istanbul ignore next */\n const portSuffix = port !== defaultPort ? `:${port}` : ''\n /* istanbul ignore next */\n const resolvedUrlPath = urlPath ?? '/'\n\n // Stable semconv v1.23+ attributes\n span.setAttributes({\n [ATTR_HTTP_REQUEST_METHOD]: method.toUpperCase(),\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: port,\n [ATTR_URL_SCHEME]: protocol,\n [ATTR_URL_PATH]: resolvedUrlPath,\n [ATTR_URL_FULL]: `${protocol}://${hostname}${portSuffix}${path}`,\n })\n\n if (urlQuery) {\n span.setAttribute(ATTR_URL_QUERY, urlQuery)\n }\n\n if (cfg.useDescriptiveSpanNames) {\n span.updateName(`${method.toUpperCase()} ${hostname}${resolvedUrlPath}`)\n }\n\n for (const header of cfg.captureRequestHeaders) {\n const value = req.getHeader(header)\n if (value !== undefined) {\n span.setAttribute(requestHeaderAttr(header), value)\n }\n }\n\n const contentLength = req.getHeader('content-length')\n if (contentLength !== undefined) {\n span.setAttribute(ATTR_HTTP_REQUEST_BODY_SIZE, Number(contentLength))\n }\n\n cfg.enrichSpan(span, req)\n}\n\nexport const applyResponseAttributes = (\n span: Span,\n res: NormalisedResponse,\n cfg: ResolvedConfig\n): void => {\n const { statusCode } = res\n\n span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, statusCode)\n\n // OTel spec for CLIENT spans: 5xx = SDK error; 4xx is not (it's the\n // server's fault). We still record error.type for both so they're filterable.\n if (statusCode >= 500) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: `HTTP ${statusCode}`,\n })\n span.setAttribute(ATTR_ERROR_TYPE, String(statusCode))\n } else if (statusCode >= 400) {\n span.setAttribute(ATTR_ERROR_TYPE, String(statusCode))\n }\n\n for (const header of cfg.captureResponseHeaders) {\n const value = res.getHeader(header)\n if (value !== undefined) {\n span.setAttribute(responseHeaderAttr(header), value)\n }\n }\n\n const contentLength = res.getHeader('content-length')\n if (contentLength !== undefined) {\n span.setAttribute(ATTR_HTTP_RESPONSE_BODY_SIZE, Number(contentLength))\n }\n\n // Resolved wire address (post-proxy) — separate from the original hostname\n // so you can see both in the span and spot mesh rewrites.\n if (res.remoteAddress) {\n span.setAttribute(ATTR_NETWORK_PEER_ADDRESS, res.remoteAddress)\n }\n if (res.remotePort) {\n span.setAttribute(ATTR_NETWORK_PEER_PORT, res.remotePort)\n }\n}\n","import type { ClientRequest, IncomingMessage } from 'node:http'\nimport { DEFAULT_REQUEST_HEADERS, DEFAULT_RESPONSE_HEADERS } from './consts'\nimport type { OutgoingHttpEnrichmentConfig, ResolvedConfig } from './types'\n\nexport const resolve = (\n opts: OutgoingHttpEnrichmentConfig\n): ResolvedConfig => ({\n captureRequestHeaders: opts.captureRequestHeaders ?? DEFAULT_REQUEST_HEADERS,\n captureResponseHeaders:\n opts.captureResponseHeaders ?? DEFAULT_RESPONSE_HEADERS,\n enrichSpan: opts.enrichSpan ?? (() => {}),\n useDescriptiveSpanNames: opts.useDescriptiveSpanNames ?? true,\n ignoreOutgoingPaths: opts.ignoreOutgoingPaths ?? [],\n})\n\nexport const isClientRequest = (\n req: ClientRequest | IncomingMessage\n): req is ClientRequest =>\n typeof (req as ClientRequest).getHeader === 'function'\n\nexport const isIncomingMessage = (res: unknown): res is IncomingMessage =>\n res != null &&\n typeof res === 'object' &&\n 'statusCode' in res &&\n 'headers' in res\n","import type { IncomingMessage, RequestOptions } from 'node:http'\nimport type { NormalisedRequest, NormalisedResponse, Protocol } from './types'\n\nexport const normHttpRequest = (req: RequestOptions): NormalisedRequest => {\n const hostname = String(req.hostname ?? req.host ?? '').split(':')[0]\n const port = Number(req.port ?? req.defaultPort ?? 80)\n const path = String(req.path ?? '/')\n const protocol: Protocol = port === 443 ? 'https' : 'http'\n\n return {\n method: req.method ?? 'GET',\n hostname,\n port,\n path,\n protocol,\n getHeader(name) {\n const headers = req.headers\n if (!headers || Array.isArray(headers)) return undefined\n return getHeaderFromObject(headers as Record<string, unknown>, name)\n },\n }\n}\n\nexport const normHttpResponse = (res: IncomingMessage): NormalisedResponse => {\n const socket = res.socket\n return {\n statusCode: res.statusCode ?? 0,\n statusMessage: res.statusMessage ?? '',\n getHeader(name) {\n return getHeaderFromObject(res.headers, name)\n },\n remoteAddress: socket?.remoteAddress,\n remotePort: socket?.remotePort,\n }\n}\n\nexport const getHeaderFromObject = (\n headers: Record<string, unknown> | undefined,\n name: string\n): string[] | undefined => {\n if (!headers) return undefined\n\n const target = name.toLowerCase()\n\n // Iterate over all keys to find case-insensitive match\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === target) {\n const value = headers[key]\n if (Array.isArray(value)) return value\n /* istanbul ignore next */\n if (typeof value === 'string') return [value]\n /* istanbul ignore next */\n return undefined\n }\n }\n\n return undefined\n}\n","import type { Attributes } from '@opentelemetry/api'\nimport type { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http'\nimport {\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_NETWORK_PROTOCOL_VERSION,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_SCHEME,\n} from '@opentelemetry/semantic-conventions'\nimport {\n applyRequestAttributes,\n applyResponseAttributes,\n} from './apply-attributes'\nimport { isClientRequest, isIncomingMessage, resolve } from './helpers'\nimport { normHttpRequest, normHttpResponse } from './normalize-http'\nimport type { OutgoingHttpEnrichmentConfig } from './types'\n\n/**\n * Build an HttpInstrumentationConfig that applies shared enrichment logic.\n *\n * The returned config can be spread with your own additional options:\n * new HttpInstrumentation({ ...buildHttpConfig(opts), serverName: 'gateway' })\n */\nexport const buildHttpConfig = (\n opts: OutgoingHttpEnrichmentConfig = {}\n): HttpInstrumentationConfig => {\n const cfg = resolve(opts)\n\n const config: HttpInstrumentationConfig = {\n enabled: opts.enabled,\n ignoreOutgoingRequestHook(req) {\n if (!cfg.ignoreOutgoingPaths.length) return false\n const path = req.path ?? ''\n return cfg.ignoreOutgoingPaths.some((p) =>\n path.toLowerCase().startsWith(p.toLowerCase())\n )\n },\n\n // startOutgoingSpanHook fires at span creation time — before any proxy or\n // service-mesh sidecar can rewrite the destination socket. The returned\n // attributes are the \"ground truth\" hostname we captured off the wire.\n startOutgoingSpanHook(req) {\n const { method, hostname, port, path, protocol } = normHttpRequest(req)\n const [urlPath] = path.split('?')\n const defaultPort = protocol === 'https' ? 443 : 80\n const portSuffix = port !== defaultPort ? `:${port}` : ''\n /* istanbul ignore next */\n const resolvedUrlPath = urlPath ?? '/'\n\n const attrs: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: method.toUpperCase(),\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: port,\n [ATTR_URL_SCHEME]: protocol,\n [ATTR_URL_PATH]: resolvedUrlPath,\n [ATTR_URL_FULL]: `${protocol}://${hostname}${portSuffix}${path}`,\n [ATTR_NETWORK_PEER_ADDRESS]: hostname,\n [ATTR_NETWORK_PEER_PORT]: port,\n }\n /* istanbul ignore next */\n for (const [key, val] of Object.entries(req.headers || {})) {\n if (!val) continue\n\n const name = key.toLowerCase().replace(/-/g, '_')\n const value = Array.isArray(val) ? val.join(',') : val\n attrs[`http.request.header.${name}`] = value\n }\n return attrs\n },\n\n requestHook(span, request) {\n // requestHook fires for both incoming (IncomingMessage) and outgoing\n // (ClientRequest) spans — skip the incoming side.\n if (!isClientRequest(request)) return\n\n // HTTP version isn't always accessible here, but try to read it.\n const proto = request.protocol\n if (proto) {\n span.setAttribute(\n ATTR_NETWORK_PROTOCOL_VERSION,\n /* istanbul ignore next */\n proto === 'https:' ? '1.1' : '1.1'\n )\n }\n\n applyRequestAttributes(span, normHttpRequest(request), cfg)\n },\n\n responseHook(span, response) {\n if (!isIncomingMessage(response)) return\n applyResponseAttributes(span, normHttpResponse(response), cfg)\n },\n }\n\n return config\n}\n","import type {\n UndiciRequest,\n UndiciResponse,\n} from '@opentelemetry/instrumentation-undici'\nimport type { NormalisedRequest, NormalisedResponse } from './types'\n\nexport const normUndiciRequest = (req: UndiciRequest): NormalisedRequest => {\n const origin = new URL(req.origin)\n const protocol = origin.protocol.replace(':', '') as 'http' | 'https'\n const port = Number(origin.port) || (protocol === 'https' ? 443 : 80)\n\n // Parse \"Key: Value\\r\\nKey2: Value2\\r\\n\" → Map\n const headers = parseUndiciRequestHeaders(req.headers)\n\n return {\n method: req.method,\n hostname: origin.hostname,\n port,\n path: req.path,\n protocol,\n getHeader: (name) => headers[name.toLowerCase()],\n }\n}\n\nexport const normUndiciResponse = (res: UndiciResponse): NormalisedResponse => {\n const headers = parseUndiciResponseHeaders(res.headers)\n\n return {\n statusCode: res.statusCode,\n statusMessage: res.statusText,\n getHeader: (name) => headers[name.toLowerCase()],\n }\n}\n\nexport const parseUndiciResponseHeaders = (\n headers: Buffer<ArrayBufferLike>[]\n): Record<string, string[]> => {\n const result: Record<string, string[]> = {}\n\n for (let i = 0; i < headers.length; i += 2) {\n const keyBuf = headers[i]\n const valBuf = headers[i + 1]\n\n if (!keyBuf || !valBuf) continue\n\n /* istanbul ignore next */\n const key = (\n Buffer.isBuffer(keyBuf)\n ? keyBuf.toString('utf8').trim()\n : Buffer.from(keyBuf as ArrayBuffer)\n .toString('utf8')\n .trim()\n ).toLowerCase()\n\n /* istanbul ignore next */\n const val = Buffer.isBuffer(valBuf)\n ? valBuf.toString('utf8').trim()\n : Buffer.from(valBuf as ArrayBuffer)\n .toString('utf8')\n .trim()\n\n if (!key || !val) continue\n\n if (!result[key]) result[key] = []\n result[key].push(val)\n }\n\n return result\n}\n\nexport const parseUndiciRequestHeaders = (\n headers: string | (string | string[])[]\n) => {\n const result: Record<string, string[]> = {}\n\n if (typeof headers === 'string') {\n // Single string format: \"key: value\"\n const [key, ...rest] = headers.split(':')\n if (key && rest.length > 0) {\n result[key.trim().toLowerCase()] = [rest.join(':').trim()]\n }\n } else {\n // The type union guarantees headers is string | array[]; the else-if is always true\n /* istanbul ignore else */\n if (Array.isArray(headers)) {\n // Array format: [key, value] or [key, [value1, value2]]\n for (let i = 0; i < headers.length; i += 2) {\n const key = headers[i]\n const val = headers[i + 1]\n if (typeof key !== 'string' || val == null) continue\n\n if (Array.isArray(val)) {\n result[key.toLowerCase()] = val.map((v) => String(v))\n } else {\n result[key.toLowerCase()] = [String(val)]\n }\n }\n }\n }\n\n return result\n}\n","import type { UndiciInstrumentationConfig } from '@opentelemetry/instrumentation-undici'\nimport {\n applyRequestAttributes,\n applyResponseAttributes,\n} from './apply-attributes'\nimport { resolve } from './helpers'\nimport { normUndiciRequest, normUndiciResponse } from './normalize-undici'\nimport type { OutgoingHttpEnrichmentConfig } from './types'\n\n/**\n * Build an UndiciInstrumentationConfig that applies shared enrichment logic.\n *\n * new UndiciInstrumentation(buildUndiciConfig(opts))\n */\nexport function buildUndiciConfig(\n opts: OutgoingHttpEnrichmentConfig = {}\n): UndiciInstrumentationConfig {\n const cfg = resolve(opts)\n\n const config: UndiciInstrumentationConfig = {\n enabled: opts.enabled,\n ignoreRequestHook(req) {\n if (!cfg.ignoreOutgoingPaths.length) return false\n const path = req.path ?? ''\n return cfg.ignoreOutgoingPaths.some((p) =>\n path.toLowerCase().startsWith(p.toLowerCase())\n )\n },\n\n // undici collapses startSpanHook + requestHook into a single requestHook\n // because diagnostics_channel gives us everything at once.\n requestHook(span, request) {\n applyRequestAttributes(span, normUndiciRequest(request), cfg)\n },\n\n responseHook(span, { response }) {\n applyResponseAttributes(span, normUndiciResponse(response), cfg)\n },\n }\n\n return config\n}\n","/* istanbul ignore file */\n/**\n * Shared enrichment logic for outgoing HTTP spans, normalised across\n * @opentelemetry/instrumentation-http (node:http / node:https)\n * @opentelemetry/instrumentation-undici (undici / global fetch)\n *\n * Usage:\n *\n * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\n * import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici'\n * import { buildHttpConfig, buildUndiciConfig } from './instrumentation/outgoing-http'\n * import type { OutgoingHttpEnrichmentConfig } from './instrumentation/outgoing-http'\n *\n * const opts: OutgoingHttpEnrichmentConfig = {\n * captureRequestHeaders: ['x-tenant-id', 'x-request-id'],\n * captureResponseHeaders: ['x-ratelimit-remaining'],\n * enrichSpan: (span, req) =>\n * span.setAttribute('app.tenant.id', req.getHeader('x-tenant-id') ?? ''),\n * ignoreOutgoingPaths: ['/health', '/ready'],\n * }\n *\n * new HttpInstrumentation(buildHttpConfig(opts))\n * new UndiciInstrumentation(buildUndiciConfig(opts))\n */\n\nexport { buildHttpConfig } from './build-http-config'\nexport { buildUndiciConfig } from './build-undici-config'\nexport type { OutgoingHttpEnrichmentConfig } from './types'\n","import type {\n Instrumentation,\n InstrumentationConfig,\n} from '@opentelemetry/instrumentation'\nimport type { DnsInstrumentationConfig } from '@opentelemetry/instrumentation-dns'\nimport type { ExpressInstrumentationConfig } from '@opentelemetry/instrumentation-express'\nimport type { FsInstrumentationConfig } from '@opentelemetry/instrumentation-fs'\nimport type { GrpcInstrumentationConfig } from '@opentelemetry/instrumentation-grpc'\nimport type { RedisInstrumentationConfig } from '@opentelemetry/instrumentation-redis'\nimport type { SocketIoInstrumentationConfig } from '@opentelemetry/instrumentation-socket.io'\nimport type { OpenSearchInstrumentationConfig } from '@sebspark/opentelemetry-instrumentation-opensearch'\nimport {\n buildHttpConfig,\n buildUndiciConfig,\n type OutgoingHttpEnrichmentConfig,\n} from './enrichments/outgoing-http'\n\nconst cache = new Map<string, Promise<Instrumentation>>()\nconst cacheKey = (\n instrumentationName: string,\n config?: InstrumentationConfig\n) => {\n return config\n ? `${instrumentationName}:${JSON.stringify(config)}`\n : instrumentationName\n}\n\nexport const instrumentations = {\n http(config?: OutgoingHttpEnrichmentConfig) {\n const key = cacheKey('http', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-http').then(\n ({ HttpInstrumentation }) =>\n new HttpInstrumentation(buildHttpConfig(config))\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n express(config?: ExpressInstrumentationConfig) {\n const key = cacheKey('express', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-express').then(\n ({ ExpressInstrumentation }) => new ExpressInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n grpc(config?: GrpcInstrumentationConfig) {\n const key = cacheKey('grpc', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-grpc').then(\n ({ GrpcInstrumentation }) => new GrpcInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n redis(config?: RedisInstrumentationConfig) {\n const key = cacheKey('redis', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-redis').then(\n ({ RedisInstrumentation }) => new RedisInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n dns(config?: DnsInstrumentationConfig) {\n const key = cacheKey('dns', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-dns').then(\n ({ DnsInstrumentation }) => new DnsInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n net(config?: InstrumentationConfig) {\n const key = cacheKey('dns', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-net').then(\n ({ NetInstrumentation }) => new NetInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n fs(config?: FsInstrumentationConfig) {\n const key = cacheKey('fs', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-fs').then(\n ({ FsInstrumentation }) => new FsInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n undici(config?: OutgoingHttpEnrichmentConfig) {\n const key = cacheKey('undici', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-undici').then(\n ({ UndiciInstrumentation }) =>\n new UndiciInstrumentation(buildUndiciConfig(config))\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n socketIo(config?: SocketIoInstrumentationConfig) {\n const key = cacheKey('socket-io', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-socket.io').then(\n ({ SocketIoInstrumentation }) => new SocketIoInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n opensearch(config?: OpenSearchInstrumentationConfig) {\n const key = cacheKey('opensearch', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@sebspark/opentelemetry-instrumentation-opensearch').then(\n ({ OpenSearchInstrumentation }) =>\n new OpenSearchInstrumentation({\n suppressInternalInstrumentation: true,\n ...(config || {}),\n })\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n} as const\n","export const LOG_SEVERITY_MAP = {\n TRACE: 1,\n DEBUG: 5,\n INFO: 9,\n NOTICE: 10,\n WARNING: 13,\n WARN: 13,\n ERROR: 17,\n FATAL: 21,\n CRITICAL: 21,\n ALERT: 22,\n EMERGENCY: 23,\n} as const\n\nexport type LOG_SEVERITY_NAME = keyof typeof LOG_SEVERITY_MAP\n","import kleur from 'kleur'\n\nexport const colors = {\n gray: kleur.gray,\n dim: kleur.dim,\n cyan: kleur.cyan,\n white: kleur.white,\n green: kleur.green,\n yellow: kleur.yellow,\n red: kleur.red,\n magenta: kleur.magenta,\n}\n\nexport const levelColorMap: Record<string, (s: string) => string> = {\n DEBUG: kleur.magenta,\n INFO: kleur.green,\n WARN: kleur.yellow,\n ERROR: kleur.red,\n FATAL: kleur.red,\n}\n\nexport const levelIconMap: Record<string, string> = {\n DEBUG: '🐛',\n INFO: 'ℹ️ ',\n WARN: '⚠️ ',\n ERROR: '❌',\n FATAL: '💀',\n}\n\n// --- Span status codes (per OpenTelemetry spec) ---\nexport const statusLabelMap: Record<number, string> = {\n 0: 'UNSET',\n 1: 'OK',\n 2: 'ERROR',\n}\n\nexport const statusColorMap: Record<number, (s: string) => string> = {\n 0: colors.gray, // UNSET\n 1: colors.green, // OK\n 2: colors.red, // ERROR\n}\n\n// --- Span kinds (for visual context: client/server etc.) ---\nexport const kindLabelMap: Record<number, string> = {\n 0: 'INTERNAL',\n 1: 'SERVER',\n 2: 'CLIENT',\n 3: 'PRODUCER',\n 4: 'CONSUMER',\n}\n\nexport const kindColorMap: Record<number, (s: string) => string> = {\n 0: colors.white, // INTERNAL\n 1: colors.cyan, // SERVER\n 2: colors.yellow, // CLIENT\n 3: colors.magenta, // PRODUCER\n 4: colors.green, // CONSUMER\n}\n","import type { HrTime } from '@opentelemetry/api'\nimport type { LogAttributes } from '@opentelemetry/api-logs'\nimport type { Resource } from '@opentelemetry/resources'\nimport type { ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-node'\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions'\nimport fss from 'fast-safe-stringify'\nimport { colors, levelColorMap, levelIconMap } from './style'\n\nconst stringify = fss.default.stableStringify\n\ntype IResource = Pick<Resource, 'attributes'>\ntype IInstrumentation = ReadableLogRecord['instrumentationScope']\n\nexport function formatTimestamp(time: HrTime): string {\n const date = new Date(hrTimeToMillis(time))\n return colors.dim(date.toISOString().slice(11, 23)) // HH:mm:ss.sss\n}\n\nexport function formatService(resource: IResource): string {\n const name = resource.attributes[ATTR_SERVICE_NAME] ?? 'unknown-service'\n const version = resource.attributes[ATTR_SERVICE_VERSION] ?? '1.0.0'\n return colors.gray(`[${name}@${version}]`)\n}\n\nexport function formatLevel(record: ReadableLogRecord): string {\n const text = (record.severityText ?? 'INFO').toUpperCase()\n const colorFn = levelColorMap[text] ?? colors.white\n const icon = levelIconMap[text] ?? '•'\n return `${icon} ${colorFn(text.padEnd(5))}`\n}\n\nexport function formatScope(\n resource: IResource,\n instrumentationScope: IInstrumentation\n): string {\n const component = resource.attributes['component.name']\n const { name } = instrumentationScope\n const scopeLabel =\n component || (name && name !== 'unknown' ? name : undefined)\n\n if (!scopeLabel) return ''\n\n return colors.cyan(`${scopeLabel} `)\n}\n\nexport function formatMessage(record: ReadableLogRecord): string {\n return typeof record.body === 'string' ? record.body : stringify(record.body)\n}\n\nexport function formatAttributes(attrs: LogAttributes): string {\n const keys = Object.keys(attrs).filter(\n (k) =>\n !k.startsWith('service.') &&\n !k.startsWith('serviceContext.') &&\n k !== 'cloud.orchestrator' &&\n k !== 'component.name'\n )\n if (keys.length === 0) return ''\n const formatted = keys.map((k) => {\n const val = attrs[k]\n return `${k}=${typeof val === 'object' ? stringify(val) : val}`\n })\n return ` ${colors.gray(formatted.join(' '))}`\n}\n\nexport function hrTimeToMillis(hrTime: [number, number]): number {\n return hrTime[0] * 1000 + Math.floor(hrTime[1] / 1_000_000)\n}\n\nexport function calculateDuration(span: ReadableSpan): number {\n const start = hrTimeToMillis(span.startTime)\n const end = hrTimeToMillis(span.endTime)\n return Math.max(0, Math.round(end - start))\n}\n","import type { ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport {\n formatAttributes,\n formatLevel,\n formatMessage,\n formatScope,\n formatService,\n formatTimestamp,\n} from './shared'\n\nexport function formatLogRecord(record: ReadableLogRecord): string {\n const timestamp = formatTimestamp(record.hrTime)\n const service = formatService(record.resource)\n const level = formatLevel(record)\n const scope = formatScope(record.resource, record.instrumentationScope)\n const message = formatMessage(record)\n const attrs = formatAttributes(record.attributes)\n\n return `${service} ${timestamp} ${level} ${scope}${message}${attrs}`\n}\n","import type { Resource } from '@opentelemetry/resources'\nimport type {\n DataPoint,\n MetricData,\n ResourceMetrics,\n ScopeMetrics,\n} from '@opentelemetry/sdk-metrics'\nimport {\n formatAttributes,\n formatScope,\n formatService,\n formatTimestamp,\n} from './shared'\nimport { colors } from './style'\n\nexport function formatMetrics(resourceMetrics: ResourceMetrics): string {\n const { resource, scopeMetrics } = resourceMetrics\n\n return scopeMetrics\n .map((scopeMetric) => formatScopeMetric(scopeMetric, resource))\n .join('\\n')\n}\n\nfunction formatScopeMetric(\n scopeMetric: ScopeMetrics,\n resource: Resource\n): string {\n return scopeMetric.metrics\n .map((metric: MetricData) =>\n formatMetricData(metric, resource, scopeMetric.scope)\n )\n .join('\\n')\n}\n\nfunction formatMetricData(\n metric: MetricData,\n resource: Resource,\n scope: ScopeMetrics['scope']\n): string {\n const scopeStr = formatScope(resource, scope)\n const serviceStr = formatService(resource)\n\n const lines: string[] = []\n\n for (const dp of metric.dataPoints) {\n const ts = formatTimestamp(dp.startTime)\n const value = extractMetricValue(dp)\n const attrs = formatAttributes(dp.attributes ?? {})\n\n lines.push(\n `${serviceStr} ${ts} 📊 ${scopeStr}${colors.white(metric.descriptor.name)} ${colors.dim(value)}${attrs}`\n )\n }\n\n return lines.join('\\n')\n}\n\nfunction extractMetricValue(dp: DataPoint<unknown>): string {\n const value = dp.value\n\n if (typeof value === 'number') {\n return value.toString()\n }\n\n if (isHistogramLike(value)) {\n return value.sum.toString()\n }\n\n return '[complex]'\n}\n\nfunction isHistogramLike(val: unknown): val is { sum: number } {\n return (\n typeof val === 'object' &&\n val !== null &&\n 'sum' in val &&\n typeof (val as { sum: number }).sum === 'number'\n )\n}\n","import { SpanStatusCode } from '@opentelemetry/api'\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-node'\nimport {\n calculateDuration,\n formatService,\n formatTimestamp,\n hrTimeToMillis,\n} from './shared'\nimport { colors, statusColorMap, statusLabelMap } from './style'\n\nconst LABEL_WIDTH = 20\nconst DESCRIPTION_MAX_WIDTH = 16\nconst BAR_MIN_WIDTH = 1\nconst BAR_MAX_WIDTH = 20\n\nexport function formatSpans(spans: ReadableSpan[]) {\n const rootSpan = spans[0]\n const rootStart = hrTimeToMillis(rootSpan.startTime)\n const rootEnd = hrTimeToMillis(rootSpan.endTime)\n const totalDuration = rootEnd - rootStart\n\n const service = formatService(rootSpan.resource)\n const timestamp = formatTimestamp(rootSpan.startTime)\n const traceId = colors.gray(`[${rootSpan.spanContext().traceId}]`)\n\n const lines = [`${service} ${timestamp} ${traceId}`]\n\n for (const span of spans) {\n const offset = hrTimeToMillis(span.startTime) - rootStart\n const depth = computeDepth(span, spans) // optional\n lines.push(\n formatSpan(span, {\n offsetMs: offset,\n totalDurationMs: totalDuration,\n depth,\n })\n )\n }\n\n return lines.join('\\n')\n}\n\nexport function formatSpan(\n span: ReadableSpan,\n opts: {\n offsetMs: number // relative start time in ms (0 for root)\n totalDurationMs: number // total duration in ms (root span duration)\n depth: number // nesting level for indent\n }\n): string {\n const label = formatLabel(span, opts.depth)\n const bar = buildBar(span, opts?.offsetMs, opts?.totalDurationMs)\n const barColor =\n span.status.code === SpanStatusCode.OK\n ? colors.green\n : span.status.code === SpanStatusCode.ERROR\n ? colors.red\n : colors.gray\n const desc = formatDescription(span)\n const status = formatStatus(span)\n const duration = formatDuration(span, opts?.offsetMs)\n const spanId = colors.gray(`[${span.spanContext().spanId}]`)\n\n return `${label} ${barColor(bar)} ${desc} ${status} ${duration} ${spanId}`\n}\n\nfunction formatLabel(span: ReadableSpan, depth: number) {\n const indent = ' '.repeat(depth) // 2 spaces per depth level\n const label = `${indent}└─ ${span.name}`\n return label.padEnd(LABEL_WIDTH)\n}\n\nfunction buildBar(\n span: ReadableSpan,\n offsetMs: number | undefined,\n totalDurationMs: number | undefined\n) {\n const duration = calculateDuration(span)\n\n if (\n typeof offsetMs !== 'number' ||\n typeof totalDurationMs !== 'number' ||\n totalDurationMs === 0\n ) {\n // fallback: show duration-only bar\n const capped = Math.min(duration, 1000)\n const barLength = Math.max(\n BAR_MIN_WIDTH,\n Math.round((capped / 1000) * BAR_MAX_WIDTH)\n )\n return '█'.repeat(barLength).padEnd(BAR_MAX_WIDTH + 2)\n }\n\n // Relative position and size\n const offsetRatio = Math.max(0, Math.min(offsetMs / totalDurationMs, 1))\n const durationRatio = Math.max(0, Math.min(duration / totalDurationMs, 1))\n\n const offsetChars = Math.floor(offsetRatio * BAR_MAX_WIDTH)\n const barChars = Math.max(\n BAR_MIN_WIDTH,\n Math.round(durationRatio * BAR_MAX_WIDTH)\n )\n\n const empty = ' '.repeat(offsetChars)\n const bar = '█'.repeat(barChars)\n\n return (empty + bar).padEnd(BAR_MAX_WIDTH + 2)\n}\n\nfunction formatDescription(span: ReadableSpan): string {\n const keyPriority = [\n // HTTP\n ['http.method', 'http.target'], // → GET /users/123\n ['http.route'], // → /users/:id\n ['http.url'], // → https://...\n\n // GraphQL\n ['graphql.operation.name'], // → getUsers\n ['graphql.operation.type'], // → query\n ['graphql.document'], // → full query text (maybe too long)\n\n // WebSocket\n ['ws.event'], // → connection, message, disconnect\n ['ws.message_type'], // → ping/pong/text/binary\n ['ws.url'], // → wss://...\n\n // Redis\n ['db.system', 'db.statement'], // → redis, \"SET foo bar\"\n ['db.operation'], // → GET, SET\n\n // Spanner\n ['db.statement'], // → SELECT * FROM...\n ['db.operation'], // → SELECT, INSERT\n ['db.name'], // → projects/.../instances/.../databases/...\n\n // OpenSearch\n ['db.operation'], // → search, index, bulk\n ['db.statement'], // → { query DSL... }\n\n // Pub/Sub (GCP)\n ['messaging.operation'], // → publish, receive\n ['messaging.destination'], // → topic-a\n ['messaging.gcp_pubsub.topic'], // → projects/x/topics/y\n\n // General FaaS\n ['faas.invoked_name'], // → myFunction\n ['faas.trigger'], // → http, pubsub, etc.\n\n // Custom or fallback\n ['otel.description'],\n ]\n\n for (const keys of keyPriority) {\n const parts = keys\n .map((k) => span.attributes[k])\n .filter((v) => v !== undefined && v !== null)\n .map((v) => String(v)) // 👈 FIX — guarantees string\n if (parts.length > 0) {\n return truncate(parts.join(' '), DESCRIPTION_MAX_WIDTH - 1).padEnd(\n DESCRIPTION_MAX_WIDTH\n )\n }\n }\n\n return ''.padEnd(DESCRIPTION_MAX_WIDTH)\n}\n\nfunction formatStatus(span: ReadableSpan): string {\n const code = span.status.code\n const label = statusLabelMap[code] ?? 'UNSET'\n const colorFn = statusColorMap[code] ?? colors.gray\n return colorFn(label).padEnd(6)\n}\n\nfunction formatDuration(\n span: ReadableSpan,\n offsetMs: number | undefined\n): string {\n const duration = calculateDuration(span)\n\n const format = (ms: number): string =>\n ms >= 1000 ? `${(ms / 1000).toFixed(2)} s` : `${ms} ms`\n\n return `(${format(offsetMs || 0)}–${format(duration)})`.padEnd(16)\n}\n\nfunction truncate(input: unknown, maxLength: number): string {\n // In practice, input is always a string — the String() cast is a defensive fallback.\n const str = String(input)\n return str.length > maxLength ? `${str.slice(0, maxLength - 1)}…` : str\n}\n\nfunction computeDepth(span: ReadableSpan, allSpans: ReadableSpan[]): number {\n let depth = 0\n let currentParentId = span.parentSpanContext?.spanId\n\n while (currentParentId) {\n const parentSpan = allSpans.find(\n (s) => s.spanContext().spanId === currentParentId\n )\n if (!parentSpan) break\n\n depth += 1\n currentParentId = parentSpan.parentSpanContext?.spanId\n }\n\n return depth\n}\n","/* istanbul ignore file */\nexport * from './log-record'\nexport * from './metrics'\nexport * from './span'\n","import { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type {\n PushMetricExporter,\n ResourceMetrics,\n} from '@opentelemetry/sdk-metrics'\nimport { formatMetrics } from './formatters/index'\n\nexport class ConsoleMetricPrettyExporter implements PushMetricExporter {\n private readonly patterns: RegExp[]\n\n constructor() {\n const raw = process.env.METRIC_FILTER ?? ''\n const entries = raw\n .split(',')\n .map((e) => e.trim())\n .filter(Boolean)\n\n this.patterns = entries.map(globToRegex)\n }\n\n private filterMetrics(\n resourceMetrics: ResourceMetrics\n ): ResourceMetrics | undefined {\n // No filter = block all metrics\n if (this.patterns.length === 0) return undefined\n\n const filteredScopes = resourceMetrics.scopeMetrics\n .map((scopeMetric) => {\n const filteredMetrics = scopeMetric.metrics.filter((metric) =>\n this.patterns.some((pattern) => pattern.test(metric.descriptor.name))\n )\n\n if (filteredMetrics.length === 0) return undefined\n\n return {\n ...scopeMetric,\n metrics: filteredMetrics,\n }\n })\n .filter((s): s is NonNullable<typeof s> => s !== undefined)\n\n if (filteredScopes.length === 0) return undefined\n\n return {\n ...resourceMetrics,\n scopeMetrics: filteredScopes,\n }\n }\n\n export(\n metrics: ResourceMetrics,\n resultCallback: (result: ExportResult) => void\n ): void {\n const filtered = this.filterMetrics(metrics)\n if (filtered) {\n console.log(formatMetrics(filtered))\n }\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve()\n }\n}\n\nfunction globToRegex(glob: string): RegExp {\n const escaped = glob.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n const regex = `^${escaped.replace(/\\*/g, '.*')}$`\n return new RegExp(regex)\n}\n","import { SeverityNumber } from '@opentelemetry/api-logs'\nimport { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type {\n LogRecordExporter,\n ReadableLogRecord,\n} from '@opentelemetry/sdk-logs'\nimport { LOG_SEVERITY_MAP, type LOG_SEVERITY_NAME } from '../consts'\nimport { formatLogRecord } from './formatters/index'\n\nexport class ConsoleLogPrettyExporter implements LogRecordExporter {\n private readonly logThreshold: number\n constructor() {\n const defaultLogLevel = 'INFO'\n const env = (process.env.LOG_LEVEL?.toUpperCase() ??\n defaultLogLevel) as LOG_SEVERITY_NAME\n this.logThreshold =\n LOG_SEVERITY_MAP[env] ?? LOG_SEVERITY_MAP[defaultLogLevel]\n }\n export(\n logs: ReadableLogRecord[],\n resultCallback: (result: ExportResult) => void\n ): void {\n this._sendLogRecords(logs, resultCallback)\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve()\n }\n\n private _sendLogRecords(\n logRecords: ReadableLogRecord[],\n done: (result: ExportResult) => void\n ): void {\n for (const record of logRecords) {\n if ((record.severityNumber ?? 0) >= this.logThreshold) {\n const formatted = formatLogRecord(record)\n /* istanbul ignore next */\n const severity = record.severityNumber || SeverityNumber.UNSPECIFIED\n\n if (severity >= SeverityNumber.ERROR) {\n console.error(formatted)\n } else if (severity >= SeverityNumber.WARN) {\n console.log(formatted)\n } else if (severity >= SeverityNumber.INFO) {\n console.info(formatted)\n } else if (severity >= SeverityNumber.DEBUG) {\n console.debug(formatted)\n } else {\n console.trace(formatted)\n }\n }\n }\n\n done?.({ code: ExportResultCode.SUCCESS })\n }\n}\n","import { SpanStatusCode } from '@opentelemetry/api'\nimport { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-node'\nimport { formatSpans } from './formatters/index'\n\nexport class ConsoleSpanPrettyExporter implements SpanExporter {\n private readonly allowedStatuses: Set<number>\n\n constructor() {\n const env = process.env.SPAN_LEVEL?.toUpperCase()\n if (!env) {\n this.allowedStatuses = new Set([\n SpanStatusCode.UNSET,\n SpanStatusCode.OK,\n SpanStatusCode.ERROR,\n ])\n } else {\n const map: Record<string, number> = {\n UNSET: SpanStatusCode.UNSET,\n OK: SpanStatusCode.OK,\n ERROR: SpanStatusCode.ERROR,\n }\n\n this.allowedStatuses = new Set(\n env\n .split(',')\n .map((s) => s.trim())\n .map((s) => map[s])\n .filter((v): v is number => typeof v === 'number')\n )\n }\n }\n\n private shouldExport(spans: ReadableSpan[]) {\n // print all spans\n if (this.allowedStatuses.size === 3) {\n return true\n }\n // print only certain levels\n return spans.some((span) => this.allowedStatuses.has(span.status.code))\n }\n\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): void {\n if (this.shouldExport(spans)) {\n console.log(formatSpans(spans))\n }\n\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n}\n","/* istanbul ignore file */\nexport * from './console-log-pretty-exporter'\nexport * from './console-span-pretty-exporter'\nexport * from './gcp-json-log-exporter'\n","import type {\n ReadableSpan,\n SpanExporter,\n SpanProcessor,\n} from '@opentelemetry/sdk-trace-node'\n\nexport class TreeSpanProcessor implements SpanProcessor {\n private exporter: SpanExporter\n private orphans: Map<string, ReadableSpan[]> = new Map()\n\n constructor(exporter: SpanExporter) {\n this.exporter = exporter\n }\n\n onStart(): void {\n // no-op\n }\n\n onEnd(span: ReadableSpan): void {\n const parentId = span.parentSpanContext?.spanId\n\n if (parentId) {\n const siblings = this.orphans.get(parentId) || []\n this.orphans.set(parentId, [...siblings, span])\n\n return\n }\n\n const children = this.getChildrenRecursively(span)\n const sorted = [span, ...children].sort((s1, s2) => {\n const [sec1, nano1] = s1.startTime\n const [sec2, nano2] = s2.startTime\n\n if (sec1 !== sec2) return sec1 - sec2\n return nano1 - nano2\n })\n this.exporter.export(sorted, () => {})\n }\n\n private getChildrenRecursively(span: ReadableSpan) {\n const spanId = span.spanContext().spanId\n const children = this.orphans.get(spanId) || []\n this.orphans.delete(spanId)\n\n const result = [...children]\n for (const child of children) {\n result.push(...this.getChildrenRecursively(child))\n }\n\n return result\n }\n\n shutdown(): Promise<void> {\n return this.exporter.shutdown()\n }\n\n async forceFlush(): Promise<void> {\n await this.exporter.forceFlush?.()\n }\n}\n","import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport type { Resource } from '@opentelemetry/resources'\nimport {\n BatchLogRecordProcessor,\n LoggerProvider,\n type LogRecordProcessor,\n SimpleLogRecordProcessor,\n} from '@opentelemetry/sdk-logs'\nimport { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\nimport {\n BatchSpanProcessor,\n SimpleSpanProcessor,\n type SpanProcessor,\n} from '@opentelemetry/sdk-trace-node'\nimport { ConsoleMetricPrettyExporter } from './loggers/console-metric-pretty-exporter'\nimport {\n ConsoleLogPrettyExporter,\n ConsoleSpanPrettyExporter,\n} from './loggers/index'\nimport { TreeSpanProcessor } from './loggers/tree-span-processor'\n\nexport const getLogProvider = (\n resource: Resource,\n otlpEndpoint: string | undefined\n) => {\n // With collector\n if (otlpEndpoint) {\n const otlpExporter = new OTLPLogExporter({ url: `${otlpEndpoint}/v1/logs` })\n const processors: LogRecordProcessor[] = [\n new BatchLogRecordProcessor({ exporter: otlpExporter }),\n ]\n\n // Console logging for cluster\n if (process.env.LOG_LEVEL) {\n const consoleExporter = new ConsoleLogPrettyExporter()\n processors.push(\n new SimpleLogRecordProcessor({ exporter: consoleExporter })\n )\n }\n\n return new LoggerProvider({\n resource,\n processors,\n })\n }\n\n // Local dev\n const consoleExporter = new ConsoleLogPrettyExporter()\n const processor = new SimpleLogRecordProcessor({ exporter: consoleExporter })\n return new LoggerProvider({\n resource,\n processors: [processor],\n })\n}\n\nexport const getSpanProcessor = (\n otlpEndpoint: string | undefined\n): SpanProcessor => {\n const exporter = otlpEndpoint\n ? new OTLPTraceExporter({\n url: `${otlpEndpoint}/v1/traces`,\n })\n : new ConsoleSpanPrettyExporter()\n\n if (!otlpEndpoint) {\n return new TreeSpanProcessor(exporter)\n }\n\n if (process.env.OTEL_SIMPLE_SPAN_PROCESSOR === 'true') {\n console.log(\n '[otel] Using SimpleSpanProcessor (OTEL_SIMPLE_SPAN_PROCESSOR=true)'\n )\n return new SimpleSpanProcessor(exporter)\n }\n\n return new BatchSpanProcessor(exporter)\n}\n\nexport const getMetricReader = (otlpEndpoint: string | undefined) => {\n const metricExporter = otlpEndpoint\n ? new OTLPMetricExporter({\n url: `${otlpEndpoint}/v1/metrics`,\n })\n : new ConsoleMetricPrettyExporter()\n const metricReader = new PeriodicExportingMetricReader({\n exporter: metricExporter,\n })\n\n return metricReader\n}\n","import {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions'\n\n/**\n * Extracts telemetry context from environment (cloud/k8s aware),\n * with support for subservice/component override.\n */\nexport function detectTelemetryContext(componentNameOverride?: string) {\n const {\n OTEL_SERVICE_NAME, // e.g. \"UserSystem\"\n OTEL_SERVICE_VERSION, // e.g. \"1.2.3\"\n K_SERVICE,\n K_REVISION,\n K_CONFIGURATION,\n KUBERNETES_SERVICE_HOST,\n POD_NAME,\n POD_NAMESPACE,\n GCP_PROJECT,\n CLOUD_PROVIDER,\n } = process.env\n\n const systemName = OTEL_SERVICE_NAME || 'unknown-service'\n const systemVersion = OTEL_SERVICE_VERSION || '1.0.0'\n\n // Only use component if explicitly provided\n const componentName = componentNameOverride || undefined\n\n const resourceAttributes = {\n [ATTR_SERVICE_NAME]: systemName,\n [ATTR_SERVICE_VERSION]: systemVersion,\n 'serviceContext.service': systemName,\n 'serviceContext.version': systemVersion,\n ...(K_SERVICE && { 'cloud.run.service': K_SERVICE }),\n ...(K_REVISION && { 'cloud.run.revision': K_REVISION }),\n ...(K_CONFIGURATION && { 'cloud.run.configuration': K_CONFIGURATION }),\n ...(POD_NAME && { 'k8s.pod_name': POD_NAME }),\n ...(POD_NAMESPACE && { 'k8s.namespace_name': POD_NAMESPACE }),\n ...(KUBERNETES_SERVICE_HOST && { 'cloud.orchestrator': 'kubernetes' }),\n ...(GCP_PROJECT && { 'cloud.account.id': GCP_PROJECT }),\n ...(CLOUD_PROVIDER && { 'cloud.provider': CLOUD_PROVIDER }),\n ...(componentName && { 'component.name': componentName }),\n }\n\n return {\n systemName,\n systemVersion,\n componentName,\n resourceAttributes,\n }\n}\n","import { containerDetector } from '@opentelemetry/resource-detector-container'\nimport { gcpDetector } from '@opentelemetry/resource-detector-gcp'\nimport {\n detectResources,\n envDetector,\n osDetector,\n processDetector,\n resourceFromAttributes,\n serviceInstanceIdDetector,\n} from '@opentelemetry/resources'\nimport { detectTelemetryContext } from './otel-context'\n\nconst isOnGcp = () =>\n !!(\n process.env.K_SERVICE ||\n process.env.GAE_APPLICATION ||\n process.env.KUBERNETES_SERVICE_HOST\n )\n\nexport const getResource = async () => {\n const baseRes = detectResources({\n detectors: [\n containerDetector,\n envDetector,\n ...(isOnGcp() ? [gcpDetector] : []),\n osDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n })\n\n if (baseRes.waitForAsyncAttributes) {\n await baseRes.waitForAsyncAttributes()\n }\n\n const { resourceAttributes } = detectTelemetryContext()\n const customRes = resourceFromAttributes(resourceAttributes)\n const resource = baseRes.merge(customRes)\n\n if (resource.waitForAsyncAttributes) {\n await resource.waitForAsyncAttributes()\n }\n\n return resource\n}\n","import {\n context,\n DiagConsoleLogger,\n DiagLogLevel,\n diag,\n metrics,\n trace,\n} from '@opentelemetry/api'\nimport { logs } from '@opentelemetry/api-logs'\nimport type { Instrumentation } from '@opentelemetry/instrumentation'\nimport type { LoggerProvider } from '@opentelemetry/sdk-logs'\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getLogProvider, getMetricReader, getSpanProcessor } from './providers'\nimport { getResource } from './resource'\n\ndiag.disable()\ndiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR)\n\n// Use globalThis with a Symbol key so the flag is shared even when the module\n// is instantiated more than once (e.g. --import preload vs main app graph when\n// using tsx or other loaders that don't share the ESM module cache).\nconst OTEL_INIT_KEY = Symbol.for('@sebspark/otel:initialized')\nconst OTEL_INIT_PROMISE_KEY = Symbol.for('@sebspark/otel:initPromise')\n\nfunction getGlobal(): {\n [key: symbol]: unknown\n} {\n return globalThis as Record<symbol, unknown>\n}\n\nexport async function initialize(\n ...instrumentations: Promise<Instrumentation>[]\n) {\n const g = getGlobal()\n if (!g[OTEL_INIT_PROMISE_KEY]) {\n const resolvedInstrumentations = await Promise.all(instrumentations)\n const promise = _initialize(resolvedInstrumentations).catch((err) => {\n // Allow re-initialization if the first attempt fails\n g[OTEL_INIT_PROMISE_KEY] = undefined\n throw err\n })\n g[OTEL_INIT_PROMISE_KEY] = promise\n }\n return g[OTEL_INIT_PROMISE_KEY] as Promise<void>\n}\n\nexport function isInitialized() {\n return getGlobal()[OTEL_INIT_KEY] === true\n}\n\nlet sdk: NodeSDK | undefined\nlet logProvider: LoggerProvider | undefined\n\nasync function _initialize(instrumentations: Instrumentation[]) {\n const serviceName = process.env.OTEL_SERVICE_NAME ?? 'unknown-service'\n const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT\n\n const resource = await getResource()\n\n // Reset any previous instrumentation\n context.disable()\n logs.disable()\n trace.disable()\n metrics.disable()\n\n // Manual setup for logs\n logProvider = getLogProvider(resource, otlpEndpoint)\n logs.setGlobalLoggerProvider(logProvider)\n\n // NodeSDK setup\n const spanProcessor = getSpanProcessor(otlpEndpoint)\n const metricReader = getMetricReader(otlpEndpoint)\n sdk = new NodeSDK({\n spanProcessor,\n metricReader,\n instrumentations,\n resource,\n })\n\n sdk.start()\n getGlobal()[OTEL_INIT_KEY] = true\n console.log(`[otel] Telemetry initialized for \"${serviceName}\"`)\n}\n\nexport const dispose = async () => {\n const processes: Promise<void>[] = []\n if (sdk) processes.push(sdk.shutdown())\n if (logProvider) processes.push(logProvider.shutdown())\n\n // Only initiate shotdown once\n sdk = undefined\n logProvider = undefined\n\n if (processes.length) {\n console.log('[otel] Shutting down...')\n await Promise.all(processes)\n console.log('[otel] Shutdown complete.')\n }\n}\n","import { context, trace } from '@opentelemetry/api'\nimport { logs } from '@opentelemetry/api-logs'\nimport { LOG_SEVERITY_MAP, type LOG_SEVERITY_NAME } from './consts'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\n// biome-ignore lint/suspicious/noExplicitAny: library\ntype Attrs = Record<string, any>\n\nexport type Logger = ReturnType<typeof getLogger>\nexport function getLogger(serviceOverride?: string, extraAttrs: Attrs = {}) {\n const { systemName, systemVersion, resourceAttributes } =\n detectTelemetryContext(serviceOverride)\n\n const defaultAttrs = {\n ...resourceAttributes,\n ...extraAttrs,\n }\n\n let hasWarnedAboutInit = false\n\n function emit(\n severityText: LOG_SEVERITY_NAME,\n body: string,\n attrs: Attrs = {}\n ) {\n // Get the logger at the last second\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n if (!hasWarnedAboutInit) {\n console.warn('OTEL must be initialized before using logger')\n hasWarnedAboutInit = true\n }\n console.log(`[${severityText}] ${body}`)\n return\n }\n const logger = logs.getLogger(systemName, systemVersion)\n\n const span = trace.getSpan(context.active())\n const spanContext = span?.spanContext()\n\n logger.emit({\n severityText,\n severityNumber: LOG_SEVERITY_MAP[severityText],\n body,\n attributes: {\n 'gcp.log_name': systemName.replace(/^@/, '').replace(/\\//g, '-'),\n ...defaultAttrs,\n ...(spanContext && {\n trace_id: spanContext.traceId,\n span_id: spanContext.spanId,\n }),\n ...attrs,\n },\n })\n }\n\n function resolveArgs(\n msg: string | Error,\n errOrAttrs?: Error | Attrs,\n maybeAttrs: Attrs = {}\n ): { body: string; attrs: Attrs } {\n if (errOrAttrs instanceof Error) {\n /* istanbul ignore next */\n const body = `${msg}: ${errOrAttrs.stack || errOrAttrs.message}`\n return { body, attrs: maybeAttrs }\n }\n\n /* istanbul ignore next */\n const body = msg instanceof Error ? msg.stack || msg.message : msg\n /* istanbul ignore next */\n const attrs = errOrAttrs || {}\n return { body, attrs }\n }\n\n type LogFn = {\n (msg: string, attrs?: Attrs): void\n (msg: string, error: Error, attrs?: Attrs): void\n (error: Error, attrs?: Attrs): void\n }\n\n function createLogFn(severity: LOG_SEVERITY_NAME): LogFn {\n return (\n msg: string | Error,\n errOrAttrs?: Error | Attrs,\n maybeAttrs: Attrs = {}\n ) => {\n const { body, attrs } = resolveArgs(msg, errOrAttrs, maybeAttrs)\n emit(severity, body, attrs)\n }\n }\n\n return {\n debug: createLogFn('DEBUG'),\n info: createLogFn('INFO'),\n notice: createLogFn('NOTICE'),\n warn: createLogFn('WARN'),\n error: createLogFn('ERROR'),\n critical: createLogFn('CRITICAL'),\n alert: createLogFn('ALERT'),\n emergency: createLogFn('EMERGENCY'),\n }\n}\n","import { metrics } from '@opentelemetry/api'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\nexport function getMeter(componentNameOverride?: string) {\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n console.warn('OTEL must be initialized before using getMeter()')\n }\n\n const { componentName, systemName, systemVersion } = detectTelemetryContext(\n componentNameOverride\n )\n return metrics.getMeter(componentName ?? systemName, systemVersion)\n}\n","import {\n context,\n type SpanOptions,\n SpanStatusCode,\n trace,\n} from '@opentelemetry/api'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\ntype OtelTracer = ReturnType<typeof trace.getTracer>\ntype Span = ReturnType<OtelTracer['startSpan']>\n\ntype Func<T> = (span: Span) => Promise<T> | T\ntype SyncFunc<T> = (span: Span) => T\n\ntype WithTrace = {\n <T>(name: string, fn: Func<T>): Promise<T>\n <T>(name: string, options: SpanOptions, fn: Func<T>): Promise<T>\n <T>(name: string, parent: Span, fn: Func<T>): Promise<T>\n <T>(name: string, options: SpanOptions, parent: Span, fn: Func<T>): Promise<T>\n}\ntype WithTraceSync = {\n <T>(name: string, fn: SyncFunc<T>): T\n <T>(name: string, options: SpanOptions, fn: SyncFunc<T>): T\n <T>(name: string, parent: Span, fn: SyncFunc<T>): T\n <T>(name: string, options: SpanOptions, parent: Span, fn: SyncFunc<T>): T\n}\n\n/**\n * Extended tracer with helper methods for span-wrapped execution\n */\ninterface Tracer extends OtelTracer {\n withTrace: WithTrace\n withTraceSync: WithTraceSync\n}\n\n/**\n * Returns an OpenTelemetry tracer bound to the current service.\n * Includes `withTrace()` and `withTraceSync()` helpers for span-wrapped execution.\n *\n * @param serviceOverride - Optional override for service name\n * @returns Tracer with helpers\n */\nexport function getTracer(componentNameOverride?: string): Tracer {\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n console.warn('OTEL must be initialized before calling getTracer()')\n }\n\n const { componentName, systemName, systemVersion } = detectTelemetryContext(\n componentNameOverride\n )\n const tracer = trace.getTracer(\n componentName ?? systemName,\n systemVersion\n ) as Tracer\n\n /**\n * Runs a function inside a new span (async variant).\n * Automatically handles span status and nesting.\n */\n const withTrace: WithTrace = async <T>(\n name: string,\n spanOptionsSpanOrFunc?: SpanOptions | Span | Func<T>,\n spanOrFunc?: Span | Func<T>,\n func?: Func<T>\n ): Promise<T> => {\n const { options, parent, fn } = extractArgs(\n spanOptionsSpanOrFunc,\n spanOrFunc,\n func\n )\n\n const parentContext = parent\n ? trace.setSpan(context.active(), parent)\n : context.active()\n\n const span = tracer.startSpan(name, options, parentContext)\n let ended = false\n const originalEnd = span.end.bind(span)\n const endOnce = () => {\n if (!ended) {\n ended = true\n originalEnd()\n }\n }\n span.end = endOnce\n\n return await context.with(trace.setSpan(parentContext, span), async () => {\n try {\n const result = await fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (err) {\n const error = err as Error\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n span.recordException?.(error)\n throw err\n } finally {\n endOnce()\n }\n })\n }\n\n /**\n * Runs a synchronous function inside a new span.\n * Automatically handles span status and nesting.\n */\n const withTraceSync: WithTraceSync = <T>(\n name: string,\n spanOptionsSpanOrFunc?: SpanOptions | Span | SyncFunc<T>,\n spanOrFunc?: Span | SyncFunc<T>,\n func?: SyncFunc<T>\n ): T => {\n const { options, parent, fn } = extractArgs(\n spanOptionsSpanOrFunc,\n spanOrFunc,\n func\n )\n\n const parentContext = parent\n ? trace.setSpan(context.active(), parent)\n : context.active()\n\n const span = tracer.startSpan(name, options, parentContext)\n let ended = false\n const originalEnd = span.end.bind(span)\n const endOnce = () => {\n if (!ended) {\n ended = true\n originalEnd()\n }\n }\n span.end = endOnce\n\n return context.with(trace.setSpan(parentContext, span), () => {\n try {\n const result = fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (err) {\n const error = err as Error\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n span.recordException?.(error)\n throw err\n } finally {\n endOnce()\n }\n })\n }\n\n tracer.withTrace = withTrace\n tracer.withTraceSync = withTraceSync\n\n return tracer\n}\n\ntype TraceArgs<T> = {\n options: SpanOptions\n parent?: Span\n fn: (span: Span) => T\n}\n\nfunction extractArgs<T>(\n spanOptionsSpanOrFunc?: SpanOptions | Span | ((span: Span) => T),\n spanOrFunc?: Span | ((span: Span) => T),\n func?: (span: Span) => T\n): TraceArgs<T> {\n let options: SpanOptions = {}\n let parent: Span | undefined\n let fn: (span: Span) => T\n\n if (isFunction(spanOptionsSpanOrFunc)) {\n fn = spanOptionsSpanOrFunc\n } else if (isFunction(spanOrFunc)) {\n const spanOrSpanOptions = spanOptionsSpanOrFunc as Span | SpanOptions\n if (isSpanOptions(spanOrSpanOptions)) {\n options = spanOrSpanOptions as SpanOptions\n } else {\n parent = spanOrSpanOptions as Span\n }\n fn = spanOrFunc\n } else {\n options = spanOptionsSpanOrFunc as SpanOptions\n parent = spanOrFunc as Span\n // biome-ignore lint/style/noNonNullAssertion: it IS defined here\n fn = func!\n }\n\n return { options, parent, fn }\n}\n\nconst isFunction = (value: unknown): value is (span: Span) => unknown =>\n typeof value === 'function'\nconst isSpan = (value: unknown): value is Span =>\n value !== null &&\n value !== undefined &&\n isFunction((value as Span).spanContext) &&\n isFunction((value as Span).end)\n/* istanbul ignore next */\nconst isSpanOptions = (value: unknown): value is SpanOptions =>\n value !== null &&\n value !== undefined &&\n (!!(value as SpanOptions).startTime ||\n !!(value as SpanOptions).attributes ||\n !!(value as SpanOptions).kind) &&\n !isSpan(value)\n","/* istanbul ignore file */\nexport {\n type Context,\n type Counter,\n context,\n type Gauge,\n type Histogram,\n type Meter,\n type ObservableCounter,\n type ObservableGauge,\n type ObservableUpDownCounter,\n type Span,\n type SpanStatus,\n SpanStatusCode,\n type UpDownCounter,\n} from '@opentelemetry/api'\nexport * from './instrumentations'\nexport * from './logger'\nexport * from './metrics'\nexport * from './otel'\nexport * from './tracer'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["SpanStatusCode","SpanStatusCode","SpanStatusCode","context","context","SpanStatusCode"],"sources":["../src/enrichments/outgoing-http/consts.ts","../src/enrichments/outgoing-http/apply-attributes.ts","../src/enrichments/outgoing-http/helpers.ts","../src/enrichments/outgoing-http/normalize-http.ts","../src/enrichments/outgoing-http/build-http-config.ts","../src/enrichments/outgoing-http/normalize-undici.ts","../src/enrichments/outgoing-http/build-undici-config.ts","../src/enrichments/outgoing-http/index.ts","../src/instrumentations.ts","../src/consts.ts","../src/loggers/formatters/style.ts","../src/loggers/formatters/shared.ts","../src/loggers/formatters/log-record.ts","../src/loggers/formatters/metrics.ts","../src/loggers/formatters/span.ts","../src/loggers/formatters/index.ts","../src/loggers/console-metric-pretty-exporter.ts","../src/loggers/console-log-pretty-exporter.ts","../src/loggers/console-span-pretty-exporter.ts","../src/loggers/index.ts","../src/loggers/tree-span-processor.ts","../src/providers.ts","../src/otel-context.ts","../src/resource.ts","../src/otel.ts","../src/logger.ts","../src/metrics.ts","../src/tracer.ts","../src/index.ts"],"sourcesContent":["// Incubating attrs — copied as string literals per OTel JS team recommendation:\n// importing from /incubating at runtime is explicitly discouraged because that\n// entry-point is NOT subject to semver and may break in minor releases.\n// https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-semantic-conventions#unstable-semconv\nexport const ATTR_HTTP_REQUEST_BODY_SIZE = 'http.request.body.size'\nexport const ATTR_HTTP_RESPONSE_BODY_SIZE = 'http.response.body.size'\n\nexport const DEFAULT_REQUEST_HEADERS: string[] = [\n 'content-type',\n 'accept',\n 'x-request-id',\n 'x-correlation-id',\n 'traceparent',\n 'tracestate',\n] as const\n\nexport const DEFAULT_RESPONSE_HEADERS: string[] = [\n 'content-type',\n 'x-request-id',\n 'x-correlation-id',\n 'x-ratelimit-limit',\n 'x-ratelimit-remaining',\n 'x-ratelimit-reset',\n 'retry-after',\n] as const\n\nexport const PROTOCOLS = ['https', 'http'] as const\n","import { type Span, SpanStatusCode } from '@opentelemetry/api'\nimport {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_QUERY,\n ATTR_URL_SCHEME,\n} from '@opentelemetry/semantic-conventions'\nimport {\n ATTR_HTTP_REQUEST_BODY_SIZE,\n ATTR_HTTP_RESPONSE_BODY_SIZE,\n} from './consts'\nimport type {\n NormalisedRequest,\n NormalisedResponse,\n ResolvedConfig,\n} from './types'\n\nconst requestHeaderAttr = (h: string) =>\n `http.request.header.${h.toLowerCase().replace(/-/g, '_')}`\nconst responseHeaderAttr = (h: string) =>\n `http.response.header.${h.toLowerCase().replace(/-/g, '_')}`\n\nexport const applyRequestAttributes = (\n span: Span,\n req: NormalisedRequest,\n cfg: ResolvedConfig\n): void => {\n const { method, hostname, port, path, protocol } = req\n const [urlPath, urlQuery] = path.split('?')\n /* istanbul ignore next */\n const defaultPort = protocol === 'https' ? 443 : 80\n /* istanbul ignore next */\n const portSuffix = port !== defaultPort ? `:${port}` : ''\n /* istanbul ignore next */\n const resolvedUrlPath = urlPath ?? '/'\n\n // Stable semconv v1.23+ attributes\n span.setAttributes({\n [ATTR_HTTP_REQUEST_METHOD]: method.toUpperCase(),\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: port,\n [ATTR_URL_SCHEME]: protocol,\n [ATTR_URL_PATH]: resolvedUrlPath,\n [ATTR_URL_FULL]: `${protocol}://${hostname}${portSuffix}${path}`,\n })\n\n if (urlQuery) {\n span.setAttribute(ATTR_URL_QUERY, urlQuery)\n }\n\n if (cfg.useDescriptiveSpanNames) {\n span.updateName(`${method.toUpperCase()} ${hostname}${resolvedUrlPath}`)\n }\n\n for (const header of cfg.captureRequestHeaders) {\n const value = req.getHeader(header)\n if (value !== undefined) {\n span.setAttribute(requestHeaderAttr(header), value)\n }\n }\n\n const contentLength = req.getHeader('content-length')\n if (contentLength !== undefined) {\n span.setAttribute(ATTR_HTTP_REQUEST_BODY_SIZE, Number(contentLength))\n }\n\n cfg.enrichSpan(span, req)\n}\n\nexport const applyResponseAttributes = (\n span: Span,\n res: NormalisedResponse,\n cfg: ResolvedConfig\n): void => {\n const { statusCode } = res\n\n span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, statusCode)\n\n // OTel spec for CLIENT spans: 5xx = SDK error; 4xx is not (it's the\n // server's fault). We still record error.type for both so they're filterable.\n if (statusCode >= 500) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: `HTTP ${statusCode}`,\n })\n span.setAttribute(ATTR_ERROR_TYPE, String(statusCode))\n } else if (statusCode >= 400) {\n span.setAttribute(ATTR_ERROR_TYPE, String(statusCode))\n }\n\n for (const header of cfg.captureResponseHeaders) {\n const value = res.getHeader(header)\n if (value !== undefined) {\n span.setAttribute(responseHeaderAttr(header), value)\n }\n }\n\n const contentLength = res.getHeader('content-length')\n if (contentLength !== undefined) {\n span.setAttribute(ATTR_HTTP_RESPONSE_BODY_SIZE, Number(contentLength))\n }\n\n // Resolved wire address (post-proxy) — separate from the original hostname\n // so you can see both in the span and spot mesh rewrites.\n if (res.remoteAddress) {\n span.setAttribute(ATTR_NETWORK_PEER_ADDRESS, res.remoteAddress)\n }\n if (res.remotePort) {\n span.setAttribute(ATTR_NETWORK_PEER_PORT, res.remotePort)\n }\n}\n","import type { ClientRequest, IncomingMessage } from 'node:http'\nimport { DEFAULT_REQUEST_HEADERS, DEFAULT_RESPONSE_HEADERS } from './consts'\nimport type { OutgoingHttpEnrichmentConfig, ResolvedConfig } from './types'\n\nexport const resolve = (\n opts: OutgoingHttpEnrichmentConfig\n): ResolvedConfig => ({\n captureRequestHeaders: opts.captureRequestHeaders ?? DEFAULT_REQUEST_HEADERS,\n captureResponseHeaders:\n opts.captureResponseHeaders ?? DEFAULT_RESPONSE_HEADERS,\n enrichSpan: opts.enrichSpan ?? (() => {}),\n useDescriptiveSpanNames: opts.useDescriptiveSpanNames ?? true,\n ignoreOutgoingPaths: opts.ignoreOutgoingPaths ?? [],\n})\n\nexport const isClientRequest = (\n req: ClientRequest | IncomingMessage\n): req is ClientRequest =>\n typeof (req as ClientRequest).getHeader === 'function'\n\nexport const isIncomingMessage = (res: unknown): res is IncomingMessage =>\n res != null &&\n typeof res === 'object' &&\n 'statusCode' in res &&\n 'headers' in res\n","import type { IncomingMessage, RequestOptions } from 'node:http'\nimport type { NormalisedRequest, NormalisedResponse, Protocol } from './types'\n\nexport const normHttpRequest = (req: RequestOptions): NormalisedRequest => {\n const hostname = String(req.hostname ?? req.host ?? '').split(':')[0]\n const port = Number(req.port ?? req.defaultPort ?? 80)\n const path = String(req.path ?? '/')\n const protocol: Protocol = port === 443 ? 'https' : 'http'\n\n return {\n method: req.method ?? 'GET',\n hostname,\n port,\n path,\n protocol,\n getHeader(name) {\n const headers = req.headers\n if (!headers || Array.isArray(headers)) return undefined\n return getHeaderFromObject(headers as Record<string, unknown>, name)\n },\n }\n}\n\nexport const normHttpResponse = (res: IncomingMessage): NormalisedResponse => {\n const socket = res.socket\n return {\n statusCode: res.statusCode ?? 0,\n statusMessage: res.statusMessage ?? '',\n getHeader(name) {\n return getHeaderFromObject(res.headers, name)\n },\n remoteAddress: socket?.remoteAddress,\n remotePort: socket?.remotePort,\n }\n}\n\nexport const getHeaderFromObject = (\n headers: Record<string, unknown> | undefined,\n name: string\n): string[] | undefined => {\n if (!headers) return undefined\n\n const target = name.toLowerCase()\n\n // Iterate over all keys to find case-insensitive match\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === target) {\n const value = headers[key]\n if (Array.isArray(value)) return value\n /* istanbul ignore next */\n if (typeof value === 'string') return [value]\n /* istanbul ignore next */\n return undefined\n }\n }\n\n return undefined\n}\n","import type { Attributes } from '@opentelemetry/api'\nimport type { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http'\nimport {\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_NETWORK_PROTOCOL_VERSION,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_SCHEME,\n} from '@opentelemetry/semantic-conventions'\nimport {\n applyRequestAttributes,\n applyResponseAttributes,\n} from './apply-attributes'\nimport { isClientRequest, isIncomingMessage, resolve } from './helpers'\nimport { normHttpRequest, normHttpResponse } from './normalize-http'\nimport type { OutgoingHttpEnrichmentConfig } from './types'\n\n/**\n * Build an HttpInstrumentationConfig that applies shared enrichment logic.\n *\n * The returned config can be spread with your own additional options:\n * new HttpInstrumentation({ ...buildHttpConfig(opts), requireParentforOutgoingSpans: true })\n */\nexport const buildHttpConfig = (\n opts: OutgoingHttpEnrichmentConfig = {}\n): HttpInstrumentationConfig => {\n const cfg = resolve(opts)\n\n const config: HttpInstrumentationConfig = {\n enabled: opts.enabled,\n ignoreOutgoingRequestHook(req) {\n if (!cfg.ignoreOutgoingPaths.length) return false\n const path = req.path ?? ''\n return cfg.ignoreOutgoingPaths.some((p) =>\n path.toLowerCase().startsWith(p.toLowerCase())\n )\n },\n\n // startOutgoingSpanHook fires at span creation time — before any proxy or\n // service-mesh sidecar can rewrite the destination socket. The returned\n // attributes are the \"ground truth\" hostname we captured off the wire.\n startOutgoingSpanHook(req) {\n const { method, hostname, port, path, protocol } = normHttpRequest(req)\n const [urlPath] = path.split('?')\n const defaultPort = protocol === 'https' ? 443 : 80\n const portSuffix = port !== defaultPort ? `:${port}` : ''\n /* istanbul ignore next */\n const resolvedUrlPath = urlPath ?? '/'\n\n const attrs: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: method.toUpperCase(),\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: port,\n [ATTR_URL_SCHEME]: protocol,\n [ATTR_URL_PATH]: resolvedUrlPath,\n [ATTR_URL_FULL]: `${protocol}://${hostname}${portSuffix}${path}`,\n [ATTR_NETWORK_PEER_ADDRESS]: hostname,\n [ATTR_NETWORK_PEER_PORT]: port,\n }\n /* istanbul ignore next */\n for (const [key, val] of Object.entries(req.headers || {})) {\n if (!val) continue\n\n const name = key.toLowerCase().replace(/-/g, '_')\n const value = Array.isArray(val) ? val.join(',') : val\n attrs[`http.request.header.${name}`] = value\n }\n return attrs\n },\n\n requestHook(span, request) {\n // requestHook fires for both incoming (IncomingMessage) and outgoing\n // (ClientRequest) spans — skip the incoming side.\n if (!isClientRequest(request)) return\n\n // HTTP version isn't always accessible here, but try to read it.\n const proto = request.protocol\n if (proto) {\n span.setAttribute(\n ATTR_NETWORK_PROTOCOL_VERSION,\n /* istanbul ignore next */\n proto === 'https:' ? '1.1' : '1.1'\n )\n }\n\n applyRequestAttributes(span, normHttpRequest(request), cfg)\n },\n\n responseHook(span, response) {\n if (!isIncomingMessage(response)) return\n applyResponseAttributes(span, normHttpResponse(response), cfg)\n },\n }\n\n return config\n}\n","import type {\n UndiciRequest,\n UndiciResponse,\n} from '@opentelemetry/instrumentation-undici'\nimport type { NormalisedRequest, NormalisedResponse } from './types'\n\nexport const normUndiciRequest = (req: UndiciRequest): NormalisedRequest => {\n const origin = new URL(req.origin)\n const protocol = origin.protocol.replace(':', '') as 'http' | 'https'\n const port = Number(origin.port) || (protocol === 'https' ? 443 : 80)\n\n // Parse \"Key: Value\\r\\nKey2: Value2\\r\\n\" → Map\n const headers = parseUndiciRequestHeaders(req.headers)\n\n return {\n method: req.method,\n hostname: origin.hostname,\n port,\n path: req.path,\n protocol,\n getHeader: (name) => headers[name.toLowerCase()],\n }\n}\n\nexport const normUndiciResponse = (res: UndiciResponse): NormalisedResponse => {\n const headers = parseUndiciResponseHeaders(res.headers)\n\n return {\n statusCode: res.statusCode,\n statusMessage: res.statusText,\n getHeader: (name) => headers[name.toLowerCase()],\n }\n}\n\nexport const parseUndiciResponseHeaders = (\n headers: Buffer<ArrayBufferLike>[]\n): Record<string, string[]> => {\n const result: Record<string, string[]> = {}\n\n for (let i = 0; i < headers.length; i += 2) {\n const keyBuf = headers[i]\n const valBuf = headers[i + 1]\n\n if (!keyBuf || !valBuf) continue\n\n /* istanbul ignore next */\n const key = (\n Buffer.isBuffer(keyBuf)\n ? keyBuf.toString('utf8').trim()\n : Buffer.from(keyBuf as ArrayBuffer)\n .toString('utf8')\n .trim()\n ).toLowerCase()\n\n /* istanbul ignore next */\n const val = Buffer.isBuffer(valBuf)\n ? valBuf.toString('utf8').trim()\n : Buffer.from(valBuf as ArrayBuffer)\n .toString('utf8')\n .trim()\n\n if (!key || !val) continue\n\n if (!result[key]) result[key] = []\n result[key].push(val)\n }\n\n return result\n}\n\nexport const parseUndiciRequestHeaders = (\n headers: string | (string | string[])[]\n) => {\n const result: Record<string, string[]> = {}\n\n if (typeof headers === 'string') {\n // Single string format: \"key: value\"\n const [key, ...rest] = headers.split(':')\n if (key && rest.length > 0) {\n result[key.trim().toLowerCase()] = [rest.join(':').trim()]\n }\n } else {\n // The type union guarantees headers is string | array[]; the else-if is always true\n /* istanbul ignore else */\n if (Array.isArray(headers)) {\n // Array format: [key, value] or [key, [value1, value2]]\n for (let i = 0; i < headers.length; i += 2) {\n const key = headers[i]\n const val = headers[i + 1]\n if (typeof key !== 'string' || val == null) continue\n\n if (Array.isArray(val)) {\n result[key.toLowerCase()] = val.map((v) => String(v))\n } else {\n result[key.toLowerCase()] = [String(val)]\n }\n }\n }\n }\n\n return result\n}\n","import type { UndiciInstrumentationConfig } from '@opentelemetry/instrumentation-undici'\nimport {\n applyRequestAttributes,\n applyResponseAttributes,\n} from './apply-attributes'\nimport { resolve } from './helpers'\nimport { normUndiciRequest, normUndiciResponse } from './normalize-undici'\nimport type { OutgoingHttpEnrichmentConfig } from './types'\n\n/**\n * Build an UndiciInstrumentationConfig that applies shared enrichment logic.\n *\n * new UndiciInstrumentation(buildUndiciConfig(opts))\n */\nexport function buildUndiciConfig(\n opts: OutgoingHttpEnrichmentConfig = {}\n): UndiciInstrumentationConfig {\n const cfg = resolve(opts)\n\n const config: UndiciInstrumentationConfig = {\n enabled: opts.enabled,\n ignoreRequestHook(req) {\n if (!cfg.ignoreOutgoingPaths.length) return false\n const path = req.path ?? ''\n return cfg.ignoreOutgoingPaths.some((p) =>\n path.toLowerCase().startsWith(p.toLowerCase())\n )\n },\n\n // undici collapses startSpanHook + requestHook into a single requestHook\n // because diagnostics_channel gives us everything at once.\n requestHook(span, request) {\n applyRequestAttributes(span, normUndiciRequest(request), cfg)\n },\n\n responseHook(span, { response }) {\n applyResponseAttributes(span, normUndiciResponse(response), cfg)\n },\n }\n\n return config\n}\n","/* istanbul ignore file */\n/**\n * Shared enrichment logic for outgoing HTTP spans, normalised across\n * @opentelemetry/instrumentation-http (node:http / node:https)\n * @opentelemetry/instrumentation-undici (undici / global fetch)\n *\n * Usage:\n *\n * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\n * import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici'\n * import { buildHttpConfig, buildUndiciConfig } from './instrumentation/outgoing-http'\n * import type { OutgoingHttpEnrichmentConfig } from './instrumentation/outgoing-http'\n *\n * const opts: OutgoingHttpEnrichmentConfig = {\n * captureRequestHeaders: ['x-tenant-id', 'x-request-id'],\n * captureResponseHeaders: ['x-ratelimit-remaining'],\n * enrichSpan: (span, req) =>\n * span.setAttribute('app.tenant.id', req.getHeader('x-tenant-id') ?? ''),\n * ignoreOutgoingPaths: ['/health', '/ready'],\n * }\n *\n * new HttpInstrumentation(buildHttpConfig(opts))\n * new UndiciInstrumentation(buildUndiciConfig(opts))\n */\n\nexport { buildHttpConfig } from './build-http-config'\nexport { buildUndiciConfig } from './build-undici-config'\nexport type { OutgoingHttpEnrichmentConfig } from './types'\n","import type {\n Instrumentation,\n InstrumentationConfig,\n} from '@opentelemetry/instrumentation'\nimport type { DnsInstrumentationConfig } from '@opentelemetry/instrumentation-dns'\nimport type { ExpressInstrumentationConfig } from '@opentelemetry/instrumentation-express'\nimport type { FsInstrumentationConfig } from '@opentelemetry/instrumentation-fs'\nimport type { GrpcInstrumentationConfig } from '@opentelemetry/instrumentation-grpc'\nimport type { RedisInstrumentationConfig } from '@opentelemetry/instrumentation-redis'\nimport type { SocketIoInstrumentationConfig } from '@opentelemetry/instrumentation-socket.io'\nimport type { OpenSearchInstrumentationConfig } from '@sebspark/opentelemetry-instrumentation-opensearch'\nimport {\n buildHttpConfig,\n buildUndiciConfig,\n type OutgoingHttpEnrichmentConfig,\n} from './enrichments/outgoing-http'\n\nconst cache = new Map<string, Promise<Instrumentation>>()\nconst cacheKey = (\n instrumentationName: string,\n config?: InstrumentationConfig\n) => {\n return config\n ? `${instrumentationName}:${JSON.stringify(config)}`\n : instrumentationName\n}\n\nexport const instrumentations = {\n http(config?: OutgoingHttpEnrichmentConfig) {\n const key = cacheKey('http', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-http').then(\n ({ HttpInstrumentation }) =>\n new HttpInstrumentation(buildHttpConfig(config))\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n express(config?: ExpressInstrumentationConfig) {\n const key = cacheKey('express', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-express').then(\n ({ ExpressInstrumentation }) => new ExpressInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n grpc(config?: GrpcInstrumentationConfig) {\n const key = cacheKey('grpc', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-grpc').then(\n ({ GrpcInstrumentation }) => new GrpcInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n redis(config?: RedisInstrumentationConfig) {\n const key = cacheKey('redis', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-redis').then(\n ({ RedisInstrumentation }) => new RedisInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n dns(config?: DnsInstrumentationConfig) {\n const key = cacheKey('dns', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-dns').then(\n ({ DnsInstrumentation }) => new DnsInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n net(config?: InstrumentationConfig) {\n const key = cacheKey('dns', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-net').then(\n ({ NetInstrumentation }) => new NetInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n fs(config?: FsInstrumentationConfig) {\n const key = cacheKey('fs', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-fs').then(\n ({ FsInstrumentation }) => new FsInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n undici(config?: OutgoingHttpEnrichmentConfig) {\n const key = cacheKey('undici', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-undici').then(\n ({ UndiciInstrumentation }) =>\n new UndiciInstrumentation(buildUndiciConfig(config))\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n socketIo(config?: SocketIoInstrumentationConfig) {\n const key = cacheKey('socket-io', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@opentelemetry/instrumentation-socket.io').then(\n ({ SocketIoInstrumentation }) => new SocketIoInstrumentation(config)\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n\n opensearch(config?: OpenSearchInstrumentationConfig) {\n const key = cacheKey('opensearch', config)\n if (!cache.has(key)) {\n cache.set(\n key,\n import('@sebspark/opentelemetry-instrumentation-opensearch').then(\n ({ OpenSearchInstrumentation }) =>\n new OpenSearchInstrumentation({\n suppressInternalInstrumentation: true,\n ...(config || {}),\n })\n )\n )\n }\n // biome-ignore lint/style/noNonNullAssertion: it will always exist\n return cache.get(key)!\n },\n} as const\n","export const LOG_SEVERITY_MAP = {\n TRACE: 1,\n DEBUG: 5,\n INFO: 9,\n NOTICE: 10,\n WARNING: 13,\n WARN: 13,\n ERROR: 17,\n FATAL: 21,\n CRITICAL: 21,\n ALERT: 22,\n EMERGENCY: 23,\n} as const\n\nexport type LOG_SEVERITY_NAME = keyof typeof LOG_SEVERITY_MAP\n","import kleur from 'kleur'\n\nexport const colors = {\n gray: kleur.gray,\n dim: kleur.dim,\n cyan: kleur.cyan,\n white: kleur.white,\n green: kleur.green,\n yellow: kleur.yellow,\n red: kleur.red,\n magenta: kleur.magenta,\n}\n\nexport const levelColorMap: Record<string, (s: string) => string> = {\n DEBUG: kleur.magenta,\n INFO: kleur.green,\n WARN: kleur.yellow,\n ERROR: kleur.red,\n FATAL: kleur.red,\n}\n\nexport const levelIconMap: Record<string, string> = {\n DEBUG: '🐛',\n INFO: 'ℹ️ ',\n WARN: '⚠️ ',\n ERROR: '❌',\n FATAL: '💀',\n}\n\n// --- Span status codes (per OpenTelemetry spec) ---\nexport const statusLabelMap: Record<number, string> = {\n 0: 'UNSET',\n 1: 'OK',\n 2: 'ERROR',\n}\n\nexport const statusColorMap: Record<number, (s: string) => string> = {\n 0: colors.gray, // UNSET\n 1: colors.green, // OK\n 2: colors.red, // ERROR\n}\n\n// --- Span kinds (for visual context: client/server etc.) ---\nexport const kindLabelMap: Record<number, string> = {\n 0: 'INTERNAL',\n 1: 'SERVER',\n 2: 'CLIENT',\n 3: 'PRODUCER',\n 4: 'CONSUMER',\n}\n\nexport const kindColorMap: Record<number, (s: string) => string> = {\n 0: colors.white, // INTERNAL\n 1: colors.cyan, // SERVER\n 2: colors.yellow, // CLIENT\n 3: colors.magenta, // PRODUCER\n 4: colors.green, // CONSUMER\n}\n","import type { Attributes, HrTime } from '@opentelemetry/api'\nimport type { Resource } from '@opentelemetry/resources'\nimport type { ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace'\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions'\nimport fss from 'fast-safe-stringify'\nimport { colors, levelColorMap, levelIconMap } from './style'\n\nconst stringify = fss.default.stableStringify\n\ntype IResource = Pick<Resource, 'attributes'>\ntype IInstrumentation = ReadableLogRecord['instrumentationScope']\n\nexport function formatTimestamp(time: HrTime): string {\n const date = new Date(hrTimeToMillis(time))\n return colors.dim(date.toISOString().slice(11, 23)) // HH:mm:ss.sss\n}\n\nexport function formatService(resource: IResource): string {\n const name = resource.attributes[ATTR_SERVICE_NAME] ?? 'unknown-service'\n const version = resource.attributes[ATTR_SERVICE_VERSION] ?? '1.0.0'\n return colors.gray(`[${name}@${version}]`)\n}\n\nexport function formatLevel(record: ReadableLogRecord): string {\n const text = (record.severityText ?? 'INFO').toUpperCase()\n const colorFn = levelColorMap[text] ?? colors.white\n const icon = levelIconMap[text] ?? '•'\n return `${icon} ${colorFn(text.padEnd(5))}`\n}\n\nexport function formatScope(\n resource: IResource,\n instrumentationScope: IInstrumentation\n): string {\n const component = resource.attributes['component.name']\n const { name } = instrumentationScope\n const scopeLabel =\n component || (name && name !== 'unknown' ? name : undefined)\n\n if (!scopeLabel) return ''\n\n return colors.cyan(`${scopeLabel} `)\n}\n\nexport function formatMessage(record: ReadableLogRecord): string {\n return typeof record.body === 'string' ? record.body : stringify(record.body)\n}\n\nexport function formatAttributes(attrs: Attributes): string {\n const keys = Object.keys(attrs).filter(\n (k) =>\n !k.startsWith('service.') &&\n !k.startsWith('serviceContext.') &&\n k !== 'cloud.orchestrator' &&\n k !== 'component.name'\n )\n if (keys.length === 0) return ''\n const formatted = keys.map((k) => {\n const val = attrs[k]\n return `${k}=${typeof val === 'object' ? stringify(val) : val}`\n })\n return ` ${colors.gray(formatted.join(' '))}`\n}\n\nexport function hrTimeToMillis(hrTime: [number, number]): number {\n return hrTime[0] * 1000 + Math.floor(hrTime[1] / 1_000_000)\n}\n\nexport function calculateDuration(span: ReadableSpan): number {\n const start = hrTimeToMillis(span.startTime)\n const end = hrTimeToMillis(span.endTime)\n return Math.max(0, Math.round(end - start))\n}\n","import type { ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport {\n formatAttributes,\n formatLevel,\n formatMessage,\n formatScope,\n formatService,\n formatTimestamp,\n} from './shared'\n\nexport function formatLogRecord(record: ReadableLogRecord): string {\n const timestamp = formatTimestamp(record.hrTime)\n const service = formatService(record.resource)\n const level = formatLevel(record)\n const scope = formatScope(record.resource, record.instrumentationScope)\n const message = formatMessage(record)\n const attrs = formatAttributes(record.attributes)\n\n return `${service} ${timestamp} ${level} ${scope}${message}${attrs}`\n}\n","import type { Resource } from '@opentelemetry/resources'\nimport type {\n DataPoint,\n MetricData,\n ResourceMetrics,\n ScopeMetrics,\n} from '@opentelemetry/sdk-metrics'\nimport {\n formatAttributes,\n formatScope,\n formatService,\n formatTimestamp,\n} from './shared'\nimport { colors } from './style'\n\nexport function formatMetrics(resourceMetrics: ResourceMetrics): string {\n const { resource, scopeMetrics } = resourceMetrics\n\n return scopeMetrics\n .map((scopeMetric) => formatScopeMetric(scopeMetric, resource))\n .join('\\n')\n}\n\nfunction formatScopeMetric(\n scopeMetric: ScopeMetrics,\n resource: Resource\n): string {\n return scopeMetric.metrics\n .map((metric: MetricData) =>\n formatMetricData(metric, resource, scopeMetric.scope)\n )\n .join('\\n')\n}\n\nfunction formatMetricData(\n metric: MetricData,\n resource: Resource,\n scope: ScopeMetrics['scope']\n): string {\n const scopeStr = formatScope(resource, scope)\n const serviceStr = formatService(resource)\n\n const lines: string[] = []\n\n for (const dp of metric.dataPoints) {\n const ts = formatTimestamp(dp.startTime)\n const value = extractMetricValue(dp)\n const attrs = formatAttributes(dp.attributes ?? {})\n\n lines.push(\n `${serviceStr} ${ts} 📊 ${scopeStr}${colors.white(metric.descriptor.name)} ${colors.dim(value)}${attrs}`\n )\n }\n\n return lines.join('\\n')\n}\n\nfunction extractMetricValue(dp: DataPoint<unknown>): string {\n const value = dp.value\n\n if (typeof value === 'number') {\n return value.toString()\n }\n\n if (isHistogramLike(value)) {\n return value.sum.toString()\n }\n\n return '[complex]'\n}\n\nfunction isHistogramLike(val: unknown): val is { sum: number } {\n return (\n typeof val === 'object' &&\n val !== null &&\n 'sum' in val &&\n typeof (val as { sum: number }).sum === 'number'\n )\n}\n","import { SpanStatusCode } from '@opentelemetry/api'\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace'\nimport {\n calculateDuration,\n formatService,\n formatTimestamp,\n hrTimeToMillis,\n} from './shared'\nimport { colors, statusColorMap, statusLabelMap } from './style'\n\nconst LABEL_WIDTH = 20\nconst DESCRIPTION_MAX_WIDTH = 16\nconst BAR_MIN_WIDTH = 1\nconst BAR_MAX_WIDTH = 20\n\nexport function formatSpans(spans: ReadableSpan[]) {\n const rootSpan = spans[0]\n const rootStart = hrTimeToMillis(rootSpan.startTime)\n const rootEnd = hrTimeToMillis(rootSpan.endTime)\n const totalDuration = rootEnd - rootStart\n\n const service = formatService(rootSpan.resource)\n const timestamp = formatTimestamp(rootSpan.startTime)\n const traceId = colors.gray(`[${rootSpan.spanContext().traceId}]`)\n\n const lines = [`${service} ${timestamp} ${traceId}`]\n\n for (const span of spans) {\n const offset = hrTimeToMillis(span.startTime) - rootStart\n const depth = computeDepth(span, spans) // optional\n lines.push(\n formatSpan(span, {\n offsetMs: offset,\n totalDurationMs: totalDuration,\n depth,\n })\n )\n }\n\n return lines.join('\\n')\n}\n\nexport function formatSpan(\n span: ReadableSpan,\n opts: {\n offsetMs: number // relative start time in ms (0 for root)\n totalDurationMs: number // total duration in ms (root span duration)\n depth: number // nesting level for indent\n }\n): string {\n const label = formatLabel(span, opts.depth)\n const bar = buildBar(span, opts?.offsetMs, opts?.totalDurationMs)\n const barColor =\n span.status.code === SpanStatusCode.OK\n ? colors.green\n : span.status.code === SpanStatusCode.ERROR\n ? colors.red\n : colors.gray\n const desc = formatDescription(span)\n const status = formatStatus(span)\n const duration = formatDuration(span, opts?.offsetMs)\n const spanId = colors.gray(`[${span.spanContext().spanId}]`)\n\n return `${label} ${barColor(bar)} ${desc} ${status} ${duration} ${spanId}`\n}\n\nfunction formatLabel(span: ReadableSpan, depth: number) {\n const indent = ' '.repeat(depth) // 2 spaces per depth level\n const label = `${indent}└─ ${span.name}`\n return label.padEnd(LABEL_WIDTH)\n}\n\nfunction buildBar(\n span: ReadableSpan,\n offsetMs: number | undefined,\n totalDurationMs: number | undefined\n) {\n const duration = calculateDuration(span)\n\n if (\n typeof offsetMs !== 'number' ||\n typeof totalDurationMs !== 'number' ||\n totalDurationMs === 0\n ) {\n // fallback: show duration-only bar\n const capped = Math.min(duration, 1000)\n const barLength = Math.max(\n BAR_MIN_WIDTH,\n Math.round((capped / 1000) * BAR_MAX_WIDTH)\n )\n return '█'.repeat(barLength).padEnd(BAR_MAX_WIDTH + 2)\n }\n\n // Relative position and size\n const offsetRatio = Math.max(0, Math.min(offsetMs / totalDurationMs, 1))\n const durationRatio = Math.max(0, Math.min(duration / totalDurationMs, 1))\n\n const offsetChars = Math.floor(offsetRatio * BAR_MAX_WIDTH)\n const barChars = Math.max(\n BAR_MIN_WIDTH,\n Math.round(durationRatio * BAR_MAX_WIDTH)\n )\n\n const empty = ' '.repeat(offsetChars)\n const bar = '█'.repeat(barChars)\n\n return (empty + bar).padEnd(BAR_MAX_WIDTH + 2)\n}\n\nfunction formatDescription(span: ReadableSpan): string {\n const keyPriority = [\n // HTTP\n ['http.method', 'http.target'], // → GET /users/123\n ['http.route'], // → /users/:id\n ['http.url'], // → https://...\n\n // GraphQL\n ['graphql.operation.name'], // → getUsers\n ['graphql.operation.type'], // → query\n ['graphql.document'], // → full query text (maybe too long)\n\n // WebSocket\n ['ws.event'], // → connection, message, disconnect\n ['ws.message_type'], // → ping/pong/text/binary\n ['ws.url'], // → wss://...\n\n // Redis\n ['db.system', 'db.statement'], // → redis, \"SET foo bar\"\n ['db.operation'], // → GET, SET\n\n // Spanner\n ['db.statement'], // → SELECT * FROM...\n ['db.operation'], // → SELECT, INSERT\n ['db.name'], // → projects/.../instances/.../databases/...\n\n // OpenSearch\n ['db.operation'], // → search, index, bulk\n ['db.statement'], // → { query DSL... }\n\n // Pub/Sub (GCP)\n ['messaging.operation'], // → publish, receive\n ['messaging.destination'], // → topic-a\n ['messaging.gcp_pubsub.topic'], // → projects/x/topics/y\n\n // General FaaS\n ['faas.invoked_name'], // → myFunction\n ['faas.trigger'], // → http, pubsub, etc.\n\n // Custom or fallback\n ['otel.description'],\n ]\n\n for (const keys of keyPriority) {\n const parts = keys\n .map((k) => span.attributes[k])\n .filter((v) => v !== undefined && v !== null)\n .map((v) => String(v)) // 👈 FIX — guarantees string\n if (parts.length > 0) {\n return truncate(parts.join(' '), DESCRIPTION_MAX_WIDTH - 1).padEnd(\n DESCRIPTION_MAX_WIDTH\n )\n }\n }\n\n return ''.padEnd(DESCRIPTION_MAX_WIDTH)\n}\n\nfunction formatStatus(span: ReadableSpan): string {\n const code = span.status.code\n const label = statusLabelMap[code] ?? 'UNSET'\n const colorFn = statusColorMap[code] ?? colors.gray\n return colorFn(label).padEnd(6)\n}\n\nfunction formatDuration(\n span: ReadableSpan,\n offsetMs: number | undefined\n): string {\n const duration = calculateDuration(span)\n\n const format = (ms: number): string =>\n ms >= 1000 ? `${(ms / 1000).toFixed(2)} s` : `${ms} ms`\n\n return `(${format(offsetMs || 0)}–${format(duration)})`.padEnd(16)\n}\n\nfunction truncate(input: unknown, maxLength: number): string {\n // In practice, input is always a string — the String() cast is a defensive fallback.\n const str = String(input)\n return str.length > maxLength ? `${str.slice(0, maxLength - 1)}…` : str\n}\n\nfunction computeDepth(span: ReadableSpan, allSpans: ReadableSpan[]): number {\n let depth = 0\n let currentParentId = span.parentSpanContext?.spanId\n\n while (currentParentId) {\n const parentSpan = allSpans.find(\n (s) => s.spanContext().spanId === currentParentId\n )\n if (!parentSpan) break\n\n depth += 1\n currentParentId = parentSpan.parentSpanContext?.spanId\n }\n\n return depth\n}\n","/* istanbul ignore file */\nexport * from './log-record'\nexport * from './metrics'\nexport * from './span'\n","import { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type {\n PushMetricExporter,\n ResourceMetrics,\n} from '@opentelemetry/sdk-metrics'\nimport { formatMetrics } from './formatters/index'\n\nexport class ConsoleMetricPrettyExporter implements PushMetricExporter {\n private readonly patterns: RegExp[]\n\n constructor() {\n const raw = process.env.METRIC_FILTER ?? ''\n const entries = raw\n .split(',')\n .map((e) => e.trim())\n .filter(Boolean)\n\n this.patterns = entries.map(globToRegex)\n }\n\n private filterMetrics(\n resourceMetrics: ResourceMetrics\n ): ResourceMetrics | undefined {\n // No filter = block all metrics\n if (this.patterns.length === 0) return undefined\n\n const filteredScopes = resourceMetrics.scopeMetrics\n .map((scopeMetric) => {\n const filteredMetrics = scopeMetric.metrics.filter((metric) =>\n this.patterns.some((pattern) => pattern.test(metric.descriptor.name))\n )\n\n if (filteredMetrics.length === 0) return undefined\n\n return {\n ...scopeMetric,\n metrics: filteredMetrics,\n }\n })\n .filter((s): s is NonNullable<typeof s> => s !== undefined)\n\n if (filteredScopes.length === 0) return undefined\n\n return {\n ...resourceMetrics,\n scopeMetrics: filteredScopes,\n }\n }\n\n export(\n metrics: ResourceMetrics,\n resultCallback: (result: ExportResult) => void\n ): void {\n const filtered = this.filterMetrics(metrics)\n if (filtered) {\n console.log(formatMetrics(filtered))\n }\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve()\n }\n}\n\nfunction globToRegex(glob: string): RegExp {\n const escaped = glob.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n const regex = `^${escaped.replace(/\\*/g, '.*')}$`\n return new RegExp(regex)\n}\n","import { SeverityNumber } from '@opentelemetry/api'\nimport { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type {\n LogRecordExporter,\n ReadableLogRecord,\n} from '@opentelemetry/sdk-logs'\nimport { LOG_SEVERITY_MAP, type LOG_SEVERITY_NAME } from '../consts'\nimport { formatLogRecord } from './formatters/index'\n\nexport class ConsoleLogPrettyExporter implements LogRecordExporter {\n private readonly logThreshold: number\n constructor() {\n const defaultLogLevel = 'INFO'\n const env = (process.env.LOG_LEVEL?.toUpperCase() ??\n defaultLogLevel) as LOG_SEVERITY_NAME\n this.logThreshold =\n LOG_SEVERITY_MAP[env] ?? LOG_SEVERITY_MAP[defaultLogLevel]\n }\n export(\n logs: ReadableLogRecord[],\n resultCallback: (result: ExportResult) => void\n ): void {\n this._sendLogRecords(logs, resultCallback)\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve()\n }\n\n private _sendLogRecords(\n logRecords: ReadableLogRecord[],\n done: (result: ExportResult) => void\n ): void {\n for (const record of logRecords) {\n if ((record.severityNumber ?? 0) >= this.logThreshold) {\n const formatted = formatLogRecord(record)\n /* istanbul ignore next */\n const severity = record.severityNumber || SeverityNumber.UNSPECIFIED\n\n if (severity >= SeverityNumber.ERROR) {\n console.error(formatted)\n } else if (severity >= SeverityNumber.WARN) {\n console.log(formatted)\n } else if (severity >= SeverityNumber.INFO) {\n console.info(formatted)\n } else if (severity >= SeverityNumber.DEBUG) {\n console.debug(formatted)\n } else {\n console.trace(formatted)\n }\n }\n }\n\n done?.({ code: ExportResultCode.SUCCESS })\n }\n}\n","import { SpanStatusCode } from '@opentelemetry/api'\nimport { type ExportResult, ExportResultCode } from '@opentelemetry/core'\nimport type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace'\nimport { formatSpans } from './formatters/index'\n\nexport class ConsoleSpanPrettyExporter implements SpanExporter {\n private readonly allowedStatuses: Set<number>\n\n constructor() {\n const env = process.env.SPAN_LEVEL?.toUpperCase()\n if (!env) {\n this.allowedStatuses = new Set([\n SpanStatusCode.UNSET,\n SpanStatusCode.OK,\n SpanStatusCode.ERROR,\n ])\n } else {\n const map: Record<string, number> = {\n UNSET: SpanStatusCode.UNSET,\n OK: SpanStatusCode.OK,\n ERROR: SpanStatusCode.ERROR,\n }\n\n this.allowedStatuses = new Set(\n env\n .split(',')\n .map((s) => s.trim())\n .map((s) => map[s])\n .filter((v): v is number => typeof v === 'number')\n )\n }\n }\n\n private shouldExport(spans: ReadableSpan[]) {\n // print all spans\n if (this.allowedStatuses.size === 3) {\n return true\n }\n // print only certain levels\n return spans.some((span) => this.allowedStatuses.has(span.status.code))\n }\n\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void\n ): void {\n if (this.shouldExport(spans)) {\n console.log(formatSpans(spans))\n }\n\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve()\n }\n}\n","/* istanbul ignore file */\nexport * from './console-log-pretty-exporter'\nexport * from './console-span-pretty-exporter'\nexport * from './gcp-json-log-exporter'\n","import type {\n ReadableSpan,\n SpanExporter,\n SpanProcessor,\n} from '@opentelemetry/sdk-trace'\n\nexport class TreeSpanProcessor implements SpanProcessor {\n private exporter: SpanExporter\n private orphans: Map<string, ReadableSpan[]> = new Map()\n\n constructor(exporter: SpanExporter) {\n this.exporter = exporter\n }\n\n onStart(): void {\n // no-op\n }\n\n onEnd(span: ReadableSpan): void {\n const parentId = span.parentSpanContext?.spanId\n\n if (parentId) {\n const siblings = this.orphans.get(parentId) || []\n this.orphans.set(parentId, [...siblings, span])\n\n return\n }\n\n const children = this.getChildrenRecursively(span)\n const sorted = [span, ...children].sort((s1, s2) => {\n const [sec1, nano1] = s1.startTime\n const [sec2, nano2] = s2.startTime\n\n if (sec1 !== sec2) return sec1 - sec2\n return nano1 - nano2\n })\n this.exporter.export(sorted, () => {})\n }\n\n private getChildrenRecursively(span: ReadableSpan) {\n const spanId = span.spanContext().spanId\n const children = this.orphans.get(spanId) || []\n this.orphans.delete(spanId)\n\n const result = [...children]\n for (const child of children) {\n result.push(...this.getChildrenRecursively(child))\n }\n\n return result\n }\n\n shutdown(): Promise<void> {\n return this.exporter.shutdown()\n }\n\n async forceFlush(): Promise<void> {\n await this.exporter.forceFlush?.()\n }\n}\n","import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport type { Resource } from '@opentelemetry/resources'\nimport {\n BatchLogRecordProcessor,\n LoggerProvider,\n type LogRecordProcessor,\n SimpleLogRecordProcessor,\n} from '@opentelemetry/sdk-logs'\nimport { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\nimport {\n BatchSpanProcessor,\n SimpleSpanProcessor,\n type SpanProcessor,\n} from '@opentelemetry/sdk-trace'\nimport { ConsoleMetricPrettyExporter } from './loggers/console-metric-pretty-exporter'\nimport {\n ConsoleLogPrettyExporter,\n ConsoleSpanPrettyExporter,\n} from './loggers/index'\nimport { TreeSpanProcessor } from './loggers/tree-span-processor'\n\nexport const getLogProvider = (\n resource: Resource,\n otlpEndpoint: string | undefined\n) => {\n // With collector\n if (otlpEndpoint) {\n const otlpExporter = new OTLPLogExporter({ url: `${otlpEndpoint}/v1/logs` })\n const processors: LogRecordProcessor[] = [\n new BatchLogRecordProcessor({ exporter: otlpExporter }),\n ]\n\n // Console logging for cluster\n if (process.env.LOG_LEVEL) {\n const consoleExporter = new ConsoleLogPrettyExporter()\n processors.push(\n new SimpleLogRecordProcessor({ exporter: consoleExporter })\n )\n }\n\n return new LoggerProvider({\n resource,\n processors,\n })\n }\n\n // Local dev\n const consoleExporter = new ConsoleLogPrettyExporter()\n const processor = new SimpleLogRecordProcessor({ exporter: consoleExporter })\n return new LoggerProvider({\n resource,\n processors: [processor],\n })\n}\n\nexport const getSpanProcessor = (\n otlpEndpoint: string | undefined\n): SpanProcessor => {\n const exporter = otlpEndpoint\n ? new OTLPTraceExporter({\n url: `${otlpEndpoint}/v1/traces`,\n })\n : new ConsoleSpanPrettyExporter()\n\n if (!otlpEndpoint) {\n return new TreeSpanProcessor(exporter)\n }\n\n if (process.env.OTEL_SIMPLE_SPAN_PROCESSOR === 'true') {\n console.log(\n '[otel] Using SimpleSpanProcessor (OTEL_SIMPLE_SPAN_PROCESSOR=true)'\n )\n return new SimpleSpanProcessor({ exporter })\n }\n\n return new BatchSpanProcessor({ exporter })\n}\n\nexport const getMetricReader = (otlpEndpoint: string | undefined) => {\n const metricExporter = otlpEndpoint\n ? new OTLPMetricExporter({\n url: `${otlpEndpoint}/v1/metrics`,\n })\n : new ConsoleMetricPrettyExporter()\n const metricReader = new PeriodicExportingMetricReader({\n exporter: metricExporter,\n })\n\n return metricReader\n}\n","import {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions'\n\n/**\n * Extracts telemetry context from environment (cloud/k8s aware),\n * with support for subservice/component override.\n */\nexport function detectTelemetryContext(componentNameOverride?: string) {\n const {\n OTEL_SERVICE_NAME, // e.g. \"UserSystem\"\n OTEL_SERVICE_VERSION, // e.g. \"1.2.3\"\n K_SERVICE,\n K_REVISION,\n K_CONFIGURATION,\n KUBERNETES_SERVICE_HOST,\n POD_NAME,\n POD_NAMESPACE,\n GCP_PROJECT,\n CLOUD_PROVIDER,\n } = process.env\n\n const systemName = OTEL_SERVICE_NAME || 'unknown-service'\n const systemVersion = OTEL_SERVICE_VERSION || '1.0.0'\n\n // Only use component if explicitly provided\n const componentName = componentNameOverride || undefined\n\n const resourceAttributes = {\n [ATTR_SERVICE_NAME]: systemName,\n [ATTR_SERVICE_VERSION]: systemVersion,\n 'serviceContext.service': systemName,\n 'serviceContext.version': systemVersion,\n ...(K_SERVICE && { 'cloud.run.service': K_SERVICE }),\n ...(K_REVISION && { 'cloud.run.revision': K_REVISION }),\n ...(K_CONFIGURATION && { 'cloud.run.configuration': K_CONFIGURATION }),\n ...(POD_NAME && { 'k8s.pod_name': POD_NAME }),\n ...(POD_NAMESPACE && { 'k8s.namespace_name': POD_NAMESPACE }),\n ...(KUBERNETES_SERVICE_HOST && { 'cloud.orchestrator': 'kubernetes' }),\n ...(GCP_PROJECT && { 'cloud.account.id': GCP_PROJECT }),\n ...(CLOUD_PROVIDER && { 'cloud.provider': CLOUD_PROVIDER }),\n ...(componentName && { 'component.name': componentName }),\n }\n\n return {\n systemName,\n systemVersion,\n componentName,\n resourceAttributes,\n }\n}\n","import { containerDetector } from '@opentelemetry/resource-detector-container'\nimport { gcpDetector } from '@opentelemetry/resource-detector-gcp'\nimport {\n detectResources,\n envDetector,\n osDetector,\n processDetector,\n resourceFromAttributes,\n serviceInstanceIdDetector,\n} from '@opentelemetry/resources'\nimport { detectTelemetryContext } from './otel-context'\n\nconst isOnGcp = () =>\n !!(\n process.env.K_SERVICE ||\n process.env.GAE_APPLICATION ||\n process.env.KUBERNETES_SERVICE_HOST\n )\n\nexport const getResource = async () => {\n const baseRes = detectResources({\n detectors: [\n containerDetector,\n envDetector,\n ...(isOnGcp() ? [gcpDetector] : []),\n osDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n })\n\n if (baseRes.waitForAsyncAttributes) {\n await baseRes.waitForAsyncAttributes()\n }\n\n const { resourceAttributes } = detectTelemetryContext()\n const customRes = resourceFromAttributes(resourceAttributes)\n const resource = baseRes.merge(customRes)\n\n if (resource.waitForAsyncAttributes) {\n await resource.waitForAsyncAttributes()\n }\n\n return resource\n}\n","import {\n context,\n DiagConsoleLogger,\n DiagLogLevel,\n diag,\n logs,\n metrics,\n trace,\n} from '@opentelemetry/api'\nimport type { Instrumentation } from '@opentelemetry/instrumentation'\nimport type { LoggerProvider } from '@opentelemetry/sdk-logs'\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { getLogProvider, getMetricReader, getSpanProcessor } from './providers'\nimport { getResource } from './resource'\n\ndiag.disable()\ndiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR)\n\n// Use globalThis with a Symbol key so the flag is shared even when the module\n// is instantiated more than once (e.g. --import preload vs main app graph when\n// using tsx or other loaders that don't share the ESM module cache).\nconst OTEL_INIT_KEY = Symbol.for('@sebspark/otel:initialized')\nconst OTEL_INIT_PROMISE_KEY = Symbol.for('@sebspark/otel:initPromise')\n\nfunction getGlobal(): {\n [key: symbol]: unknown\n} {\n return globalThis as Record<symbol, unknown>\n}\n\nexport async function initialize(\n ...instrumentations: Promise<Instrumentation>[]\n) {\n const g = getGlobal()\n if (!g[OTEL_INIT_PROMISE_KEY]) {\n const resolvedInstrumentations = await Promise.all(instrumentations)\n const promise = _initialize(resolvedInstrumentations).catch((err) => {\n // Allow re-initialization if the first attempt fails\n g[OTEL_INIT_PROMISE_KEY] = undefined\n throw err\n })\n g[OTEL_INIT_PROMISE_KEY] = promise\n }\n return g[OTEL_INIT_PROMISE_KEY] as Promise<void>\n}\n\nexport function isInitialized() {\n return getGlobal()[OTEL_INIT_KEY] === true\n}\n\nlet sdk: NodeSDK | undefined\nlet logProvider: LoggerProvider | undefined\n\nasync function _initialize(instrumentations: Instrumentation[]) {\n const serviceName = process.env.OTEL_SERVICE_NAME ?? 'unknown-service'\n const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT\n\n const resource = await getResource()\n\n // Reset any previous instrumentation\n context.disable()\n logs.disable()\n trace.disable()\n metrics.disable()\n\n // Manual setup for logs\n logProvider = getLogProvider(resource, otlpEndpoint)\n logs.setGlobalLoggerProvider(logProvider)\n\n // NodeSDK setup\n const spanProcessor = getSpanProcessor(otlpEndpoint)\n const metricReader = getMetricReader(otlpEndpoint)\n sdk = new NodeSDK({\n spanProcessors: [spanProcessor],\n metricReaders: [metricReader],\n instrumentations,\n resource,\n })\n\n sdk.start()\n getGlobal()[OTEL_INIT_KEY] = true\n console.log(`[otel] Telemetry initialized for \"${serviceName}\"`)\n}\n\nexport const dispose = async () => {\n const processes: Promise<void>[] = []\n if (sdk) processes.push(sdk.shutdown())\n if (logProvider) processes.push(logProvider.shutdown())\n\n // Only initiate shotdown once\n sdk = undefined\n logProvider = undefined\n\n if (processes.length) {\n console.log('[otel] Shutting down...')\n await Promise.all(processes)\n console.log('[otel] Shutdown complete.')\n }\n}\n","import { context, logs, trace } from '@opentelemetry/api'\nimport { LOG_SEVERITY_MAP, type LOG_SEVERITY_NAME } from './consts'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\n// biome-ignore lint/suspicious/noExplicitAny: library\ntype Attrs = Record<string, any>\n\nexport type Logger = ReturnType<typeof getLogger>\nexport function getLogger(serviceOverride?: string, extraAttrs: Attrs = {}) {\n const { systemName, systemVersion, resourceAttributes } =\n detectTelemetryContext(serviceOverride)\n\n const defaultAttrs = {\n ...resourceAttributes,\n ...extraAttrs,\n }\n\n let hasWarnedAboutInit = false\n\n function emit(\n severityText: LOG_SEVERITY_NAME,\n body: string,\n attrs: Attrs = {}\n ) {\n // Get the logger at the last second\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n if (!hasWarnedAboutInit) {\n console.warn('OTEL must be initialized before using logger')\n hasWarnedAboutInit = true\n }\n console.log(`[${severityText}] ${body}`)\n return\n }\n const logger = logs.getLogger(systemName, systemVersion)\n\n const span = trace.getSpan(context.active())\n const spanContext = span?.spanContext()\n\n logger.emit({\n severityText,\n severityNumber: LOG_SEVERITY_MAP[severityText],\n body,\n attributes: {\n 'gcp.log_name': systemName.replace(/^@/, '').replace(/\\//g, '-'),\n ...defaultAttrs,\n ...(spanContext && {\n trace_id: spanContext.traceId,\n span_id: spanContext.spanId,\n }),\n ...attrs,\n },\n })\n }\n\n function resolveArgs(\n msg: string | Error,\n errOrAttrs?: Error | Attrs,\n maybeAttrs: Attrs = {}\n ): { body: string; attrs: Attrs } {\n if (errOrAttrs instanceof Error) {\n /* istanbul ignore next */\n const body = `${msg}: ${errOrAttrs.stack || errOrAttrs.message}`\n return { body, attrs: maybeAttrs }\n }\n\n /* istanbul ignore next */\n const body = msg instanceof Error ? msg.stack || msg.message : msg\n /* istanbul ignore next */\n const attrs = errOrAttrs || {}\n return { body, attrs }\n }\n\n type LogFn = {\n (msg: string, attrs?: Attrs): void\n (msg: string, error: Error, attrs?: Attrs): void\n (error: Error, attrs?: Attrs): void\n }\n\n function createLogFn(severity: LOG_SEVERITY_NAME): LogFn {\n return (\n msg: string | Error,\n errOrAttrs?: Error | Attrs,\n maybeAttrs: Attrs = {}\n ) => {\n const { body, attrs } = resolveArgs(msg, errOrAttrs, maybeAttrs)\n emit(severity, body, attrs)\n }\n }\n\n return {\n debug: createLogFn('DEBUG'),\n info: createLogFn('INFO'),\n notice: createLogFn('NOTICE'),\n warn: createLogFn('WARN'),\n error: createLogFn('ERROR'),\n critical: createLogFn('CRITICAL'),\n alert: createLogFn('ALERT'),\n emergency: createLogFn('EMERGENCY'),\n }\n}\n","import { metrics } from '@opentelemetry/api'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\nexport function getMeter(componentNameOverride?: string) {\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n console.warn('OTEL must be initialized before using getMeter()')\n }\n\n const { componentName, systemName, systemVersion } = detectTelemetryContext(\n componentNameOverride\n )\n return metrics.getMeter(componentName ?? systemName, systemVersion)\n}\n","import {\n context,\n type SpanOptions,\n SpanStatusCode,\n trace,\n} from '@opentelemetry/api'\nimport { isInitialized } from './otel'\nimport { detectTelemetryContext } from './otel-context'\n\ntype OtelTracer = ReturnType<typeof trace.getTracer>\ntype Span = ReturnType<OtelTracer['startSpan']>\n\ntype Func<T> = (span: Span) => Promise<T> | T\ntype SyncFunc<T> = (span: Span) => T\n\ntype WithTrace = {\n <T>(name: string, fn: Func<T>): Promise<T>\n <T>(name: string, options: SpanOptions, fn: Func<T>): Promise<T>\n <T>(name: string, parent: Span, fn: Func<T>): Promise<T>\n <T>(name: string, options: SpanOptions, parent: Span, fn: Func<T>): Promise<T>\n}\ntype WithTraceSync = {\n <T>(name: string, fn: SyncFunc<T>): T\n <T>(name: string, options: SpanOptions, fn: SyncFunc<T>): T\n <T>(name: string, parent: Span, fn: SyncFunc<T>): T\n <T>(name: string, options: SpanOptions, parent: Span, fn: SyncFunc<T>): T\n}\n\n/**\n * Extended tracer with helper methods for span-wrapped execution\n */\ninterface Tracer extends OtelTracer {\n withTrace: WithTrace\n withTraceSync: WithTraceSync\n}\n\n/**\n * Returns an OpenTelemetry tracer bound to the current service.\n * Includes `withTrace()` and `withTraceSync()` helpers for span-wrapped execution.\n *\n * @param serviceOverride - Optional override for service name\n * @returns Tracer with helpers\n */\nexport function getTracer(componentNameOverride?: string): Tracer {\n if (!isInitialized() && process.env.NODE_ENV !== 'test') {\n console.warn('OTEL must be initialized before calling getTracer()')\n }\n\n const { componentName, systemName, systemVersion } = detectTelemetryContext(\n componentNameOverride\n )\n const tracer = trace.getTracer(\n componentName ?? systemName,\n systemVersion\n ) as Tracer\n\n /**\n * Runs a function inside a new span (async variant).\n * Automatically handles span status and nesting.\n */\n const withTrace: WithTrace = async <T>(\n name: string,\n spanOptionsSpanOrFunc?: SpanOptions | Span | Func<T>,\n spanOrFunc?: Span | Func<T>,\n func?: Func<T>\n ): Promise<T> => {\n const { options, parent, fn } = extractArgs(\n spanOptionsSpanOrFunc,\n spanOrFunc,\n func\n )\n\n const parentContext = parent\n ? trace.setSpan(context.active(), parent)\n : context.active()\n\n const span = tracer.startSpan(name, options, parentContext)\n let ended = false\n const originalEnd = span.end.bind(span)\n const endOnce = () => {\n if (!ended) {\n ended = true\n originalEnd()\n }\n }\n span.end = endOnce\n\n return await context.with(trace.setSpan(parentContext, span), async () => {\n try {\n const result = await fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (err) {\n const error = err as Error\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n span.recordException?.(error)\n throw err\n } finally {\n endOnce()\n }\n })\n }\n\n /**\n * Runs a synchronous function inside a new span.\n * Automatically handles span status and nesting.\n */\n const withTraceSync: WithTraceSync = <T>(\n name: string,\n spanOptionsSpanOrFunc?: SpanOptions | Span | SyncFunc<T>,\n spanOrFunc?: Span | SyncFunc<T>,\n func?: SyncFunc<T>\n ): T => {\n const { options, parent, fn } = extractArgs(\n spanOptionsSpanOrFunc,\n spanOrFunc,\n func\n )\n\n const parentContext = parent\n ? trace.setSpan(context.active(), parent)\n : context.active()\n\n const span = tracer.startSpan(name, options, parentContext)\n let ended = false\n const originalEnd = span.end.bind(span)\n const endOnce = () => {\n if (!ended) {\n ended = true\n originalEnd()\n }\n }\n span.end = endOnce\n\n return context.with(trace.setSpan(parentContext, span), () => {\n try {\n const result = fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (err) {\n const error = err as Error\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n span.recordException?.(error)\n throw err\n } finally {\n endOnce()\n }\n })\n }\n\n tracer.withTrace = withTrace\n tracer.withTraceSync = withTraceSync\n\n return tracer\n}\n\ntype TraceArgs<T> = {\n options: SpanOptions\n parent?: Span\n fn: (span: Span) => T\n}\n\nfunction extractArgs<T>(\n spanOptionsSpanOrFunc?: SpanOptions | Span | ((span: Span) => T),\n spanOrFunc?: Span | ((span: Span) => T),\n func?: (span: Span) => T\n): TraceArgs<T> {\n let options: SpanOptions = {}\n let parent: Span | undefined\n let fn: (span: Span) => T\n\n if (isFunction(spanOptionsSpanOrFunc)) {\n fn = spanOptionsSpanOrFunc\n } else if (isFunction(spanOrFunc)) {\n const spanOrSpanOptions = spanOptionsSpanOrFunc as Span | SpanOptions\n if (isSpanOptions(spanOrSpanOptions)) {\n options = spanOrSpanOptions as SpanOptions\n } else {\n parent = spanOrSpanOptions as Span\n }\n fn = spanOrFunc\n } else {\n options = spanOptionsSpanOrFunc as SpanOptions\n parent = spanOrFunc as Span\n // biome-ignore lint/style/noNonNullAssertion: it IS defined here\n fn = func!\n }\n\n return { options, parent, fn }\n}\n\nconst isFunction = (value: unknown): value is (span: Span) => unknown =>\n typeof value === 'function'\nconst isSpan = (value: unknown): value is Span =>\n value !== null &&\n value !== undefined &&\n isFunction((value as Span).spanContext) &&\n isFunction((value as Span).end)\n/* istanbul ignore next */\nconst isSpanOptions = (value: unknown): value is SpanOptions =>\n value !== null &&\n value !== undefined &&\n (!!(value as SpanOptions).startTime ||\n !!(value as SpanOptions).attributes ||\n !!(value as SpanOptions).kind) &&\n !isSpan(value)\n","/* istanbul ignore file */\nexport {\n type Context,\n type Counter,\n context,\n type Gauge,\n type Histogram,\n type Meter,\n type ObservableCounter,\n type ObservableGauge,\n type ObservableUpDownCounter,\n type Span,\n type SpanStatus,\n SpanStatusCode,\n type UpDownCounter,\n} from '@opentelemetry/api'\nexport * from './instrumentations'\nexport * from './logger'\nexport * from './metrics'\nexport * from './otel'\nexport * from './tracer'\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebspark/otel",
3
- "version": "4.1.16",
3
+ "version": "4.2.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -18,58 +18,54 @@
18
18
  "build": "spark-build src/index.ts",
19
19
  "dev": "tsc --watch --noEmit",
20
20
  "lint": "biome check .",
21
- "test": "vitest run --passWithNoTests --coverage",
22
- "test:e2e": "vitest --config vitest.config.e2e.ts --run",
21
+ "test": "vitest run --passWithNoTests --coverage --fsModuleCachePath node_modules/.vitest-cache",
22
+ "test:e2e": "vitest --config vitest.config.e2e.ts --run --fsModuleCachePath node_modules/.vitest-cache",
23
23
  "typecheck": "vitest --typecheck.only --passWithNoTests --run"
24
24
  },
25
25
  "dependencies": {
26
- "@opentelemetry/api": "1.9.1",
27
- "@opentelemetry/api-logs": "0.222.0",
28
- "@opentelemetry/core": "2.11.0",
29
- "@opentelemetry/exporter-logs-otlp-http": "0.222.0",
30
- "@opentelemetry/exporter-metrics-otlp-http": "0.222.0",
31
- "@opentelemetry/exporter-trace-otlp-http": "0.222.0",
32
- "@opentelemetry/instrumentation": "0.222.0",
33
- "@opentelemetry/instrumentation-dns": "0.65.0",
34
- "@opentelemetry/instrumentation-express": "0.70.0",
35
- "@opentelemetry/instrumentation-fs": "0.41.0",
36
- "@opentelemetry/instrumentation-grpc": "0.222.0",
37
- "@opentelemetry/instrumentation-http": "0.222.0",
38
- "@opentelemetry/instrumentation-net": "0.66.0",
39
- "@opentelemetry/instrumentation-redis": "0.70.0",
40
- "@opentelemetry/instrumentation-socket.io": "0.69.0",
41
- "@opentelemetry/instrumentation-undici": "0.32.0",
42
- "@opentelemetry/resource-detector-container": "0.8.13",
43
- "@opentelemetry/resource-detector-gcp": "0.57.0",
44
- "@opentelemetry/resources": "2.11.0",
45
- "@opentelemetry/sdk-logs": "0.222.0",
46
- "@opentelemetry/sdk-metrics": "2.11.0",
47
- "@opentelemetry/sdk-node": "0.222.0",
48
- "@opentelemetry/sdk-trace-node": "2.11.0",
26
+ "@opentelemetry/api": "1.10.0",
27
+ "@opentelemetry/core": "3.0.0",
28
+ "@opentelemetry/exporter-logs-otlp-http": "0.300.0",
29
+ "@opentelemetry/exporter-metrics-otlp-http": "0.300.0",
30
+ "@opentelemetry/exporter-trace-otlp-http": "0.300.0",
31
+ "@opentelemetry/instrumentation": "0.300.0",
32
+ "@opentelemetry/instrumentation-dns": "0.67.0",
33
+ "@opentelemetry/instrumentation-express": "0.72.0",
34
+ "@opentelemetry/instrumentation-fs": "0.43.0",
35
+ "@opentelemetry/instrumentation-grpc": "0.300.0",
36
+ "@opentelemetry/instrumentation-http": "0.300.0",
37
+ "@opentelemetry/instrumentation-net": "0.68.0",
38
+ "@opentelemetry/instrumentation-redis": "0.72.0",
39
+ "@opentelemetry/instrumentation-socket.io": "0.71.0",
40
+ "@opentelemetry/instrumentation-undici": "0.34.0",
41
+ "@opentelemetry/resource-detector-container": "0.9.0",
42
+ "@opentelemetry/resource-detector-gcp": "0.59.0",
43
+ "@opentelemetry/resources": "3.0.0",
44
+ "@opentelemetry/sdk-logs": "3.0.0",
45
+ "@opentelemetry/sdk-metrics": "3.0.0",
46
+ "@opentelemetry/sdk-node": "0.300.0",
47
+ "@opentelemetry/sdk-trace": "3.0.0",
49
48
  "@opentelemetry/semantic-conventions": "1.43.0",
50
- "@sebspark/opentelemetry-instrumentation-opensearch": "0.3.14",
49
+ "@sebspark/opentelemetry-instrumentation-opensearch": "0.4.0",
51
50
  "fast-safe-stringify": "2.1.1",
52
51
  "kleur": "4.1.5",
53
- "yaml": "2.9.0"
52
+ "yaml": "2.9.1"
54
53
  },
55
54
  "devDependencies": {
56
- "@biomejs/biome": "2.5.12",
57
- "@opensearch-project/opensearch": "3.6.0",
58
- "@opentelemetry/context-async-hooks": "2.11.0",
59
- "@sebspark/tsconfig": "*",
60
- "@testcontainers/opensearch": "12.1.0",
61
- "@testcontainers/redis": "12.1.0",
55
+ "@biomejs/biome": "2.6.3",
56
+ "@opensearch-project/opensearch": "3.9.0",
57
+ "@opentelemetry/context-async-hooks": "3.0.0",
58
+ "@sebspark/tsconfig": "3.0.26",
59
+ "@testcontainers/opensearch": "12.2.1",
60
+ "@testcontainers/redis": "12.2.1",
62
61
  "axios": "1.20.0",
63
- "express": "5.2.1",
62
+ "express": "5.3.0",
64
63
  "find-free-ports": "3.1.1",
65
- "redis": "6.2.1",
64
+ "redis": "6.3.0",
66
65
  "typescript": "7.0.2",
67
- "undici": "8.10.2",
68
- "vite": "8.2.2",
69
- "vitest": "5.0.0"
70
- },
71
- "resolutions": {
72
- "protobufjs": "8.8.0"
66
+ "undici": "8.12.3",
67
+ "vite": "8.3.5",
68
+ "vitest": "5.0.5"
73
69
  },
74
70
  "repository": {
75
71
  "type": "git",