autotel 4.1.0 → 4.2.1

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 (253) hide show
  1. package/dist/auto.cjs +5 -3
  2. package/dist/auto.cjs.map +1 -1
  3. package/dist/auto.js +3 -3
  4. package/dist/auto.js.map +1 -1
  5. package/dist/chunk-C_NdSu1c.cjs +34 -0
  6. package/dist/correlation-id.cjs +1 -1
  7. package/dist/correlation-id.d.cts.map +1 -1
  8. package/dist/correlation-id.d.ts.map +1 -1
  9. package/dist/correlation-id.js +1 -1
  10. package/dist/decorators.cjs +1 -1
  11. package/dist/decorators.js +1 -1
  12. package/dist/{event-ByBTV9M2.js → event-531asIM6.js} +4 -4
  13. package/dist/{event-ByBTV9M2.js.map → event-531asIM6.js.map} +1 -1
  14. package/dist/{event-BhHREDJk.cjs → event-CcZYwp50.cjs} +4 -4
  15. package/dist/{event-BhHREDJk.cjs.map → event-CcZYwp50.cjs.map} +1 -1
  16. package/dist/event.cjs +1 -1
  17. package/dist/event.js +1 -1
  18. package/dist/{functional-zpzNLhky.cjs → functional-C8B0Qa7o.cjs} +10 -7
  19. package/dist/functional-C8B0Qa7o.cjs.map +1 -0
  20. package/dist/{functional-DtI0u4vx.js → functional-r-AUIRy_.js} +9 -9
  21. package/dist/functional-r-AUIRy_.js.map +1 -0
  22. package/dist/functional.cjs +1 -1
  23. package/dist/functional.js +1 -1
  24. package/dist/http.cjs +1 -1
  25. package/dist/http.js +1 -1
  26. package/dist/index.cjs +15 -13
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts.map +1 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +14 -14
  31. package/dist/index.js.map +1 -1
  32. package/dist/{init-D-jnNMix.js → init-BS2JVkrL.js} +2 -2
  33. package/dist/{init-D-jnNMix.js.map → init-BS2JVkrL.js.map} +1 -1
  34. package/dist/{init-BX7AmFRl.cjs → init-BXiuPK6j.cjs} +3 -3
  35. package/dist/{init-BX7AmFRl.cjs.map → init-BXiuPK6j.cjs.map} +1 -1
  36. package/dist/instrumentation.cjs +2 -2
  37. package/dist/instrumentation.js +2 -2
  38. package/dist/logger.cjs +236 -8
  39. package/dist/logger.cjs.map +1 -0
  40. package/dist/messaging.cjs +1 -1
  41. package/dist/messaging.js +1 -1
  42. package/dist/{node-require-DF5QBX6z.cjs → node-require-CZ_PU448.cjs} +6 -4
  43. package/dist/node-require-CZ_PU448.cjs.map +1 -0
  44. package/dist/{node-require-Db1oDpLj.js → node-require-vROmTeJ8.js} +5 -5
  45. package/dist/node-require-vROmTeJ8.js.map +1 -0
  46. package/dist/{operation-context-C-2hmmtP.js → operation-context-CKBoA4Qy.js} +3 -3
  47. package/dist/operation-context-CKBoA4Qy.js.map +1 -0
  48. package/dist/{operation-context-n4_obUwq.cjs → operation-context-D6LDf4W_.cjs} +3 -1
  49. package/dist/operation-context-D6LDf4W_.cjs.map +1 -0
  50. package/dist/register.cjs +3 -1
  51. package/dist/register.cjs.map +1 -1
  52. package/dist/register.js +2 -2
  53. package/dist/register.js.map +1 -1
  54. package/dist/semantic-helpers.cjs +1 -1
  55. package/dist/semantic-helpers.js +1 -1
  56. package/dist/{stable-hash-Cg5cT34Q.js → stable-hash-ChFBIhNt.js} +3 -3
  57. package/dist/stable-hash-ChFBIhNt.js.map +1 -0
  58. package/dist/{stable-hash-BNTMrmdB.cjs → stable-hash-brKISGf1.cjs} +4 -2
  59. package/dist/stable-hash-brKISGf1.cjs.map +1 -0
  60. package/dist/trace-context-Cijqoi6e.d.cts.map +1 -1
  61. package/dist/trace-context-Cijqoi6e.d.ts.map +1 -1
  62. package/dist/trace-helpers.cjs +1 -1
  63. package/dist/trace-helpers.js +1 -1
  64. package/dist/{track-wc0HafS_.js → track-COUuU48p.js} +5 -5
  65. package/dist/track-COUuU48p.js.map +1 -0
  66. package/dist/{track-D59FfpL0.cjs → track-Cb3Q4QmS.cjs} +4 -2
  67. package/dist/track-Cb3Q4QmS.cjs.map +1 -0
  68. package/dist/validate.cjs +1 -1
  69. package/dist/validate.js +1 -1
  70. package/dist/webhook.cjs +1 -1
  71. package/dist/webhook.js +1 -1
  72. package/dist/workflow-distributed.cjs +1 -1
  73. package/dist/workflow-distributed.js +1 -1
  74. package/dist/workflow.cjs +3 -1
  75. package/dist/workflow.cjs.map +1 -1
  76. package/dist/workflow.d.cts.map +1 -1
  77. package/dist/workflow.d.ts.map +1 -1
  78. package/dist/workflow.js +3 -3
  79. package/dist/workflow.js.map +1 -1
  80. package/dist/yaml-config.cjs +233 -4
  81. package/dist/yaml-config.cjs.map +1 -0
  82. package/dist/yaml-config.d.cts.map +1 -1
  83. package/dist/yaml-config.d.ts.map +1 -1
  84. package/dist/yaml-config.js +8 -7
  85. package/dist/yaml-config.js.map +1 -1
  86. package/package.json +1 -2
  87. package/dist/functional-DtI0u4vx.js.map +0 -1
  88. package/dist/functional-zpzNLhky.cjs.map +0 -1
  89. package/dist/logger-thMPLpOG.cjs +0 -487
  90. package/dist/logger-thMPLpOG.cjs.map +0 -1
  91. package/dist/node-require-DF5QBX6z.cjs.map +0 -1
  92. package/dist/node-require-Db1oDpLj.js.map +0 -1
  93. package/dist/operation-context-C-2hmmtP.js.map +0 -1
  94. package/dist/operation-context-n4_obUwq.cjs.map +0 -1
  95. package/dist/stable-hash-BNTMrmdB.cjs.map +0 -1
  96. package/dist/stable-hash-Cg5cT34Q.js.map +0 -1
  97. package/dist/track-D59FfpL0.cjs.map +0 -1
  98. package/dist/track-wc0HafS_.js.map +0 -1
  99. package/dist/yaml-config-Ck2uB0Dp.cjs +0 -273
  100. package/dist/yaml-config-Ck2uB0Dp.cjs.map +0 -1
  101. package/src/attribute-redacting-processor.test.ts +0 -763
  102. package/src/attribute-redacting-processor.ts +0 -621
  103. package/src/attributes/attachers.ts +0 -161
  104. package/src/attributes/builders.ts +0 -529
  105. package/src/attributes/domains.ts +0 -42
  106. package/src/attributes/index.ts +0 -81
  107. package/src/attributes/registry.ts +0 -323
  108. package/src/attributes/types.ts +0 -211
  109. package/src/attributes/utils.ts +0 -64
  110. package/src/attributes/validators.ts +0 -266
  111. package/src/attributes.test.ts +0 -292
  112. package/src/auto.ts +0 -67
  113. package/src/autotel-logger.test.ts +0 -548
  114. package/src/autotel-logger.ts +0 -364
  115. package/src/baggage-span-processor.test.ts +0 -202
  116. package/src/baggage-span-processor.ts +0 -100
  117. package/src/business-baggage.test.ts +0 -500
  118. package/src/business-baggage.ts +0 -669
  119. package/src/circuit-breaker.test.ts +0 -341
  120. package/src/circuit-breaker.ts +0 -184
  121. package/src/config.test.ts +0 -94
  122. package/src/config.ts +0 -172
  123. package/src/correlated-events.test.ts +0 -151
  124. package/src/correlated-events.ts +0 -47
  125. package/src/correlation-id.test.ts +0 -163
  126. package/src/correlation-id.ts +0 -206
  127. package/src/db.test.ts +0 -252
  128. package/src/db.ts +0 -447
  129. package/src/decorators.test.ts +0 -153
  130. package/src/decorators.ts +0 -188
  131. package/src/define-event.test.ts +0 -41
  132. package/src/define-event.ts +0 -58
  133. package/src/devtools.ts +0 -60
  134. package/src/drain-pipeline.test.ts +0 -68
  135. package/src/drain-pipeline.ts +0 -199
  136. package/src/drain-toolkit.test.ts +0 -113
  137. package/src/drain-toolkit.ts +0 -129
  138. package/src/enricher-toolkit.test.ts +0 -67
  139. package/src/enricher-toolkit.ts +0 -79
  140. package/src/enrichers.test.ts +0 -150
  141. package/src/enrichers.ts +0 -145
  142. package/src/env-config.test.ts +0 -323
  143. package/src/env-config.ts +0 -309
  144. package/src/error-catalog.test.ts +0 -133
  145. package/src/error-catalog.ts +0 -262
  146. package/src/event-queue.test.ts +0 -864
  147. package/src/event-queue.ts +0 -699
  148. package/src/event-subscriber.ts +0 -262
  149. package/src/event-testing.ts +0 -197
  150. package/src/event.test.ts +0 -1104
  151. package/src/event.ts +0 -988
  152. package/src/events-config.ts +0 -235
  153. package/src/exporters.ts +0 -165
  154. package/src/filtering-span-processor.test.ts +0 -281
  155. package/src/filtering-span-processor.ts +0 -111
  156. package/src/flatten-attributes.test.ts +0 -76
  157. package/src/flatten-attributes.ts +0 -80
  158. package/src/functional.strict-types.typecheck.ts +0 -53
  159. package/src/functional.test.ts +0 -1464
  160. package/src/functional.ts +0 -2539
  161. package/src/functional.types.test.ts +0 -135
  162. package/src/hook.mjs +0 -15
  163. package/src/http.test.ts +0 -485
  164. package/src/http.ts +0 -424
  165. package/src/index.ts +0 -433
  166. package/src/init-auto-redactor.test.ts +0 -53
  167. package/src/init-redactor.test.ts +0 -8
  168. package/src/init.customization.test.ts +0 -665
  169. package/src/init.integrations.test.ts +0 -399
  170. package/src/init.openllmetry.test.ts +0 -194
  171. package/src/init.protocol.test.ts +0 -215
  172. package/src/init.ts +0 -2439
  173. package/src/instrumentation.test.ts +0 -108
  174. package/src/instrumentation.ts +0 -319
  175. package/src/logger.test.ts +0 -125
  176. package/src/logger.ts +0 -341
  177. package/src/messaging-adapters.test.ts +0 -595
  178. package/src/messaging-adapters.ts +0 -583
  179. package/src/messaging-testing.test.ts +0 -573
  180. package/src/messaging-testing.ts +0 -935
  181. package/src/messaging.test.ts +0 -1646
  182. package/src/messaging.ts +0 -2245
  183. package/src/metric-helpers.ts +0 -47
  184. package/src/metric-testing.ts +0 -197
  185. package/src/metric.ts +0 -446
  186. package/src/metrics.test.ts +0 -241
  187. package/src/node-require.ts +0 -123
  188. package/src/operation-context.ts +0 -93
  189. package/src/parse-error.test.ts +0 -73
  190. package/src/parse-error.ts +0 -112
  191. package/src/posthog-logs.test.ts +0 -115
  192. package/src/posthog-logs.ts +0 -77
  193. package/src/pretty-console-exporter.test.ts +0 -545
  194. package/src/pretty-console-exporter.ts +0 -413
  195. package/src/pretty-log-formatter.test.ts +0 -123
  196. package/src/pretty-log-formatter.ts +0 -210
  197. package/src/processors/canonical-log-line-processor.test.ts +0 -523
  198. package/src/processors/canonical-log-line-processor.ts +0 -396
  199. package/src/processors.ts +0 -152
  200. package/src/rate-limiter.test.ts +0 -199
  201. package/src/rate-limiter.ts +0 -98
  202. package/src/redact-values.test.ts +0 -90
  203. package/src/redact-values.ts +0 -34
  204. package/src/register.ts +0 -37
  205. package/src/request-logger.test.ts +0 -545
  206. package/src/request-logger.ts +0 -342
  207. package/src/sampling.test.ts +0 -1060
  208. package/src/sampling.ts +0 -737
  209. package/src/security-schema.test.ts +0 -45
  210. package/src/security-schema.ts +0 -107
  211. package/src/semantic-conventions.ts +0 -15
  212. package/src/semantic-helpers.test.ts +0 -226
  213. package/src/semantic-helpers.ts +0 -438
  214. package/src/shutdown.test.ts +0 -364
  215. package/src/shutdown.ts +0 -246
  216. package/src/span-name-normalizer.test.ts +0 -377
  217. package/src/span-name-normalizer.ts +0 -213
  218. package/src/stable-hash.ts +0 -27
  219. package/src/structured-error.test.ts +0 -191
  220. package/src/structured-error.ts +0 -157
  221. package/src/stub.integration.test.ts +0 -361
  222. package/src/tail-sampling-processor.test.ts +0 -230
  223. package/src/tail-sampling-processor.ts +0 -55
  224. package/src/test-span-collector.test.ts +0 -234
  225. package/src/test-span-collector.ts +0 -150
  226. package/src/testing.ts +0 -705
  227. package/src/trace-context.test.ts +0 -73
  228. package/src/trace-context.ts +0 -567
  229. package/src/trace-helpers.new.test.ts +0 -278
  230. package/src/trace-helpers.test.ts +0 -290
  231. package/src/trace-helpers.ts +0 -710
  232. package/src/trace-hybrid.test.ts +0 -42
  233. package/src/trace-hybrid.ts +0 -37
  234. package/src/tracer-provider.test.ts +0 -183
  235. package/src/tracer-provider.ts +0 -266
  236. package/src/track.test.ts +0 -154
  237. package/src/track.ts +0 -216
  238. package/src/validate.test.ts +0 -287
  239. package/src/validate.ts +0 -307
  240. package/src/validation-attributes.ts +0 -43
  241. package/src/validation.test.ts +0 -330
  242. package/src/validation.ts +0 -246
  243. package/src/variable-name-inference.test.ts +0 -178
  244. package/src/variable-name-inference.ts +0 -242
  245. package/src/webhook.test.ts +0 -649
  246. package/src/webhook.ts +0 -637
  247. package/src/workflow-distributed.test.ts +0 -786
  248. package/src/workflow-distributed.ts +0 -916
  249. package/src/workflow.async-safety.integration.test.ts +0 -345
  250. package/src/workflow.test.ts +0 -647
  251. package/src/workflow.ts +0 -810
  252. package/src/yaml-config.test.ts +0 -373
  253. package/src/yaml-config.ts +0 -351
@@ -1,42 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { trace as otelTraceApi } from '@opentelemetry/api';
3
- import { trace } from './trace-hybrid';
4
-
5
- describe('hybrid trace', () => {
6
- it('is callable like autotel trace', () => {
7
- expect(typeof trace).toBe('function');
8
-
9
- const wrapped = trace(async (x: number) => x * 2);
10
- expect(typeof wrapped).toBe('function');
11
- });
12
-
13
- it('exposes the OTel TraceAPI surface', () => {
14
- expect(typeof trace.getActiveSpan).toBe('function');
15
- expect(typeof trace.getTracer).toBe('function');
16
- expect(typeof trace.getTracerProvider).toBe('function');
17
- expect(typeof trace.setSpan).toBe('function');
18
- expect(typeof trace.getSpan).toBe('function');
19
- expect(typeof trace.setSpanContext).toBe('function');
20
- expect(typeof trace.getSpanContext).toBe('function');
21
- expect(typeof trace.deleteSpan).toBe('function');
22
- expect(typeof trace.wrapSpanContext).toBe('function');
23
- expect(typeof trace.isSpanContextValid).toBe('function');
24
- expect(typeof trace.disable).toBe('function');
25
- expect(typeof trace.setGlobalTracerProvider).toBe('function');
26
- });
27
-
28
- it('forwards getActiveSpan / getTracerProvider to the OTel singleton', () => {
29
- expect(trace.getActiveSpan()).toBe(otelTraceApi.getActiveSpan());
30
- // Same TracerProvider singleton — guarantees getTracer goes through one
31
- // place. (Tracer instances themselves may not be referentially identical
32
- // because the proxy creates a new wrapper per call.)
33
- expect(trace.getTracerProvider()).toBe(otelTraceApi.getTracerProvider());
34
- });
35
-
36
- it('preserves `this` for class methods (no unbound-this errors)', () => {
37
- // setGlobalTracerProvider/getTracerProvider rely on `this._proxyTracerProvider`.
38
- // Calling through the destructured reference must not throw.
39
- const { getTracerProvider } = trace;
40
- expect(() => getTracerProvider()).not.toThrow();
41
- });
42
- });
@@ -1,37 +0,0 @@
1
- /**
2
- * Hybrid `trace` export: callable like autotel's `trace(fn)`, AND exposes the
3
- * full `@opentelemetry/api` `TraceAPI` surface (`trace.getActiveSpan()`,
4
- * `trace.getTracer()`, …) so existing OTel code "just works" when imported
5
- * from `autotel`.
6
- *
7
- * Implementation: `Object.assign` mutates the autotel `trace` function to
8
- * attach the OTel TraceAPI methods. Because every reference to `trace` across
9
- * autotel resolves to the same function instance, this is a one-time, global
10
- * augmentation.
11
- */
12
-
13
- import { trace as otelTraceApi } from '@opentelemetry/api';
14
- import { trace as autotelTraceFn } from './functional';
15
-
16
- const otelMethods = {
17
- // Class methods on TraceAPI — bind to the singleton.
18
- setGlobalTracerProvider:
19
- otelTraceApi.setGlobalTracerProvider.bind(otelTraceApi),
20
- getTracerProvider: otelTraceApi.getTracerProvider.bind(otelTraceApi),
21
- getTracer: otelTraceApi.getTracer.bind(otelTraceApi),
22
- disable: otelTraceApi.disable.bind(otelTraceApi),
23
- // Instance fields on TraceAPI — already standalone, copy by reference.
24
- wrapSpanContext: otelTraceApi.wrapSpanContext,
25
- isSpanContextValid: otelTraceApi.isSpanContextValid,
26
- deleteSpan: otelTraceApi.deleteSpan,
27
- getSpan: otelTraceApi.getSpan,
28
- getActiveSpan: otelTraceApi.getActiveSpan,
29
- getSpanContext: otelTraceApi.getSpanContext,
30
- setSpan: otelTraceApi.setSpan,
31
- setSpanContext: otelTraceApi.setSpanContext,
32
- };
33
-
34
- export const trace: typeof autotelTraceFn & typeof otelTraceApi = Object.assign(
35
- autotelTraceFn,
36
- otelMethods,
37
- ) as typeof autotelTraceFn & typeof otelTraceApi;
@@ -1,183 +0,0 @@
1
- /**
2
- * Tests for isolated tracer provider support
3
- */
4
-
5
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
6
- import {
7
- setAutotelTracerProvider,
8
- getAutotelTracerProvider,
9
- getAutotelTracer,
10
- } from './tracer-provider';
11
- import { trace } from '@opentelemetry/api';
12
- import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
13
-
14
- describe('Isolated Tracer Provider', () => {
15
- let customProvider: NodeTracerProvider;
16
-
17
- beforeEach(() => {
18
- // Create a custom provider for testing
19
- customProvider = new NodeTracerProvider();
20
- });
21
-
22
- afterEach(() => {
23
- // Clean up: reset to null after each test
24
- setAutotelTracerProvider(null);
25
- });
26
-
27
- describe('setAutotelTracerProvider', () => {
28
- it('should set isolated provider', () => {
29
- setAutotelTracerProvider(customProvider);
30
-
31
- const provider = getAutotelTracerProvider();
32
- expect(provider).toBe(customProvider);
33
- });
34
-
35
- it('should clear isolated provider when set to null', () => {
36
- setAutotelTracerProvider(customProvider);
37
- setAutotelTracerProvider(null);
38
-
39
- const provider = getAutotelTracerProvider();
40
- // Should fall back to global provider
41
- expect(provider).toBe(trace.getTracerProvider());
42
- });
43
-
44
- it('should allow overwriting existing isolated provider', () => {
45
- const provider1 = new NodeTracerProvider();
46
- const provider2 = new NodeTracerProvider();
47
-
48
- setAutotelTracerProvider(provider1);
49
- expect(getAutotelTracerProvider()).toBe(provider1);
50
-
51
- setAutotelTracerProvider(provider2);
52
- expect(getAutotelTracerProvider()).toBe(provider2);
53
- });
54
- });
55
-
56
- describe('getAutotelTracerProvider', () => {
57
- it('should return isolated provider when set', () => {
58
- setAutotelTracerProvider(customProvider);
59
-
60
- const provider = getAutotelTracerProvider();
61
- expect(provider).toBe(customProvider);
62
- });
63
-
64
- it('should return global provider when no isolated provider is set', () => {
65
- const provider = getAutotelTracerProvider();
66
- expect(provider).toBe(trace.getTracerProvider());
67
- });
68
-
69
- it('should be idempotent', () => {
70
- setAutotelTracerProvider(customProvider);
71
-
72
- const provider1 = getAutotelTracerProvider();
73
- const provider2 = getAutotelTracerProvider();
74
-
75
- expect(provider1).toBe(provider2);
76
- });
77
- });
78
-
79
- describe('getAutotelTracer', () => {
80
- it('should return tracer from isolated provider when set', () => {
81
- setAutotelTracerProvider(customProvider);
82
-
83
- const tracer = getAutotelTracer('test-tracer');
84
-
85
- // Verify tracer is from custom provider
86
- // (We can't directly compare tracers, but we can verify it's not throwing)
87
- expect(tracer).toBeDefined();
88
- expect(typeof tracer.startSpan).toBe('function');
89
- });
90
-
91
- it('should return tracer from global provider when no isolated provider is set', () => {
92
- const tracer = getAutotelTracer('test-tracer');
93
-
94
- expect(tracer).toBeDefined();
95
- expect(typeof tracer.startSpan).toBe('function');
96
- });
97
-
98
- it('should use default tracer name when not specified', () => {
99
- setAutotelTracerProvider(customProvider);
100
-
101
- const tracer = getAutotelTracer();
102
-
103
- expect(tracer).toBeDefined();
104
- });
105
-
106
- it('should respect custom tracer name', () => {
107
- setAutotelTracerProvider(customProvider);
108
-
109
- const tracer = getAutotelTracer('custom-name', '1.0.0');
110
-
111
- expect(tracer).toBeDefined();
112
- });
113
-
114
- it('should support version parameter', () => {
115
- setAutotelTracerProvider(customProvider);
116
-
117
- const tracer = getAutotelTracer('my-service', '2.0.0');
118
-
119
- expect(tracer).toBeDefined();
120
- });
121
- });
122
-
123
- describe('Integration with Autotel config', () => {
124
- it('should allow isolated provider to work independently of init()', () => {
125
- // Don't call init(), just set isolated provider
126
- setAutotelTracerProvider(customProvider);
127
-
128
- const tracer = getAutotelTracer('standalone');
129
- expect(tracer).toBeDefined();
130
-
131
- // Should be able to create spans
132
- const span = tracer.startSpan('test-span');
133
- expect(span).toBeDefined();
134
- expect(typeof span.end).toBe('function');
135
- span.end();
136
- });
137
-
138
- it('should persist across multiple getTracer calls', () => {
139
- setAutotelTracerProvider(customProvider);
140
-
141
- const tracer1 = getAutotelTracer('service-1');
142
- const tracer2 = getAutotelTracer('service-2');
143
-
144
- // Both should come from the same provider
145
- expect(tracer1).toBeDefined();
146
- expect(tracer2).toBeDefined();
147
- });
148
- });
149
-
150
- describe('Global state isolation', () => {
151
- it('should not affect global OTel provider', () => {
152
- const globalProvider = trace.getTracerProvider();
153
-
154
- setAutotelTracerProvider(customProvider);
155
-
156
- // Global provider should remain unchanged
157
- expect(trace.getTracerProvider()).toBe(globalProvider);
158
- // But Autotel provider should be our custom one
159
- expect(getAutotelTracerProvider()).toBe(customProvider);
160
- });
161
-
162
- it('should allow both global and isolated providers to coexist', () => {
163
- const _globalProvider = trace.getTracerProvider();
164
- setAutotelTracerProvider(customProvider);
165
-
166
- const globalTracer = trace.getTracer('global-tracer');
167
- const isolatedTracer = getAutotelTracer('isolated-tracer');
168
-
169
- expect(globalTracer).toBeDefined();
170
- expect(isolatedTracer).toBeDefined();
171
-
172
- // Can create spans from both
173
- const globalSpan = globalTracer.startSpan('global-span');
174
- const isolatedSpan = isolatedTracer.startSpan('isolated-span');
175
-
176
- expect(globalSpan).toBeDefined();
177
- expect(isolatedSpan).toBeDefined();
178
-
179
- globalSpan.end();
180
- isolatedSpan.end();
181
- });
182
- });
183
- });
@@ -1,266 +0,0 @@
1
- /**
2
- * Isolated tracer provider support for Autotel
3
- *
4
- * Allows Autotel to use a separate TracerProvider instance, avoiding conflicts
5
- * with other OpenTelemetry instrumentation in the application.
6
- *
7
- * **Use Case:** Library authors who want to use Autotel without interfering
8
- * with the application's global OpenTelemetry setup.
9
- *
10
- * **Limitation:** While this isolates span processing and export, OpenTelemetry
11
- * context (trace IDs, parent spans) is still shared globally. Spans created with
12
- * the isolated provider may inherit trace context from global spans.
13
- */
14
-
15
- import { trace } from '@opentelemetry/api';
16
- import type { TracerProvider } from '@opentelemetry/api';
17
-
18
- /**
19
- * Symbol for storing isolated tracer provider in global scope
20
- * Using Symbol.for() ensures the same symbol across module boundaries
21
- */
22
- const AUTOTEL_GLOBAL_SYMBOL = Symbol.for('autotel');
23
-
24
- /**
25
- * Global state for Autotel
26
- */
27
- type AutotelGlobalState = {
28
- isolatedTracerProvider: TracerProvider | null;
29
- };
30
-
31
- /**
32
- * Create initial state
33
- */
34
- function createState(): AutotelGlobalState {
35
- return {
36
- isolatedTracerProvider: null,
37
- };
38
- }
39
-
40
- /**
41
- * Extend globalThis to include our symbol
42
- */
43
- interface GlobalThis {
44
- [AUTOTEL_GLOBAL_SYMBOL]?: AutotelGlobalState;
45
- }
46
-
47
- /**
48
- * Get the global state, creating it if it doesn't exist
49
- * Handles edge cases like missing globalThis
50
- */
51
- function getGlobalState(): AutotelGlobalState {
52
- const initialState = createState();
53
-
54
- try {
55
- const g = globalThis as typeof globalThis & GlobalThis;
56
-
57
- if (typeof g !== 'object' || g === null) {
58
- console.warn(
59
- '[autotel] globalThis is not available, using fallback state',
60
- );
61
- return initialState;
62
- }
63
-
64
- if (!g[AUTOTEL_GLOBAL_SYMBOL]) {
65
- Object.defineProperty(g, AUTOTEL_GLOBAL_SYMBOL, {
66
- value: initialState,
67
- writable: false, // Lock the slot (not the contents)
68
- configurable: false,
69
- enumerable: false,
70
- });
71
- }
72
-
73
- return g[AUTOTEL_GLOBAL_SYMBOL]!;
74
- } catch (error) {
75
- if (error instanceof Error) {
76
- console.error(
77
- `[autotel] Failed to access global state: ${error.message}`,
78
- );
79
- } else {
80
- console.error(
81
- `[autotel] Failed to access global state: ${String(error)}`,
82
- );
83
- }
84
-
85
- return initialState;
86
- }
87
- }
88
-
89
- /**
90
- * Sets an isolated TracerProvider for Autotel tracing operations.
91
- *
92
- * This allows Autotel to use its own TracerProvider instance, separate from
93
- * the global OpenTelemetry TracerProvider. This is useful for avoiding conflicts
94
- * with other OpenTelemetry instrumentation in the application.
95
- *
96
- * **Limitation: Span Context Sharing**
97
- *
98
- * While this function isolates span processing and export, it does NOT provide
99
- * complete trace isolation. OpenTelemetry context (trace IDs, parent spans) is
100
- * still shared between the global and isolated providers. This means:
101
- *
102
- * - Spans created with the isolated provider inherit trace IDs from global spans
103
- * - Spans created with the isolated provider inherit parent relationships from global spans
104
- * - This can result in spans from different providers being part of the same logical trace
105
- *
106
- * **Why this happens:**
107
- * OpenTelemetry uses a global context propagation mechanism that operates at the
108
- * JavaScript runtime level, independent of individual TracerProvider instances.
109
- * The context (containing trace ID, span ID) flows through async boundaries and
110
- * is inherited by all spans created within that context, regardless of which
111
- * TracerProvider creates them.
112
- *
113
- * **When to use this:**
114
- * - Library code that ships with embedded Autotel
115
- * - SDKs that want observability without requiring users to set up OpenTelemetry
116
- * - Applications that need separate span processing for different subsystems
117
- * - Testing scenarios where you want to isolate trace collection
118
- *
119
- * @param provider - The TracerProvider instance to use, or null to clear the isolated provider
120
- *
121
- * @example Library with embedded Autotel
122
- * ```typescript
123
- * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'
124
- * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'
125
- * import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
126
- * import { setAutolem
127
-
128
- etryTracerProvider } from 'autotel/tracer-provider'
129
- *
130
- * // Create provider with span processors in constructor
131
- * const exporter = new OTLPTraceExporter({
132
- * url: 'https://your-backend.com/v1/traces'
133
- * })
134
- *
135
- * const provider = new NodeTracerProvider()
136
- * provider.addSpanProcessor(new BatchSpanProcessor(exporter))
137
- *
138
- * // Set as Autotel's isolated provider (doesn't call provider.register())
139
- * setAutotelTracerProvider(provider)
140
- *
141
- * // Now all Autotel trace() calls use this provider
142
- * // But won't interfere with the application's global OpenTelemetry setup
143
- * ```
144
- *
145
- * @example Testing with isolated provider
146
- * ```typescript
147
- * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'
148
- * import { InMemorySpanExporter } from '@opentelemetry/sdk-trace-base'
149
- * import { setAutotelTracerProvider } from 'autotel/tracer-provider'
150
- *
151
- * // Test setup
152
- * const exporter = new InMemorySpanExporter()
153
- * const provider = new NodeTracerProvider()
154
- * provider.addSpanProcessor(new SimpleSpanProcessor(exporter))
155
- *
156
- * setAutotelTracerProvider(provider)
157
- *
158
- * // Run tests...
159
- * const spans = exporter.getFinishedSpans()
160
- *
161
- * // Cleanup
162
- * setAutotelTracerProvider(null)
163
- * ```
164
- *
165
- * @example Multiple subsystems with different exporters
166
- * ```typescript
167
- * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'
168
- * import { setAutotelTracerProvider } from 'autotel/tracer-provider'
169
- *
170
- * // Payment subsystem - send to payment team's backend
171
- * const paymentProvider = new NodeTracerProvider()
172
- * paymentProvider.addSpanProcessor(new BatchSpanProcessor(
173
- * new OTLPTraceExporter({ url: 'https://payment-team-backend.com/v1/traces' })
174
- * ))
175
- *
176
- * // In payment module initialization
177
- * setAutotelTracerProvider(paymentProvider)
178
- * ```
179
- *
180
- * @public
181
- */
182
- export function setAutotelTracerProvider(
183
- provider: TracerProvider | null,
184
- ): void {
185
- getGlobalState().isolatedTracerProvider = provider;
186
- }
187
-
188
- /**
189
- * Gets the TracerProvider for Autotel tracing operations.
190
- *
191
- * Returns the isolated TracerProvider if one has been set via setAutotelTracerProvider(),
192
- * otherwise falls back to the global OpenTelemetry TracerProvider.
193
- *
194
- * This function is used internally by Autotel's trace functions. Most users
195
- * will not need to call this directly.
196
- *
197
- * @returns The TracerProvider instance to use for Autotel tracing
198
- *
199
- * @example Getting the current provider
200
- * ```typescript
201
- * import { getAutotelTracerProvider } from 'autotel/tracer-provider'
202
- *
203
- * const provider = getAutotelTracerProvider()
204
- * const tracer = provider.getTracer('my-service', '1.0.0')
205
- * ```
206
- *
207
- * @example Checking if isolated provider is active
208
- * ```typescript
209
- * import { getAutotelTracerProvider, setAutotelTracerProvider } from 'autotel/tracer-provider'
210
- * import { trace } from '@opentelemetry/api'
211
- *
212
- * const currentProvider = getAutotelTracerProvider()
213
- * const globalProvider = trace.getTracerProvider()
214
- *
215
- * if (currentProvider === globalProvider) {
216
- * console.log('Using global provider')
217
- * } else {
218
- * console.log('Using isolated provider')
219
- * }
220
- * ```
221
- *
222
- * @public
223
- */
224
- export function getAutotelTracerProvider(): TracerProvider {
225
- const { isolatedTracerProvider } = getGlobalState();
226
-
227
- if (isolatedTracerProvider) return isolatedTracerProvider;
228
-
229
- return trace.getTracerProvider();
230
- }
231
-
232
- /**
233
- * Gets the OpenTelemetry tracer instance for Autotel.
234
- *
235
- * This function returns a tracer specifically configured for Autotel
236
- * with the correct tracer name and version. Used internally by all
237
- * Autotel tracing functions to ensure consistent trace creation.
238
- *
239
- * Uses the isolated provider if set, otherwise uses the global provider.
240
- *
241
- * @param name - Tracer name (default: 'autotel')
242
- * @param version - Optional version string
243
- * @returns The Autotel OpenTelemetry tracer instance
244
- *
245
- * @example Basic usage
246
- * ```typescript
247
- * import { getAutotelTracer } from 'autotel/tracer-provider'
248
- *
249
- * const tracer = getAutotelTracer()
250
- * const span = tracer.startSpan('my-operation')
251
- * // ... use span
252
- * span.end()
253
- * ```
254
- *
255
- * @example Custom tracer name
256
- * ```typescript
257
- * import { getAutotelTracer } from 'autotel/tracer-provider'
258
- *
259
- * const tracer = getAutotelTracer('my-library', '2.1.0')
260
- * ```
261
- *
262
- * @public
263
- */
264
- export function getAutotelTracer(name = 'autotel', version?: string) {
265
- return getAutotelTracerProvider().getTracer(name, version);
266
- }
package/src/track.test.ts DELETED
@@ -1,154 +0,0 @@
1
- /**
2
- * Tests for track() function
3
- */
4
-
5
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
6
- import { trace } from '@opentelemetry/api';
7
- import { track, getEventQueue } from './track';
8
- import { init, getLogger } from './init';
9
-
10
- type TrackedEvent = {
11
- name: string;
12
- attributes?: Record<string, unknown>;
13
- };
14
-
15
- // Mock adapter for testing
16
- class MockAdapter {
17
- public events: TrackedEvent[] = [];
18
-
19
- async trackEvent(
20
- name: string,
21
- attributes?: Record<string, unknown>,
22
- ): Promise<void> {
23
- this.events.push({ name, attributes });
24
- }
25
-
26
- async trackFunnelStep(): Promise<void> {}
27
- async trackOutcome(): Promise<void> {}
28
- async trackValue(): Promise<void> {}
29
- }
30
-
31
- describe('track() function', () => {
32
- let mockAdapter: MockAdapter;
33
- let loggerWarnSpy: ReturnType<typeof vi.spyOn> | null = null;
34
-
35
- beforeEach(() => {
36
- vi.resetModules();
37
- mockAdapter = new MockAdapter();
38
- });
39
-
40
- afterEach(() => {
41
- if (loggerWarnSpy) {
42
- loggerWarnSpy.mockRestore();
43
- }
44
- });
45
-
46
- describe('Initialization checks', () => {
47
- it('should warn in dev if track() called before init()', () => {
48
- process.env.NODE_ENV = 'development';
49
-
50
- // Spy on logger after it's initialized (it uses default silent logger initially)
51
- loggerWarnSpy = vi.spyOn(getLogger(), 'warn');
52
-
53
- track('test.event', { foo: 'bar' });
54
-
55
- expect(loggerWarnSpy).toHaveBeenCalledWith(
56
- {},
57
- expect.stringContaining('track() used before init()'),
58
- );
59
- });
60
-
61
- it('should not throw in production if track() called before init()', () => {
62
- process.env.NODE_ENV = 'production';
63
-
64
- expect(() => {
65
- track('test.event', { foo: 'bar' });
66
- }).not.toThrow();
67
- });
68
-
69
- it('should be no-op if no adapters configured', () => {
70
- init({ service: 'test-app' }); // No adapters
71
-
72
- expect(() => {
73
- track('test.event', { foo: 'bar' });
74
- }).not.toThrow();
75
-
76
- const queue = getEventQueue();
77
- expect(queue).toBeNull();
78
- });
79
- });
80
-
81
- describe('Event tracking', () => {
82
- beforeEach(() => {
83
- init({
84
- service: 'test-app',
85
- subscribers: [mockAdapter],
86
- });
87
- });
88
-
89
- it('should enqueue events', () => {
90
- track('user.signup', { userId: '123', plan: 'pro' });
91
-
92
- const queue = getEventQueue();
93
- expect(queue).not.toBeNull();
94
- expect(queue?.size()).toBeGreaterThan(0);
95
- });
96
-
97
- it('should track event name and attributes', () => {
98
- track('user.signup', { userId: '123', plan: 'pro' });
99
-
100
- // Queue batches events, so we need to flush
101
- // In real usage, this would be automatic
102
- });
103
- });
104
-
105
- describe('Trace correlation', () => {
106
- beforeEach(() => {
107
- init({
108
- service: 'test-app',
109
- subscribers: [mockAdapter],
110
- });
111
- });
112
-
113
- it('should auto-attach traceId and spanId when in active span', () => {
114
- const tracer = trace.getTracer('test');
115
-
116
- tracer.startActiveSpan('test-span', (span) => {
117
- track('user.signup', { userId: '123' });
118
-
119
- // Verify event was enqueued with trace context
120
- const queue = getEventQueue();
121
- expect(queue).not.toBeNull();
122
-
123
- span.end();
124
- });
125
- });
126
-
127
- it('should not fail if no active span', () => {
128
- expect(() => {
129
- track('user.signup', { userId: '123' });
130
- }).not.toThrow();
131
- });
132
- });
133
-
134
- describe('Type safety', () => {
135
- beforeEach(() => {
136
- init({
137
- service: 'test-app',
138
- subscribers: [mockAdapter],
139
- });
140
- });
141
-
142
- it('should accept typed events', () => {
143
- interface Events {
144
- 'user.signup': { userId: string; plan: string };
145
- }
146
-
147
- // Type-safe call (TypeScript would catch errors here)
148
- track<Events>('user.signup', { userId: '123', plan: 'pro' });
149
-
150
- const queue = getEventQueue();
151
- expect(queue!.size()).toBeGreaterThan(0);
152
- });
153
- });
154
- });