autotel 2.1.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.
Files changed (272) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1946 -0
  3. package/dist/chunk-2LNRY4QK.js +273 -0
  4. package/dist/chunk-2LNRY4QK.js.map +1 -0
  5. package/dist/chunk-3HENGDW2.js +587 -0
  6. package/dist/chunk-3HENGDW2.js.map +1 -0
  7. package/dist/chunk-4OAT42CA.cjs +73 -0
  8. package/dist/chunk-4OAT42CA.cjs.map +1 -0
  9. package/dist/chunk-5GWX5LFW.js +70 -0
  10. package/dist/chunk-5GWX5LFW.js.map +1 -0
  11. package/dist/chunk-5R2M36QB.js +195 -0
  12. package/dist/chunk-5R2M36QB.js.map +1 -0
  13. package/dist/chunk-5ZN622AO.js +73 -0
  14. package/dist/chunk-5ZN622AO.js.map +1 -0
  15. package/dist/chunk-77MSMAUQ.cjs +498 -0
  16. package/dist/chunk-77MSMAUQ.cjs.map +1 -0
  17. package/dist/chunk-ABPEQ6RK.cjs +596 -0
  18. package/dist/chunk-ABPEQ6RK.cjs.map +1 -0
  19. package/dist/chunk-BWYGJKRB.js +95 -0
  20. package/dist/chunk-BWYGJKRB.js.map +1 -0
  21. package/dist/chunk-BZHG5IZ4.js +73 -0
  22. package/dist/chunk-BZHG5IZ4.js.map +1 -0
  23. package/dist/chunk-G7VZBCD6.cjs +35 -0
  24. package/dist/chunk-G7VZBCD6.cjs.map +1 -0
  25. package/dist/chunk-GVLK7YUU.cjs +30 -0
  26. package/dist/chunk-GVLK7YUU.cjs.map +1 -0
  27. package/dist/chunk-HCCXC7XG.js +205 -0
  28. package/dist/chunk-HCCXC7XG.js.map +1 -0
  29. package/dist/chunk-HE6T6FIX.cjs +203 -0
  30. package/dist/chunk-HE6T6FIX.cjs.map +1 -0
  31. package/dist/chunk-KIXWPOCO.cjs +100 -0
  32. package/dist/chunk-KIXWPOCO.cjs.map +1 -0
  33. package/dist/chunk-KVGNW3FC.js +87 -0
  34. package/dist/chunk-KVGNW3FC.js.map +1 -0
  35. package/dist/chunk-LITNXTTT.js +3 -0
  36. package/dist/chunk-LITNXTTT.js.map +1 -0
  37. package/dist/chunk-M4ANN7RL.js +114 -0
  38. package/dist/chunk-M4ANN7RL.js.map +1 -0
  39. package/dist/chunk-NC52UBR2.cjs +32 -0
  40. package/dist/chunk-NC52UBR2.cjs.map +1 -0
  41. package/dist/chunk-NHCNRQD3.cjs +212 -0
  42. package/dist/chunk-NHCNRQD3.cjs.map +1 -0
  43. package/dist/chunk-NZ72VDNY.cjs +4 -0
  44. package/dist/chunk-NZ72VDNY.cjs.map +1 -0
  45. package/dist/chunk-P6JUDYNO.js +57 -0
  46. package/dist/chunk-P6JUDYNO.js.map +1 -0
  47. package/dist/chunk-RJYY7BWX.js +1349 -0
  48. package/dist/chunk-RJYY7BWX.js.map +1 -0
  49. package/dist/chunk-TRI4V5BF.cjs +126 -0
  50. package/dist/chunk-TRI4V5BF.cjs.map +1 -0
  51. package/dist/chunk-UL33I6IS.js +139 -0
  52. package/dist/chunk-UL33I6IS.js.map +1 -0
  53. package/dist/chunk-URRW6M2C.cjs +61 -0
  54. package/dist/chunk-URRW6M2C.cjs.map +1 -0
  55. package/dist/chunk-UY3UYPBZ.cjs +77 -0
  56. package/dist/chunk-UY3UYPBZ.cjs.map +1 -0
  57. package/dist/chunk-W3253FGB.cjs +277 -0
  58. package/dist/chunk-W3253FGB.cjs.map +1 -0
  59. package/dist/chunk-W7LHZVQF.js +26 -0
  60. package/dist/chunk-W7LHZVQF.js.map +1 -0
  61. package/dist/chunk-WBWNM6LB.cjs +1360 -0
  62. package/dist/chunk-WBWNM6LB.cjs.map +1 -0
  63. package/dist/chunk-WFJ7L2RV.js +494 -0
  64. package/dist/chunk-WFJ7L2RV.js.map +1 -0
  65. package/dist/chunk-X4RMFFMR.js +28 -0
  66. package/dist/chunk-X4RMFFMR.js.map +1 -0
  67. package/dist/chunk-Y4Y2S7BM.cjs +92 -0
  68. package/dist/chunk-Y4Y2S7BM.cjs.map +1 -0
  69. package/dist/chunk-YLPNXZFI.cjs +143 -0
  70. package/dist/chunk-YLPNXZFI.cjs.map +1 -0
  71. package/dist/chunk-YTXEZ4SD.cjs +77 -0
  72. package/dist/chunk-YTXEZ4SD.cjs.map +1 -0
  73. package/dist/chunk-Z6ZWNWWR.js +30 -0
  74. package/dist/chunk-Z6ZWNWWR.js.map +1 -0
  75. package/dist/config.cjs +26 -0
  76. package/dist/config.cjs.map +1 -0
  77. package/dist/config.d.cts +75 -0
  78. package/dist/config.d.ts +75 -0
  79. package/dist/config.js +5 -0
  80. package/dist/config.js.map +1 -0
  81. package/dist/db.cjs +233 -0
  82. package/dist/db.cjs.map +1 -0
  83. package/dist/db.d.cts +123 -0
  84. package/dist/db.d.ts +123 -0
  85. package/dist/db.js +228 -0
  86. package/dist/db.js.map +1 -0
  87. package/dist/decorators.cjs +67 -0
  88. package/dist/decorators.cjs.map +1 -0
  89. package/dist/decorators.d.cts +91 -0
  90. package/dist/decorators.d.ts +91 -0
  91. package/dist/decorators.js +65 -0
  92. package/dist/decorators.js.map +1 -0
  93. package/dist/event-subscriber.cjs +6 -0
  94. package/dist/event-subscriber.cjs.map +1 -0
  95. package/dist/event-subscriber.d.cts +116 -0
  96. package/dist/event-subscriber.d.ts +116 -0
  97. package/dist/event-subscriber.js +3 -0
  98. package/dist/event-subscriber.js.map +1 -0
  99. package/dist/event-testing.cjs +21 -0
  100. package/dist/event-testing.cjs.map +1 -0
  101. package/dist/event-testing.d.cts +110 -0
  102. package/dist/event-testing.d.ts +110 -0
  103. package/dist/event-testing.js +4 -0
  104. package/dist/event-testing.js.map +1 -0
  105. package/dist/event.cjs +30 -0
  106. package/dist/event.cjs.map +1 -0
  107. package/dist/event.d.cts +282 -0
  108. package/dist/event.d.ts +282 -0
  109. package/dist/event.js +13 -0
  110. package/dist/event.js.map +1 -0
  111. package/dist/exporters.cjs +17 -0
  112. package/dist/exporters.cjs.map +1 -0
  113. package/dist/exporters.d.cts +1 -0
  114. package/dist/exporters.d.ts +1 -0
  115. package/dist/exporters.js +4 -0
  116. package/dist/exporters.js.map +1 -0
  117. package/dist/functional.cjs +46 -0
  118. package/dist/functional.cjs.map +1 -0
  119. package/dist/functional.d.cts +478 -0
  120. package/dist/functional.d.ts +478 -0
  121. package/dist/functional.js +13 -0
  122. package/dist/functional.js.map +1 -0
  123. package/dist/http.cjs +189 -0
  124. package/dist/http.cjs.map +1 -0
  125. package/dist/http.d.cts +169 -0
  126. package/dist/http.d.ts +169 -0
  127. package/dist/http.js +184 -0
  128. package/dist/http.js.map +1 -0
  129. package/dist/index.cjs +333 -0
  130. package/dist/index.cjs.map +1 -0
  131. package/dist/index.d.cts +758 -0
  132. package/dist/index.d.ts +758 -0
  133. package/dist/index.js +143 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/instrumentation.cjs +182 -0
  136. package/dist/instrumentation.cjs.map +1 -0
  137. package/dist/instrumentation.d.cts +49 -0
  138. package/dist/instrumentation.d.ts +49 -0
  139. package/dist/instrumentation.js +179 -0
  140. package/dist/instrumentation.js.map +1 -0
  141. package/dist/logger.cjs +19 -0
  142. package/dist/logger.cjs.map +1 -0
  143. package/dist/logger.d.cts +146 -0
  144. package/dist/logger.d.ts +146 -0
  145. package/dist/logger.js +6 -0
  146. package/dist/logger.js.map +1 -0
  147. package/dist/metric-helpers.cjs +31 -0
  148. package/dist/metric-helpers.cjs.map +1 -0
  149. package/dist/metric-helpers.d.cts +13 -0
  150. package/dist/metric-helpers.d.ts +13 -0
  151. package/dist/metric-helpers.js +6 -0
  152. package/dist/metric-helpers.js.map +1 -0
  153. package/dist/metric-testing.cjs +21 -0
  154. package/dist/metric-testing.cjs.map +1 -0
  155. package/dist/metric-testing.d.cts +110 -0
  156. package/dist/metric-testing.d.ts +110 -0
  157. package/dist/metric-testing.js +4 -0
  158. package/dist/metric-testing.js.map +1 -0
  159. package/dist/metric.cjs +26 -0
  160. package/dist/metric.cjs.map +1 -0
  161. package/dist/metric.d.cts +240 -0
  162. package/dist/metric.d.ts +240 -0
  163. package/dist/metric.js +9 -0
  164. package/dist/metric.js.map +1 -0
  165. package/dist/processors.cjs +17 -0
  166. package/dist/processors.cjs.map +1 -0
  167. package/dist/processors.d.cts +1 -0
  168. package/dist/processors.d.ts +1 -0
  169. package/dist/processors.js +4 -0
  170. package/dist/processors.js.map +1 -0
  171. package/dist/sampling.cjs +40 -0
  172. package/dist/sampling.cjs.map +1 -0
  173. package/dist/sampling.d.cts +260 -0
  174. package/dist/sampling.d.ts +260 -0
  175. package/dist/sampling.js +7 -0
  176. package/dist/sampling.js.map +1 -0
  177. package/dist/semantic-helpers.cjs +35 -0
  178. package/dist/semantic-helpers.cjs.map +1 -0
  179. package/dist/semantic-helpers.d.cts +442 -0
  180. package/dist/semantic-helpers.d.ts +442 -0
  181. package/dist/semantic-helpers.js +14 -0
  182. package/dist/semantic-helpers.js.map +1 -0
  183. package/dist/tail-sampling-processor.cjs +13 -0
  184. package/dist/tail-sampling-processor.cjs.map +1 -0
  185. package/dist/tail-sampling-processor.d.cts +27 -0
  186. package/dist/tail-sampling-processor.d.ts +27 -0
  187. package/dist/tail-sampling-processor.js +4 -0
  188. package/dist/tail-sampling-processor.js.map +1 -0
  189. package/dist/testing.cjs +286 -0
  190. package/dist/testing.cjs.map +1 -0
  191. package/dist/testing.d.cts +291 -0
  192. package/dist/testing.d.ts +291 -0
  193. package/dist/testing.js +263 -0
  194. package/dist/testing.js.map +1 -0
  195. package/dist/trace-context-DRZdUvVY.d.cts +181 -0
  196. package/dist/trace-context-DRZdUvVY.d.ts +181 -0
  197. package/dist/trace-helpers.cjs +54 -0
  198. package/dist/trace-helpers.cjs.map +1 -0
  199. package/dist/trace-helpers.d.cts +524 -0
  200. package/dist/trace-helpers.d.ts +524 -0
  201. package/dist/trace-helpers.js +5 -0
  202. package/dist/trace-helpers.js.map +1 -0
  203. package/dist/tracer-provider.cjs +21 -0
  204. package/dist/tracer-provider.cjs.map +1 -0
  205. package/dist/tracer-provider.d.cts +169 -0
  206. package/dist/tracer-provider.d.ts +169 -0
  207. package/dist/tracer-provider.js +4 -0
  208. package/dist/tracer-provider.js.map +1 -0
  209. package/package.json +280 -0
  210. package/src/baggage-span-processor.test.ts +202 -0
  211. package/src/baggage-span-processor.ts +98 -0
  212. package/src/circuit-breaker.test.ts +341 -0
  213. package/src/circuit-breaker.ts +184 -0
  214. package/src/config.test.ts +94 -0
  215. package/src/config.ts +169 -0
  216. package/src/db.test.ts +252 -0
  217. package/src/db.ts +447 -0
  218. package/src/decorators.test.ts +203 -0
  219. package/src/decorators.ts +188 -0
  220. package/src/env-config.test.ts +246 -0
  221. package/src/env-config.ts +158 -0
  222. package/src/event-queue.test.ts +222 -0
  223. package/src/event-queue.ts +203 -0
  224. package/src/event-subscriber.ts +136 -0
  225. package/src/event-testing.ts +197 -0
  226. package/src/event.test.ts +718 -0
  227. package/src/event.ts +556 -0
  228. package/src/exporters.ts +96 -0
  229. package/src/functional.test.ts +1059 -0
  230. package/src/functional.ts +2295 -0
  231. package/src/http.test.ts +487 -0
  232. package/src/http.ts +424 -0
  233. package/src/index.ts +158 -0
  234. package/src/init.customization.test.ts +210 -0
  235. package/src/init.integrations.test.ts +366 -0
  236. package/src/init.openllmetry.test.ts +282 -0
  237. package/src/init.protocol.test.ts +215 -0
  238. package/src/init.ts +1426 -0
  239. package/src/instrumentation.test.ts +108 -0
  240. package/src/instrumentation.ts +308 -0
  241. package/src/logger.test.ts +117 -0
  242. package/src/logger.ts +246 -0
  243. package/src/metric-helpers.ts +47 -0
  244. package/src/metric-testing.ts +197 -0
  245. package/src/metric.ts +434 -0
  246. package/src/metrics.test.ts +205 -0
  247. package/src/operation-context.ts +93 -0
  248. package/src/processors.ts +106 -0
  249. package/src/rate-limiter.test.ts +199 -0
  250. package/src/rate-limiter.ts +98 -0
  251. package/src/sampling.test.ts +513 -0
  252. package/src/sampling.ts +428 -0
  253. package/src/semantic-helpers.test.ts +311 -0
  254. package/src/semantic-helpers.ts +584 -0
  255. package/src/shutdown.test.ts +311 -0
  256. package/src/shutdown.ts +222 -0
  257. package/src/stub.integration.test.ts +361 -0
  258. package/src/tail-sampling-processor.test.ts +226 -0
  259. package/src/tail-sampling-processor.ts +51 -0
  260. package/src/testing.ts +670 -0
  261. package/src/trace-context.ts +470 -0
  262. package/src/trace-helpers.new.test.ts +278 -0
  263. package/src/trace-helpers.test.ts +242 -0
  264. package/src/trace-helpers.ts +690 -0
  265. package/src/tracer-provider.test.ts +183 -0
  266. package/src/tracer-provider.ts +266 -0
  267. package/src/track.test.ts +153 -0
  268. package/src/track.ts +120 -0
  269. package/src/validation.test.ts +306 -0
  270. package/src/validation.ts +239 -0
  271. package/src/variable-name-inference.test.ts +178 -0
  272. package/src/variable-name-inference.ts +242 -0
package/dist/index.js ADDED
@@ -0,0 +1,143 @@
1
+ import { resetMetrics } from './chunk-2LNRY4QK.js';
2
+ export { Metric, getMetrics, resetMetrics } from './chunk-2LNRY4QK.js';
3
+ import './chunk-5ZN622AO.js';
4
+ export { createCounter, createHistogram, createObservableGauge, createUpDownCounter, getMeter } from './chunk-W7LHZVQF.js';
5
+ export { traceDB, traceHTTP, traceLLM, traceMessaging } from './chunk-BWYGJKRB.js';
6
+ import { resetEventQueue, getEventQueue } from './chunk-RJYY7BWX.js';
7
+ export { ctx, instrument, span, trace, track, withBaggage, withNewContext, withTracing } from './chunk-RJYY7BWX.js';
8
+ export { createDeterministicTraceId, finalizeSpan, flattenMetadata, getActiveContext, getActiveSpan, getTracer, runWithSpan } from './chunk-M4ANN7RL.js';
9
+ import { init_trace_context } from './chunk-HCCXC7XG.js';
10
+ export { defineBaggageSchema } from './chunk-HCCXC7XG.js';
11
+ import { resetEvents } from './chunk-WFJ7L2RV.js';
12
+ export { Event, getEvents, resetEvents } from './chunk-WFJ7L2RV.js';
13
+ import './chunk-LITNXTTT.js';
14
+ import './chunk-BZHG5IZ4.js';
15
+ export { getOperationContext, runInOperationContext } from './chunk-UL33I6IS.js';
16
+ import { getLogger, getSdk } from './chunk-3HENGDW2.js';
17
+ export { BaggageSpanProcessor, init } from './chunk-3HENGDW2.js';
18
+ import './chunk-X4RMFFMR.js';
19
+ export { AdaptiveSampler, AlwaysSampler, NeverSampler, RandomSampler, UserIdSampler } from './chunk-5R2M36QB.js';
20
+ import './chunk-5GWX5LFW.js';
21
+ import './chunk-KVGNW3FC.js';
22
+ export { getAutotelTracer, getAutotelTracerProvider, setAutotelTracerProvider } from './chunk-P6JUDYNO.js';
23
+ import './chunk-Z6ZWNWWR.js';
24
+ export { SpanKind, SpanStatusCode, context, trace as otelTrace, propagation } from '@opentelemetry/api';
25
+
26
+ // src/shutdown.ts
27
+ async function flush(options) {
28
+ const timeout = options?.timeout ?? 2e3;
29
+ const doFlush = async () => {
30
+ const eventsQueue = getEventQueue();
31
+ if (eventsQueue) {
32
+ await eventsQueue.flush();
33
+ }
34
+ const sdk = getSdk();
35
+ if (sdk) {
36
+ try {
37
+ const sdkAny = sdk;
38
+ if (typeof sdkAny.getTracerProvider === "function") {
39
+ const tracerProvider = sdkAny.getTracerProvider();
40
+ if (tracerProvider && typeof tracerProvider.forceFlush === "function") {
41
+ await tracerProvider.forceFlush();
42
+ }
43
+ }
44
+ } catch {
45
+ }
46
+ }
47
+ };
48
+ let timeoutHandle;
49
+ try {
50
+ await Promise.race([
51
+ doFlush().finally(() => {
52
+ if (timeoutHandle) {
53
+ clearTimeout(timeoutHandle);
54
+ }
55
+ }),
56
+ new Promise((_, reject) => {
57
+ timeoutHandle = setTimeout(
58
+ () => reject(new Error("Flush timeout")),
59
+ timeout
60
+ );
61
+ timeoutHandle.unref();
62
+ })
63
+ ]);
64
+ } catch (error) {
65
+ if (timeoutHandle) {
66
+ clearTimeout(timeoutHandle);
67
+ }
68
+ const logger = getLogger();
69
+ logger.error(
70
+ "[autotel] Flush error:",
71
+ error instanceof Error ? error : new Error(String(error))
72
+ );
73
+ throw error;
74
+ }
75
+ }
76
+ async function shutdown() {
77
+ const logger = getLogger();
78
+ let shutdownError = null;
79
+ try {
80
+ await flush();
81
+ } catch (error) {
82
+ const err = error instanceof Error ? error : new Error(String(error));
83
+ shutdownError = err;
84
+ logger.error(
85
+ "[autotel] Flush failed during shutdown, continuing cleanup",
86
+ err
87
+ );
88
+ }
89
+ try {
90
+ const sdk = getSdk();
91
+ if (sdk) {
92
+ await sdk.shutdown();
93
+ }
94
+ } catch (error) {
95
+ const err = error instanceof Error ? error : new Error(String(error));
96
+ const isConnectionRefused = typeof error === "object" && error !== null && "code" in error && error.code === "ECONNREFUSED";
97
+ if (!isConnectionRefused) {
98
+ if (!shutdownError) {
99
+ shutdownError = err;
100
+ }
101
+ logger.error("[autotel] SDK shutdown failed", err);
102
+ }
103
+ } finally {
104
+ resetEvents();
105
+ resetMetrics();
106
+ resetEventQueue();
107
+ }
108
+ if (shutdownError) {
109
+ throw shutdownError;
110
+ }
111
+ }
112
+ function registerShutdownHooks() {
113
+ if (typeof process === "undefined") return;
114
+ const signals = ["SIGTERM", "SIGINT"];
115
+ let shuttingDown = false;
116
+ for (const signal of signals) {
117
+ process.on(signal, async () => {
118
+ if (shuttingDown) return;
119
+ shuttingDown = true;
120
+ if (process.env.NODE_ENV !== "test") {
121
+ getLogger().info(`[autotel] Received ${signal}, flushing telemetry...`);
122
+ }
123
+ try {
124
+ await shutdown();
125
+ } catch (error) {
126
+ getLogger().error(
127
+ "[autotel] Error during shutdown",
128
+ error instanceof Error ? error : void 0
129
+ );
130
+ } finally {
131
+ process.exit(0);
132
+ }
133
+ });
134
+ }
135
+ }
136
+ registerShutdownHooks();
137
+
138
+ // src/index.ts
139
+ init_trace_context();
140
+
141
+ export { flush, shutdown };
142
+ //# sourceMappingURL=index.js.map
143
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shutdown.ts","../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,eAAsB,MAAM,OAAA,EAA+C;AACzE,EAAA,MAAM,OAAA,GAAU,SAAS,OAAA,IAAW,GAAA;AAEpC,EAAA,MAAM,UAAU,YAAY;AAE1B,IAAA,MAAM,cAAc,aAAA,EAAc;AAClC,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,MAAM,YAAY,KAAA,EAAM;AAAA,IAC1B;AAIA,IAAA,MAAM,MAAM,MAAA,EAAO;AACnB,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,IAAI;AAGF,QAAA,MAAM,MAAA,GAAS,GAAA;AACf,QAAA,IAAI,OAAO,MAAA,CAAO,iBAAA,KAAsB,UAAA,EAAY;AAClD,UAAA,MAAM,cAAA,GAAiB,OAAO,iBAAA,EAAkB;AAChD,UAAA,IACE,cAAA,IACA,OAAO,cAAA,CAAe,UAAA,KAAe,UAAA,EACrC;AACA,YAAA,MAAM,eAAe,UAAA,EAAW;AAAA,UAClC;AAAA,QACF;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAA;AAGA,EAAA,IAAI,aAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,QAAQ,IAAA,CAAK;AAAA,MACjB,OAAA,EAAQ,CAAE,OAAA,CAAQ,MAAM;AAEtB,QAAA,IAAI,aAAA,EAAe;AACjB,UAAA,YAAA,CAAa,aAAa,CAAA;AAAA,QAC5B;AAAA,MACF,CAAC,CAAA;AAAA,MACD,IAAI,OAAA,CAAc,CAAC,CAAA,EAAG,MAAA,KAAW;AAC/B,QAAA,aAAA,GAAgB,UAAA;AAAA,UACd,MAAM,MAAA,CAAO,IAAI,KAAA,CAAM,eAAe,CAAC,CAAA;AAAA,UACvC;AAAA,SACF;AAGA,QAAA,aAAA,CAAc,KAAA,EAAM;AAAA,MACtB,CAAC;AAAA,KACF,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AAEd,IAAA,IAAI,aAAA,EAAe;AACjB,MAAA,YAAA,CAAa,aAAa,CAAA;AAAA,IAC5B;AACA,IAAA,MAAM,SAAS,SAAA,EAAU;AACzB,IAAA,MAAA,CAAO,KAAA;AAAA,MACL,wBAAA;AAAA,MACA,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC;AAAA,KAC1D;AACA,IAAA,MAAM,KAAA;AAAA,EACR;AACF;AAyBA,eAAsB,QAAA,GAA0B;AAC9C,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,IAAI,aAAA,GAA8B,IAAA;AAGlC,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,EAAM;AAAA,EACd,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,GAAA,GAAM,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACpE,IAAA,aAAA,GAAgB,GAAA;AAChB,IAAA,MAAA,CAAO,KAAA;AAAA,MACL,4DAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAGA,EAAA,IAAI;AAEF,IAAA,MAAM,MAAM,MAAA,EAAO;AACnB,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,MAAM,IAAI,QAAA,EAAS;AAAA,IACrB;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,GAAA,GAAM,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AAIpE,IAAA,MAAM,mBAAA,GACJ,OAAO,KAAA,KAAU,QAAA,IACjB,UAAU,IAAA,IACV,MAAA,IAAU,KAAA,IACV,KAAA,CAAM,IAAA,KAAS,cAAA;AAEjB,IAAA,IAAI,CAAC,mBAAA,EAAqB;AAExB,MAAA,IAAI,CAAC,aAAA,EAAe;AAClB,QAAA,aAAA,GAAgB,GAAA;AAAA,MAClB;AACA,MAAA,MAAA,CAAO,KAAA,CAAM,iCAAiC,GAAG,CAAA;AAAA,IACnD;AAAA,EACF,CAAA,SAAE;AAGA,IAAA,WAAA,EAAY;AACZ,IAAA,YAAA,EAAa;AACb,IAAA,eAAA,EAAgB;AAAA,EAClB;AAIA,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,MAAM,aAAA;AAAA,EACR;AACF;AAWA,SAAS,qBAAA,GAA8B;AACrC,EAAA,IAAI,OAAO,YAAY,WAAA,EAAa;AAEpC,EAAA,MAAM,OAAA,GAA4B,CAAC,SAAA,EAAW,QAAQ,CAAA;AACtD,EAAA,IAAI,YAAA,GAAe,KAAA;AAEnB,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,OAAA,CAAQ,EAAA,CAAG,QAAQ,YAAY;AAC7B,MAAA,IAAI,YAAA,EAAc;AAClB,MAAA,YAAA,GAAe,IAAA;AAEf,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,MAAA,EAAQ;AACnC,QAAA,SAAA,EAAU,CAAE,IAAA,CAAK,CAAA,mBAAA,EAAsB,MAAM,CAAA,uBAAA,CAAyB,CAAA;AAAA,MACxE;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,EAAS;AAAA,MACjB,SAAS,KAAA,EAAO;AACd,QAAA,SAAA,EAAU,CAAE,KAAA;AAAA,UACV,iCAAA;AAAA,UACA,KAAA,YAAiB,QAAQ,KAAA,GAAQ;AAAA,SACnC;AAAA,MACF,CAAA,SAAE;AACA,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AACF;AAGA,qBAAA,EAAsB;;;AChEtB,kBAAA,EAAA","file":"index.js","sourcesContent":["/**\n * Graceful shutdown with flush and cleanup\n */\n\nimport { getSdk, getLogger } from './init';\nimport { getEventQueue, resetEventQueue } from './track';\nimport { resetEvents } from './event';\nimport { resetMetrics } from './metric';\n\n/**\n * Flush all pending telemetry\n *\n * Flushes both events events and OpenTelemetry spans to their destinations.\n * Includes timeout protection to prevent hanging in serverless environments.\n *\n * Safe to call multiple times.\n *\n * @param options - Optional configuration\n * @param options.timeout - Timeout in milliseconds (default: 2000ms)\n *\n * @example Manual flush in serverless\n * ```typescript\n * import { flush } from 'autotel';\n *\n * export const handler = async (event) => {\n * // ... process event\n * await flush(); // Flush before function returns\n * return result;\n * };\n * ```\n *\n * @example With custom timeout\n * ```typescript\n * await flush({ timeout: 5000 }); // 5 second timeout\n * ```\n */\nexport async function flush(options?: { timeout?: number }): Promise<void> {\n const timeout = options?.timeout ?? 2000;\n\n const doFlush = async () => {\n // Flush events queue\n const eventsQueue = getEventQueue();\n if (eventsQueue) {\n await eventsQueue.flush();\n }\n\n // Flush OpenTelemetry spans\n // This ensures spans are exported immediately, critical for serverless\n const sdk = getSdk();\n if (sdk) {\n try {\n // Type assertion needed as getTracerProvider is not in the public NodeSDK interface\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sdkAny = sdk as any;\n if (typeof sdkAny.getTracerProvider === 'function') {\n const tracerProvider = sdkAny.getTracerProvider();\n if (\n tracerProvider &&\n typeof tracerProvider.forceFlush === 'function'\n ) {\n await tracerProvider.forceFlush();\n }\n }\n } catch {\n // Ignore errors when accessing tracer provider (may not be available in test mocks)\n }\n }\n };\n\n // Add timeout protection to prevent hanging\n let timeoutHandle: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n doFlush().finally(() => {\n // Clear timeout as soon as flush completes\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }),\n new Promise<void>((_, reject) => {\n timeoutHandle = setTimeout(\n () => reject(new Error('Flush timeout')),\n timeout,\n );\n // Use unref() to allow Node to exit if flush completes first\n // This prevents the 2s delay in serverless when flush succeeds immediately\n timeoutHandle.unref();\n }),\n ]);\n } catch (error) {\n // Clear timeout on error too\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n const logger = getLogger();\n logger.error(\n '[autotel] Flush error:',\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n}\n\n/**\n * Shutdown telemetry and cleanup resources\n *\n * - Flushes all pending data\n * - Shuts down OpenTelemetry SDK\n * - Cleans up resources\n *\n * Call this before process exit.\n *\n * Always performs cleanup even if flush fails, preventing resource leaks\n * in serverless handlers or tests.\n *\n * @example Express server\n * ```typescript\n * const server = app.listen(3000)\n *\n * process.on('SIGTERM', async () => {\n * await server.close()\n * await shutdown()\n * process.exit(0)\n * })\n * ```\n */\nexport async function shutdown(): Promise<void> {\n const logger = getLogger();\n let shutdownError: Error | null = null;\n\n // Attempt to flush, but continue with cleanup even if it fails\n try {\n await flush();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n shutdownError = err;\n logger.error(\n '[autotel] Flush failed during shutdown, continuing cleanup',\n err,\n );\n }\n\n // Always shutdown SDK and clean up resources\n try {\n // Shutdown OpenTelemetry SDK\n const sdk = getSdk();\n if (sdk) {\n await sdk.shutdown();\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n\n // Ignore ECONNREFUSED errors - this happens when no OTLP endpoint was configured\n // The SDK tries to flush exporters that don't exist, which is harmless\n const isConnectionRefused =\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n error.code === 'ECONNREFUSED';\n\n if (!isConnectionRefused) {\n // Only store/log non-connection errors\n if (!shutdownError) {\n shutdownError = err;\n }\n logger.error('[autotel] SDK shutdown failed', err);\n }\n } finally {\n // Clean up singleton Maps and queues to prevent memory leaks\n // This runs even if SDK shutdown fails\n resetEvents();\n resetMetrics();\n resetEventQueue();\n }\n\n // Rethrow first error after cleanup completes\n // This allows tests and CI to detect failures while still ensuring cleanup\n if (shutdownError) {\n throw shutdownError;\n }\n}\n\n/**\n * Register automatic shutdown hooks for common signals\n *\n * Handles:\n * - SIGTERM (Docker/K8s graceful shutdown)\n * - SIGINT (Ctrl+C)\n *\n * @internal Called automatically on module load\n */\nfunction registerShutdownHooks(): void {\n if (typeof process === 'undefined') return; // Not in Node.js\n\n const signals: NodeJS.Signals[] = ['SIGTERM', 'SIGINT'];\n let shuttingDown = false;\n\n for (const signal of signals) {\n process.on(signal, async () => {\n if (shuttingDown) return; // Prevent double shutdown\n shuttingDown = true;\n\n if (process.env.NODE_ENV !== 'test') {\n getLogger().info(`[autotel] Received ${signal}, flushing telemetry...`);\n }\n\n try {\n await shutdown();\n } catch (error) {\n getLogger().error(\n '[autotel] Error during shutdown',\n error instanceof Error ? error : undefined,\n );\n } finally {\n process.exit(0);\n }\n });\n }\n}\n\n// Auto-register shutdown hooks\nregisterShutdownHooks();\n","/**\n * autotel - Simplified OpenTelemetry instrumentation\n *\n * @example Minimal setup\n * ```typescript\n * import { init, trace, track } from 'autotel'\n *\n * init({ service: 'my-app' })\n *\n * export const createUser = trace(ctx => async (data: CreateUserData) => {\n * track('user.signup', { userId: data.id, plan: data.plan })\n * })\n * ```\n *\n * @example With events\n * ```typescript\n * import { init, trace, track } from 'autotel'\n * import { PostHogSubscriber } from 'autotel-subscribers'\n *\n * init({\n * service: 'my-app',\n * subscribers: [new PostHogSubscriber({ apiKey: '...' })]\n * })\n *\n * export const createUser = trace(ctx => async (data: CreateUserData) => {\n * track('user.signup', { userId: data.id })\n * })\n * ```\n */\n\n// Core initialization\nexport { init, type AutotelConfig } from './init';\n\n// Baggage span processor\nexport {\n BaggageSpanProcessor,\n type BaggageSpanProcessorOptions,\n} from './baggage-span-processor';\n\n// Functional API (re-export for convenience)\nexport type {\n TraceContext,\n SpanOptions,\n WithNewContextOptions,\n WithBaggageOptions,\n InstrumentOptions,\n} from './functional';\nexport {\n trace,\n instrument,\n withTracing,\n span,\n withNewContext,\n withBaggage,\n ctx,\n} from './functional';\n\n// Operation context (for advanced usage)\nexport type { OperationContext } from './operation-context';\nexport {\n getOperationContext,\n runInOperationContext,\n} from './operation-context';\n\n// Global track function\nexport { track } from './track';\n\n// Graceful shutdown\nexport { flush, shutdown } from './shutdown';\n\n// Re-export sampling strategies\nexport {\n type Sampler,\n type SamplingContext,\n AlwaysSampler,\n NeverSampler,\n RandomSampler,\n AdaptiveSampler,\n UserIdSampler,\n} from './sampling';\n\n// Events API\nexport { Event, getEvents, resetEvents, type EventsOptions } from './event';\n\n// Metrics API\nexport {\n Metric,\n getMetrics,\n resetMetrics,\n type MetricsOptions,\n} from './metric';\n\n// Meter helpers for custom metrics\nexport {\n getMeter,\n createCounter,\n createHistogram,\n createUpDownCounter,\n createObservableGauge,\n} from './metric-helpers';\n\n// Tracer helpers for custom spans\nexport {\n getTracer,\n getActiveSpan,\n getActiveContext,\n runWithSpan,\n finalizeSpan,\n createDeterministicTraceId,\n flattenMetadata,\n} from './trace-helpers';\n\n// Isolated tracer provider support (advanced - for library authors)\nexport {\n setAutotelTracerProvider,\n getAutotelTracerProvider,\n getAutotelTracer,\n} from './tracer-provider';\n\n// Semantic convention helpers\nexport {\n traceLLM,\n traceDB,\n traceHTTP,\n traceMessaging,\n type LLMConfig,\n type DBConfig,\n type HTTPConfig,\n type MessagingConfig,\n} from './semantic-helpers';\n\n// Re-export events types\nexport type {\n EventSubscriber,\n EventAttributes,\n FunnelStatus,\n OutcomeStatus,\n} from './event-subscriber';\n\n// Re-export OpenTelemetry APIs for convenience\n// (Users shouldn't need to import @opentelemetry/api directly)\n// Note: OTel's trace is exported as 'otelTrace' to avoid naming conflict with autotel's trace()\n// Plugin developers can also access it directly: import { otelTrace } from 'autotel'\nexport {\n context,\n propagation,\n SpanStatusCode,\n trace as otelTrace,\n} from '@opentelemetry/api';\n\n// Re-export common OpenTelemetry types and utilities\n// This allows plugins and apps to use OTel without needing separate @opentelemetry/api installation\nexport type { Span, SpanContext, Tracer, Context } from '@opentelemetry/api';\nexport { SpanKind } from '@opentelemetry/api';\n// Note: trace exported from functional.ts, context/propagation/SpanStatusCode already exported above\n\n// Export typed baggage helper\nexport { defineBaggageSchema } from './trace-context';\n"]}
@@ -0,0 +1,182 @@
1
+ 'use strict';
2
+
3
+ var chunkABPEQ6RK_cjs = require('./chunk-ABPEQ6RK.cjs');
4
+ var chunkGVLK7YUU_cjs = require('./chunk-GVLK7YUU.cjs');
5
+ require('./chunk-HE6T6FIX.cjs');
6
+ require('./chunk-4OAT42CA.cjs');
7
+ require('./chunk-Y4Y2S7BM.cjs');
8
+ require('./chunk-URRW6M2C.cjs');
9
+ require('./chunk-G7VZBCD6.cjs');
10
+ var sdkNode = require('@opentelemetry/sdk-node');
11
+ var autoInstrumentationsNode = require('@opentelemetry/auto-instrumentations-node');
12
+ var exporterTraceOtlpHttp = require('@opentelemetry/exporter-trace-otlp-http');
13
+ var exporterLogsOtlpHttp = require('@opentelemetry/exporter-logs-otlp-http');
14
+ var sdkLogs = require('@opentelemetry/sdk-logs');
15
+ var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
16
+ var resources = require('@opentelemetry/resources');
17
+ var incubating = require('@opentelemetry/semantic-conventions/incubating');
18
+ var exporterMetricsOtlpHttp = require('@opentelemetry/exporter-metrics-otlp-http');
19
+ var sdkMetrics = require('@opentelemetry/sdk-metrics');
20
+
21
+ function parseOtlpHeaders(headersString) {
22
+ if (!headersString) return {};
23
+ const headers = {};
24
+ const pairs = headersString.split(",");
25
+ for (const pair of pairs) {
26
+ const [key, ...valueParts] = pair.split("=");
27
+ if (key && valueParts.length > 0) {
28
+ headers[key.trim()] = valueParts.join("=").trim();
29
+ }
30
+ }
31
+ return headers;
32
+ }
33
+ function parseResourceAttributes(attributesString) {
34
+ if (!attributesString) return {};
35
+ const attributes = {};
36
+ const pairs = attributesString.split(",");
37
+ for (const pair of pairs) {
38
+ const [key, ...valueParts] = pair.split("=");
39
+ if (key && valueParts.length > 0) {
40
+ attributes[key.trim()] = valueParts.join("=").trim();
41
+ }
42
+ }
43
+ return attributes;
44
+ }
45
+ var currentSDK = null;
46
+ var shutdownHandlerRegistered = false;
47
+ async function shutdownInstrumentation(sdk) {
48
+ const sdkToShutdown = sdk || currentSDK;
49
+ if (!sdkToShutdown) {
50
+ chunkABPEQ6RK_cjs.getLogger().warn("No SDK to shutdown");
51
+ return;
52
+ }
53
+ try {
54
+ await sdkToShutdown.shutdown();
55
+ chunkABPEQ6RK_cjs.getLogger().info("OpenTelemetry terminated successfully");
56
+ if (sdkToShutdown === currentSDK) {
57
+ currentSDK = null;
58
+ }
59
+ } catch (error) {
60
+ chunkABPEQ6RK_cjs.getLogger().error(
61
+ "Error terminating OpenTelemetry",
62
+ error instanceof Error ? error : void 0
63
+ );
64
+ throw error;
65
+ }
66
+ }
67
+ async function initInstrumentation(config) {
68
+ if (currentSDK) {
69
+ chunkABPEQ6RK_cjs.getLogger().info(
70
+ "Shutting down existing OpenTelemetry SDK before reinitializing..."
71
+ );
72
+ await shutdownInstrumentation(currentSDK);
73
+ }
74
+ const otlpHeaders = parseOtlpHeaders(config.otlpHeaders);
75
+ const customResourceAttributes = parseResourceAttributes(
76
+ config.resourceAttributes
77
+ );
78
+ let resource;
79
+ const detectors = [resources.processDetector, resources.hostDetector];
80
+ try {
81
+ const awsDetectors = await import('@opentelemetry/resource-detector-aws');
82
+ detectors.push(
83
+ awsDetectors.awsEc2Detector,
84
+ awsDetectors.awsEcsDetector,
85
+ awsDetectors.awsEksDetector
86
+ );
87
+ } catch {
88
+ }
89
+ try {
90
+ const gcpDetectors = await import('@opentelemetry/resource-detector-gcp');
91
+ detectors.push(gcpDetectors.gcpDetector);
92
+ } catch {
93
+ }
94
+ try {
95
+ const containerDetectors = await import('@opentelemetry/resource-detector-container');
96
+ detectors.push(containerDetectors.containerDetector);
97
+ } catch {
98
+ }
99
+ if (config.detectResources) {
100
+ const detectedResource = await resources.detectResources({
101
+ detectors
102
+ });
103
+ resource = detectedResource.merge(
104
+ resources.resourceFromAttributes({
105
+ [incubating.ATTR_SERVICE_NAME]: config.serviceName,
106
+ [incubating.ATTR_SERVICE_VERSION]: config.serviceVersion || "1.0.0",
107
+ "deployment.environment": config.deploymentEnvironment || "development",
108
+ ...customResourceAttributes
109
+ // Merge custom resource attributes
110
+ })
111
+ );
112
+ } else {
113
+ resource = resources.resourceFromAttributes({
114
+ [incubating.ATTR_SERVICE_NAME]: config.serviceName,
115
+ [incubating.ATTR_SERVICE_VERSION]: config.serviceVersion || "1.0.0",
116
+ "deployment.environment": config.deploymentEnvironment || "development",
117
+ ...customResourceAttributes
118
+ // Merge custom resource attributes
119
+ });
120
+ }
121
+ const instrumentations = config.selectiveInstrumentation === false ? [autoInstrumentationsNode.getNodeAutoInstrumentations()] : config.instrumentations || [];
122
+ const traceExporter = new exporterTraceOtlpHttp.OTLPTraceExporter({
123
+ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/traces`,
124
+ headers: otlpHeaders
125
+ });
126
+ const spanProcessor = new chunkGVLK7YUU_cjs.TailSamplingSpanProcessor(
127
+ new sdkTraceBase.BatchSpanProcessor(traceExporter)
128
+ );
129
+ const sdk = new sdkNode.NodeSDK({
130
+ resource,
131
+ spanProcessor,
132
+ // Use our wrapped processor instead of traceExporter directly
133
+ metricReader: new sdkMetrics.PeriodicExportingMetricReader({
134
+ exporter: new exporterMetricsOtlpHttp.OTLPMetricExporter({
135
+ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/metrics`,
136
+ headers: otlpHeaders
137
+ })
138
+ }),
139
+ logRecordProcessors: [
140
+ new sdkLogs.BatchLogRecordProcessor(
141
+ new exporterLogsOtlpHttp.OTLPLogExporter({
142
+ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/logs`,
143
+ headers: otlpHeaders
144
+ })
145
+ )
146
+ ],
147
+ instrumentations
148
+ });
149
+ try {
150
+ await sdk.start();
151
+ chunkABPEQ6RK_cjs.getLogger().info("OpenTelemetry instrumentation started successfully");
152
+ } catch (error) {
153
+ chunkABPEQ6RK_cjs.getLogger().error(
154
+ "Failed to start OpenTelemetry SDK",
155
+ error instanceof Error ? error : void 0
156
+ );
157
+ throw error;
158
+ }
159
+ currentSDK = sdk;
160
+ if (!shutdownHandlerRegistered) {
161
+ shutdownHandlerRegistered = true;
162
+ const shutdownHandler = () => {
163
+ shutdownInstrumentation().then(() => {
164
+ process.exit(0);
165
+ }).catch((error) => {
166
+ chunkABPEQ6RK_cjs.getLogger().error(
167
+ "Shutdown error",
168
+ error instanceof Error ? error : void 0
169
+ );
170
+ process.exit(1);
171
+ });
172
+ };
173
+ process.on("SIGTERM", shutdownHandler);
174
+ process.on("SIGINT", shutdownHandler);
175
+ }
176
+ return sdk;
177
+ }
178
+
179
+ exports.initInstrumentation = initInstrumentation;
180
+ exports.shutdownInstrumentation = shutdownInstrumentation;
181
+ //# sourceMappingURL=instrumentation.cjs.map
182
+ //# sourceMappingURL=instrumentation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/instrumentation.ts"],"names":["getLogger","processDetector","hostDetector","detectResources","resourceFromAttributes","ATTR_SERVICE_NAME","ATTR_SERVICE_VERSION","getNodeAutoInstrumentations","OTLPTraceExporter","TailSamplingSpanProcessor","BatchSpanProcessor","NodeSDK","PeriodicExportingMetricReader","OTLPMetricExporter","BatchLogRecordProcessor","OTLPLogExporter"],"mappings":"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","file":"instrumentation.cjs","sourcesContent":["import { NodeSDK } from '@opentelemetry/sdk-node';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\nimport { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';\nimport { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { TailSamplingSpanProcessor } from './tail-sampling-processor';\nimport { getLogger } from './init';\nimport {\n resourceFromAttributes,\n detectResources,\n processDetector,\n hostDetector,\n type Resource,\n type ResourceDetector,\n} from '@opentelemetry/resources';\nimport {\n ATTR_SERVICE_NAME,\n ATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions/incubating';\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';\nimport { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';\n\n/**\n * Parse OTLP headers string into object format\n * @param headersString - Headers as \"key1=value1,key2=value2\" or \"Authorization=Basic ...\"\n * @returns Headers object for OTLP exporters\n */\nfunction parseOtlpHeaders(headersString?: string): Record<string, string> {\n if (!headersString) return {};\n\n const headers: Record<string, string> = {};\n const pairs = headersString.split(',');\n\n for (const pair of pairs) {\n const [key, ...valueParts] = pair.split('=');\n if (key && valueParts.length > 0) {\n headers[key.trim()] = valueParts.join('=').trim();\n }\n }\n\n return headers;\n}\n\n/**\n * Parse resource attributes string into object format\n * @param attributesString - Attributes as \"key1=value1,key2=value2\"\n * @returns Resource attributes object\n */\nfunction parseResourceAttributes(\n attributesString?: string,\n): Record<string, string> {\n if (!attributesString) return {};\n\n const attributes: Record<string, string> = {};\n const pairs = attributesString.split(',');\n\n for (const pair of pairs) {\n const [key, ...valueParts] = pair.split('=');\n if (key && valueParts.length > 0) {\n attributes[key.trim()] = valueParts.join('=').trim();\n }\n }\n\n return attributes;\n}\n\nexport interface InstrumentationConfig {\n serviceName: string;\n serviceVersion?: string;\n deploymentEnvironment?: string;\n otlpEndpoint?: string;\n /** OTLP headers for authentication (e.g., Grafana Cloud) */\n otlpHeaders?: string;\n /** Resource attributes as comma-separated key=value pairs */\n resourceAttributes?: string;\n /** Enable async resource detection for process/host info (default: false) */\n detectResources?: boolean;\n /**\n * Use selective instrumentation instead of full auto-instrumentation\n * **Default: true** (performance-first)\n *\n * When true, auto-instrumentation is disabled. You can manually add\n * specific instrumentations via the `instrumentations` field.\n * This reduces overhead from ~81% to near-zero based on Platformatic benchmarks.\n *\n * Set to false to enable full auto-instrumentation (not recommended for production).\n *\n * @see https://blogger.platformatic.dev/the-hidden-cost-of-context\n */\n selectiveInstrumentation?: boolean;\n\n /**\n * Custom instrumentations to use (only when selectiveInstrumentation is true)\n * @example\n * ```typescript\n * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\n *\n * initInstrumentation({\n * serviceName: 'api',\n * selectiveInstrumentation: true,\n * instrumentations: [new HttpInstrumentation()]\n * })\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n instrumentations?: any[];\n}\n\n/**\n * Initialize OpenTelemetry instrumentation with OTLP exporters\n *\n * This sets up:\n * - Traces (OTLP HTTP)\n * - Metrics (OTLP HTTP)\n * - Logs (OTLP HTTP)\n * - Auto-instrumentation for common Node.js libraries\n *\n * @example\n * // Call this at the very start of your application\n * import { initInstrumentation } from '@your-org/otel-decorators'\n *\n * initInstrumentation({\n * serviceName: 'my-service' }\n * serviceVersion: '1.0.0',\n * deploymentEnvironment: 'production',\n * otlpEndpoint: 'http://localhost:4318'\n * })\n *\n * // Or with async resource detection (top-level await required)\n * await initInstrumentation({\n * serviceName: 'my-service' }\n * detectResources: true\n * })\n */\n// Enables graceful shutdown and prevents SDK leaks on hot-reload\nlet currentSDK: NodeSDK | null = null;\nlet shutdownHandlerRegistered = false;\n\n/**\n * Shutdown the OpenTelemetry SDK gracefully\n * Call this before process exit or during hot-reloads\n */\nexport async function shutdownInstrumentation(sdk?: NodeSDK): Promise<void> {\n const sdkToShutdown = sdk || currentSDK;\n if (!sdkToShutdown) {\n getLogger().warn('No SDK to shutdown');\n return;\n }\n\n try {\n await sdkToShutdown.shutdown();\n getLogger().info('OpenTelemetry terminated successfully');\n if (sdkToShutdown === currentSDK) {\n currentSDK = null;\n }\n } catch (error) {\n getLogger().error(\n 'Error terminating OpenTelemetry',\n error instanceof Error ? error : undefined,\n );\n throw error;\n }\n}\n\nexport async function initInstrumentation(\n config: InstrumentationConfig,\n): Promise<NodeSDK> {\n // Prevents resource leaks on hot-reload or multiple init calls\n if (currentSDK) {\n getLogger().info(\n 'Shutting down existing OpenTelemetry SDK before reinitializing...',\n );\n await shutdownInstrumentation(currentSDK);\n }\n\n // Parse OTLP headers and resource attributes\n const otlpHeaders = parseOtlpHeaders(config.otlpHeaders);\n const customResourceAttributes = parseResourceAttributes(\n config.resourceAttributes,\n );\n\n let resource: Resource;\n\n // Dynamically load optional resource detectors\n const detectors: ResourceDetector[] = [processDetector, hostDetector];\n try {\n const awsDetectors = await import('@opentelemetry/resource-detector-aws');\n detectors.push(\n awsDetectors.awsEc2Detector,\n awsDetectors.awsEcsDetector,\n awsDetectors.awsEksDetector,\n );\n } catch {\n // ignore\n }\n try {\n const gcpDetectors = await import('@opentelemetry/resource-detector-gcp');\n detectors.push(gcpDetectors.gcpDetector);\n } catch {\n // ignore\n }\n try {\n const containerDetectors = await import(\n '@opentelemetry/resource-detector-container'\n );\n detectors.push(containerDetectors.containerDetector);\n } catch {\n // ignore\n }\n\n if (config.detectResources) {\n const detectedResource = await detectResources({\n detectors,\n });\n\n resource = detectedResource.merge(\n resourceFromAttributes({\n [ATTR_SERVICE_NAME]: config.serviceName,\n [ATTR_SERVICE_VERSION]: config.serviceVersion || '1.0.0',\n 'deployment.environment': config.deploymentEnvironment || 'development',\n ...customResourceAttributes, // Merge custom resource attributes\n }),\n );\n } else {\n resource = resourceFromAttributes({\n [ATTR_SERVICE_NAME]: config.serviceName,\n [ATTR_SERVICE_VERSION]: config.serviceVersion || '1.0.0',\n 'deployment.environment': config.deploymentEnvironment || 'development',\n ...customResourceAttributes, // Merge custom resource attributes\n });\n }\n\n // Default to selective (near-zero overhead) vs full auto (~81% overhead)\n const instrumentations =\n config.selectiveInstrumentation === false\n ? [getNodeAutoInstrumentations()]\n : config.instrumentations || [];\n\n const traceExporter = new OTLPTraceExporter({\n url: `${config.otlpEndpoint || 'http://localhost:4318'}/v1/traces`,\n headers: otlpHeaders,\n });\n\n // Enables tail sampling via sampling.tail.keep attribute\n const spanProcessor = new TailSamplingSpanProcessor(\n new BatchSpanProcessor(traceExporter),\n );\n\n const sdk = new NodeSDK({\n resource,\n spanProcessor, // Use our wrapped processor instead of traceExporter directly\n metricReader: new PeriodicExportingMetricReader({\n exporter: new OTLPMetricExporter({\n url: `${config.otlpEndpoint || 'http://localhost:4318'}/v1/metrics`,\n headers: otlpHeaders,\n }),\n }),\n logRecordProcessors: [\n new BatchLogRecordProcessor(\n new OTLPLogExporter({\n url: `${config.otlpEndpoint || 'http://localhost:4318'}/v1/logs`,\n headers: otlpHeaders,\n }),\n ),\n ],\n instrumentations,\n });\n\n try {\n await sdk.start();\n getLogger().info('OpenTelemetry instrumentation started successfully');\n } catch (error) {\n getLogger().error(\n 'Failed to start OpenTelemetry SDK',\n error instanceof Error ? error : undefined,\n );\n throw error;\n }\n\n // Track current SDK for shutdown handler\n currentSDK = sdk;\n\n if (!shutdownHandlerRegistered) {\n shutdownHandlerRegistered = true;\n\n const shutdownHandler = () => {\n shutdownInstrumentation()\n .then(() => {\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(0);\n })\n .catch((error) => {\n getLogger().error(\n 'Shutdown error',\n error instanceof Error ? error : undefined,\n );\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(1);\n });\n };\n\n process.on('SIGTERM', shutdownHandler);\n process.on('SIGINT', shutdownHandler);\n }\n\n return sdk;\n}\n"]}
@@ -0,0 +1,49 @@
1
+ import { NodeSDK } from '@opentelemetry/sdk-node';
2
+
3
+ interface InstrumentationConfig {
4
+ serviceName: string;
5
+ serviceVersion?: string;
6
+ deploymentEnvironment?: string;
7
+ otlpEndpoint?: string;
8
+ /** OTLP headers for authentication (e.g., Grafana Cloud) */
9
+ otlpHeaders?: string;
10
+ /** Resource attributes as comma-separated key=value pairs */
11
+ resourceAttributes?: string;
12
+ /** Enable async resource detection for process/host info (default: false) */
13
+ detectResources?: boolean;
14
+ /**
15
+ * Use selective instrumentation instead of full auto-instrumentation
16
+ * **Default: true** (performance-first)
17
+ *
18
+ * When true, auto-instrumentation is disabled. You can manually add
19
+ * specific instrumentations via the `instrumentations` field.
20
+ * This reduces overhead from ~81% to near-zero based on Platformatic benchmarks.
21
+ *
22
+ * Set to false to enable full auto-instrumentation (not recommended for production).
23
+ *
24
+ * @see https://blogger.platformatic.dev/the-hidden-cost-of-context
25
+ */
26
+ selectiveInstrumentation?: boolean;
27
+ /**
28
+ * Custom instrumentations to use (only when selectiveInstrumentation is true)
29
+ * @example
30
+ * ```typescript
31
+ * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'
32
+ *
33
+ * initInstrumentation({
34
+ * serviceName: 'api',
35
+ * selectiveInstrumentation: true,
36
+ * instrumentations: [new HttpInstrumentation()]
37
+ * })
38
+ * ```
39
+ */
40
+ instrumentations?: any[];
41
+ }
42
+ /**
43
+ * Shutdown the OpenTelemetry SDK gracefully
44
+ * Call this before process exit or during hot-reloads
45
+ */
46
+ declare function shutdownInstrumentation(sdk?: NodeSDK): Promise<void>;
47
+ declare function initInstrumentation(config: InstrumentationConfig): Promise<NodeSDK>;
48
+
49
+ export { type InstrumentationConfig, initInstrumentation, shutdownInstrumentation };
@@ -0,0 +1,49 @@
1
+ import { NodeSDK } from '@opentelemetry/sdk-node';
2
+
3
+ interface InstrumentationConfig {
4
+ serviceName: string;
5
+ serviceVersion?: string;
6
+ deploymentEnvironment?: string;
7
+ otlpEndpoint?: string;
8
+ /** OTLP headers for authentication (e.g., Grafana Cloud) */
9
+ otlpHeaders?: string;
10
+ /** Resource attributes as comma-separated key=value pairs */
11
+ resourceAttributes?: string;
12
+ /** Enable async resource detection for process/host info (default: false) */
13
+ detectResources?: boolean;
14
+ /**
15
+ * Use selective instrumentation instead of full auto-instrumentation
16
+ * **Default: true** (performance-first)
17
+ *
18
+ * When true, auto-instrumentation is disabled. You can manually add
19
+ * specific instrumentations via the `instrumentations` field.
20
+ * This reduces overhead from ~81% to near-zero based on Platformatic benchmarks.
21
+ *
22
+ * Set to false to enable full auto-instrumentation (not recommended for production).
23
+ *
24
+ * @see https://blogger.platformatic.dev/the-hidden-cost-of-context
25
+ */
26
+ selectiveInstrumentation?: boolean;
27
+ /**
28
+ * Custom instrumentations to use (only when selectiveInstrumentation is true)
29
+ * @example
30
+ * ```typescript
31
+ * import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'
32
+ *
33
+ * initInstrumentation({
34
+ * serviceName: 'api',
35
+ * selectiveInstrumentation: true,
36
+ * instrumentations: [new HttpInstrumentation()]
37
+ * })
38
+ * ```
39
+ */
40
+ instrumentations?: any[];
41
+ }
42
+ /**
43
+ * Shutdown the OpenTelemetry SDK gracefully
44
+ * Call this before process exit or during hot-reloads
45
+ */
46
+ declare function shutdownInstrumentation(sdk?: NodeSDK): Promise<void>;
47
+ declare function initInstrumentation(config: InstrumentationConfig): Promise<NodeSDK>;
48
+
49
+ export { type InstrumentationConfig, initInstrumentation, shutdownInstrumentation };
@@ -0,0 +1,179 @@
1
+ import { getLogger } from './chunk-3HENGDW2.js';
2
+ import { TailSamplingSpanProcessor } from './chunk-X4RMFFMR.js';
3
+ import './chunk-5R2M36QB.js';
4
+ import './chunk-5GWX5LFW.js';
5
+ import './chunk-KVGNW3FC.js';
6
+ import './chunk-P6JUDYNO.js';
7
+ import './chunk-Z6ZWNWWR.js';
8
+ import { NodeSDK } from '@opentelemetry/sdk-node';
9
+ import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
10
+ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
11
+ import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
12
+ import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
13
+ import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
14
+ import { processDetector, hostDetector, detectResources, resourceFromAttributes } from '@opentelemetry/resources';
15
+ import { ATTR_SERVICE_VERSION, ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions/incubating';
16
+ import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
17
+ import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
18
+
19
+ function parseOtlpHeaders(headersString) {
20
+ if (!headersString) return {};
21
+ const headers = {};
22
+ const pairs = headersString.split(",");
23
+ for (const pair of pairs) {
24
+ const [key, ...valueParts] = pair.split("=");
25
+ if (key && valueParts.length > 0) {
26
+ headers[key.trim()] = valueParts.join("=").trim();
27
+ }
28
+ }
29
+ return headers;
30
+ }
31
+ function parseResourceAttributes(attributesString) {
32
+ if (!attributesString) return {};
33
+ const attributes = {};
34
+ const pairs = attributesString.split(",");
35
+ for (const pair of pairs) {
36
+ const [key, ...valueParts] = pair.split("=");
37
+ if (key && valueParts.length > 0) {
38
+ attributes[key.trim()] = valueParts.join("=").trim();
39
+ }
40
+ }
41
+ return attributes;
42
+ }
43
+ var currentSDK = null;
44
+ var shutdownHandlerRegistered = false;
45
+ async function shutdownInstrumentation(sdk) {
46
+ const sdkToShutdown = sdk || currentSDK;
47
+ if (!sdkToShutdown) {
48
+ getLogger().warn("No SDK to shutdown");
49
+ return;
50
+ }
51
+ try {
52
+ await sdkToShutdown.shutdown();
53
+ getLogger().info("OpenTelemetry terminated successfully");
54
+ if (sdkToShutdown === currentSDK) {
55
+ currentSDK = null;
56
+ }
57
+ } catch (error) {
58
+ getLogger().error(
59
+ "Error terminating OpenTelemetry",
60
+ error instanceof Error ? error : void 0
61
+ );
62
+ throw error;
63
+ }
64
+ }
65
+ async function initInstrumentation(config) {
66
+ if (currentSDK) {
67
+ getLogger().info(
68
+ "Shutting down existing OpenTelemetry SDK before reinitializing..."
69
+ );
70
+ await shutdownInstrumentation(currentSDK);
71
+ }
72
+ const otlpHeaders = parseOtlpHeaders(config.otlpHeaders);
73
+ const customResourceAttributes = parseResourceAttributes(
74
+ config.resourceAttributes
75
+ );
76
+ let resource;
77
+ const detectors = [processDetector, hostDetector];
78
+ try {
79
+ const awsDetectors = await import('@opentelemetry/resource-detector-aws');
80
+ detectors.push(
81
+ awsDetectors.awsEc2Detector,
82
+ awsDetectors.awsEcsDetector,
83
+ awsDetectors.awsEksDetector
84
+ );
85
+ } catch {
86
+ }
87
+ try {
88
+ const gcpDetectors = await import('@opentelemetry/resource-detector-gcp');
89
+ detectors.push(gcpDetectors.gcpDetector);
90
+ } catch {
91
+ }
92
+ try {
93
+ const containerDetectors = await import('@opentelemetry/resource-detector-container');
94
+ detectors.push(containerDetectors.containerDetector);
95
+ } catch {
96
+ }
97
+ if (config.detectResources) {
98
+ const detectedResource = await detectResources({
99
+ detectors
100
+ });
101
+ resource = detectedResource.merge(
102
+ resourceFromAttributes({
103
+ [ATTR_SERVICE_NAME]: config.serviceName,
104
+ [ATTR_SERVICE_VERSION]: config.serviceVersion || "1.0.0",
105
+ "deployment.environment": config.deploymentEnvironment || "development",
106
+ ...customResourceAttributes
107
+ // Merge custom resource attributes
108
+ })
109
+ );
110
+ } else {
111
+ resource = resourceFromAttributes({
112
+ [ATTR_SERVICE_NAME]: config.serviceName,
113
+ [ATTR_SERVICE_VERSION]: config.serviceVersion || "1.0.0",
114
+ "deployment.environment": config.deploymentEnvironment || "development",
115
+ ...customResourceAttributes
116
+ // Merge custom resource attributes
117
+ });
118
+ }
119
+ const instrumentations = config.selectiveInstrumentation === false ? [getNodeAutoInstrumentations()] : config.instrumentations || [];
120
+ const traceExporter = new OTLPTraceExporter({
121
+ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/traces`,
122
+ headers: otlpHeaders
123
+ });
124
+ const spanProcessor = new TailSamplingSpanProcessor(
125
+ new BatchSpanProcessor(traceExporter)
126
+ );
127
+ const sdk = new NodeSDK({
128
+ resource,
129
+ spanProcessor,
130
+ // Use our wrapped processor instead of traceExporter directly
131
+ metricReader: new PeriodicExportingMetricReader({
132
+ exporter: new OTLPMetricExporter({
133
+ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/metrics`,
134
+ headers: otlpHeaders
135
+ })
136
+ }),
137
+ logRecordProcessors: [
138
+ new BatchLogRecordProcessor(
139
+ new OTLPLogExporter({
140
+ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/logs`,
141
+ headers: otlpHeaders
142
+ })
143
+ )
144
+ ],
145
+ instrumentations
146
+ });
147
+ try {
148
+ await sdk.start();
149
+ getLogger().info("OpenTelemetry instrumentation started successfully");
150
+ } catch (error) {
151
+ getLogger().error(
152
+ "Failed to start OpenTelemetry SDK",
153
+ error instanceof Error ? error : void 0
154
+ );
155
+ throw error;
156
+ }
157
+ currentSDK = sdk;
158
+ if (!shutdownHandlerRegistered) {
159
+ shutdownHandlerRegistered = true;
160
+ const shutdownHandler = () => {
161
+ shutdownInstrumentation().then(() => {
162
+ process.exit(0);
163
+ }).catch((error) => {
164
+ getLogger().error(
165
+ "Shutdown error",
166
+ error instanceof Error ? error : void 0
167
+ );
168
+ process.exit(1);
169
+ });
170
+ };
171
+ process.on("SIGTERM", shutdownHandler);
172
+ process.on("SIGINT", shutdownHandler);
173
+ }
174
+ return sdk;
175
+ }
176
+
177
+ export { initInstrumentation, shutdownInstrumentation };
178
+ //# sourceMappingURL=instrumentation.js.map
179
+ //# sourceMappingURL=instrumentation.js.map