autotel-edge 3.16.13 → 3.16.15

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 (45) hide show
  1. package/dist/config-0FktBGyj.js +290 -0
  2. package/dist/config-0FktBGyj.js.map +1 -0
  3. package/dist/events.d.ts +42 -43
  4. package/dist/events.d.ts.map +1 -0
  5. package/dist/events.js +144 -137
  6. package/dist/events.js.map +1 -1
  7. package/dist/execution-logger-BWlya70r.d.ts +137 -0
  8. package/dist/execution-logger-BWlya70r.d.ts.map +1 -0
  9. package/dist/execution-logger-CoxSsBmU.js +247 -0
  10. package/dist/execution-logger-CoxSsBmU.js.map +1 -0
  11. package/dist/index.d.ts +192 -276
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +930 -1060
  14. package/dist/index.js.map +1 -1
  15. package/dist/logger.d.ts +122 -136
  16. package/dist/logger.d.ts.map +1 -0
  17. package/dist/logger.js +783 -774
  18. package/dist/logger.js.map +1 -1
  19. package/dist/parse-error.d.ts +12 -10
  20. package/dist/parse-error.d.ts.map +1 -0
  21. package/dist/parse-error.js +55 -2
  22. package/dist/parse-error.js.map +1 -1
  23. package/dist/sampling.d.ts +51 -76
  24. package/dist/sampling.d.ts.map +1 -0
  25. package/dist/sampling.js +155 -90
  26. package/dist/sampling.js.map +1 -1
  27. package/dist/testing.d.ts +1 -2
  28. package/dist/testing.js +1 -3
  29. package/dist/types-HCbsjZzp.d.ts +214 -0
  30. package/dist/types-HCbsjZzp.d.ts.map +1 -0
  31. package/package.json +6 -6
  32. package/src/core/buffer.ts +4 -3
  33. package/src/core/provider.context.test.ts +55 -0
  34. package/src/core/provider.ts +18 -1
  35. package/binding.gyp +0 -9
  36. package/dist/chunk-AL7ZD64M.js +0 -291
  37. package/dist/chunk-AL7ZD64M.js.map +0 -1
  38. package/dist/chunk-INQQQVXN.js +0 -310
  39. package/dist/chunk-INQQQVXN.js.map +0 -1
  40. package/dist/chunk-M7Z4P5MC.js +0 -64
  41. package/dist/chunk-M7Z4P5MC.js.map +0 -1
  42. package/dist/execution-logger-77TRRoWn.d.ts +0 -84
  43. package/dist/testing.js.map +0 -1
  44. package/dist/types-uulICZo7.d.ts +0 -216
  45. package/index.js +0 -1
package/dist/sampling.js CHANGED
@@ -1,108 +1,173 @@
1
- // src/sampling/index.ts
1
+ //#region src/sampling/index.ts
2
+ /**
3
+ * Create an adaptive tail sampler
4
+ *
5
+ * This sampler ensures you never miss critical issues while keeping costs down:
6
+ * - Always traces errors (status code = ERROR)
7
+ * - Always traces slow requests (duration >= slowThresholdMs)
8
+ * - Uses baseline sample rate for successful fast requests
9
+ *
10
+ * **Recommended for production use.**
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const tailSampler = createAdaptiveTailSampler({
15
+ * baselineSampleRate: 0.1, // 10% of normal requests
16
+ * slowThresholdMs: 1000, // Requests > 1s are "slow"
17
+ * alwaysSampleErrors: true, // Always trace errors
18
+ * alwaysSampleSlow: true // Always trace slow requests
19
+ * })
20
+ * ```
21
+ */
2
22
  function createAdaptiveTailSampler(options = {}) {
3
- const baselineSampleRate = options.baselineSampleRate ?? 0.1;
4
- const slowThresholdMs = options.slowThresholdMs ?? 1e3;
5
- const alwaysSampleErrors = options.alwaysSampleErrors ?? true;
6
- const alwaysSampleSlow = options.alwaysSampleSlow ?? true;
7
- if (baselineSampleRate < 0 || baselineSampleRate > 1) {
8
- throw new Error("Baseline sample rate must be between 0 and 1");
9
- }
10
- const baselineDecisions = /* @__PURE__ */ new Map();
11
- return (traceInfo) => {
12
- const { traceId, localRootSpan } = traceInfo;
13
- if (!baselineDecisions.has(traceId)) {
14
- baselineDecisions.set(traceId, Math.random() < baselineSampleRate);
15
- }
16
- const baselineDecision = baselineDecisions.get(traceId);
17
- if (alwaysSampleErrors && localRootSpan.status.code === 2) {
18
- return true;
19
- }
20
- if (alwaysSampleSlow) {
21
- const duration = getDurationMs(localRootSpan);
22
- if (duration >= slowThresholdMs) {
23
- return true;
24
- }
25
- }
26
- return baselineDecision;
27
- };
23
+ const baselineSampleRate = options.baselineSampleRate ?? .1;
24
+ const slowThresholdMs = options.slowThresholdMs ?? 1e3;
25
+ const alwaysSampleErrors = options.alwaysSampleErrors ?? true;
26
+ const alwaysSampleSlow = options.alwaysSampleSlow ?? true;
27
+ if (baselineSampleRate < 0 || baselineSampleRate > 1) throw new Error("Baseline sample rate must be between 0 and 1");
28
+ const baselineDecisions = /* @__PURE__ */ new Map();
29
+ return (traceInfo) => {
30
+ const { traceId, localRootSpan } = traceInfo;
31
+ if (!baselineDecisions.has(traceId)) baselineDecisions.set(traceId, Math.random() < baselineSampleRate);
32
+ const baselineDecision = baselineDecisions.get(traceId);
33
+ if (alwaysSampleErrors && localRootSpan.status.code === 2) return true;
34
+ if (alwaysSampleSlow) {
35
+ if (getDurationMs(localRootSpan) >= slowThresholdMs) return true;
36
+ }
37
+ return baselineDecision;
38
+ };
28
39
  }
40
+ /**
41
+ * Create a simple random tail sampler
42
+ *
43
+ * Samples a fixed percentage of all traces regardless of outcome.
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const tailSampler = createRandomTailSampler(0.1) // 10% of all requests
48
+ * ```
49
+ */
29
50
  function createRandomTailSampler(sampleRate) {
30
- if (sampleRate < 0 || sampleRate > 1) {
31
- throw new Error("Sample rate must be between 0 and 1");
32
- }
33
- const decisions = /* @__PURE__ */ new Map();
34
- return (traceInfo) => {
35
- const { traceId } = traceInfo;
36
- if (!decisions.has(traceId)) {
37
- decisions.set(traceId, Math.random() < sampleRate);
38
- }
39
- return decisions.get(traceId);
40
- };
51
+ if (sampleRate < 0 || sampleRate > 1) throw new Error("Sample rate must be between 0 and 1");
52
+ const decisions = /* @__PURE__ */ new Map();
53
+ return (traceInfo) => {
54
+ const { traceId } = traceInfo;
55
+ if (!decisions.has(traceId)) decisions.set(traceId, Math.random() < sampleRate);
56
+ return decisions.get(traceId);
57
+ };
41
58
  }
59
+ /**
60
+ * Create a tail sampler that keeps all errors
61
+ *
62
+ * Useful for debugging - captures all failures while dropping successful requests.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const tailSampler = createErrorOnlyTailSampler()
67
+ * ```
68
+ */
42
69
  function createErrorOnlyTailSampler() {
43
- return (traceInfo) => {
44
- return traceInfo.localRootSpan.status.code === 2;
45
- };
70
+ return (traceInfo) => {
71
+ return traceInfo.localRootSpan.status.code === 2;
72
+ };
46
73
  }
74
+ /**
75
+ * Create a tail sampler that keeps slow requests
76
+ *
77
+ * Useful for performance debugging - captures slow requests while dropping fast ones.
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const tailSampler = createSlowOnlyTailSampler(1000) // Keep requests > 1s
82
+ * ```
83
+ */
47
84
  function createSlowOnlyTailSampler(thresholdMs) {
48
- return (traceInfo) => {
49
- const duration = getDurationMs(traceInfo.localRootSpan);
50
- return duration >= thresholdMs;
51
- };
85
+ return (traceInfo) => {
86
+ return getDurationMs(traceInfo.localRootSpan) >= thresholdMs;
87
+ };
52
88
  }
89
+ /**
90
+ * Combine multiple tail samplers with OR logic
91
+ *
92
+ * Keeps a trace if ANY sampler returns true.
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * const tailSampler = combineTailSamplers(
97
+ * createErrorOnlyTailSampler(),
98
+ * createSlowOnlyTailSampler(1000),
99
+ * createRandomTailSampler(0.01) // 1% baseline
100
+ * )
101
+ * ```
102
+ */
53
103
  function combineTailSamplers(...samplers) {
54
- if (samplers.length === 0) {
55
- throw new Error("combineTailSamplers requires at least one sampler");
56
- }
57
- return (traceInfo) => {
58
- return samplers.some((sampler) => sampler(traceInfo));
59
- };
104
+ if (samplers.length === 0) throw new Error("combineTailSamplers requires at least one sampler");
105
+ return (traceInfo) => {
106
+ return samplers.some((sampler) => sampler(traceInfo));
107
+ };
60
108
  }
109
+ /**
110
+ * Create a tail sampler based on custom predicate
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * // Keep traces with specific attributes
115
+ * const tailSampler = createCustomTailSampler((trace) => {
116
+ * const attrs = trace.localRootSpan.attributes
117
+ * return attrs['user.id'] === 'vip_123'
118
+ * })
119
+ * ```
120
+ */
61
121
  function createCustomTailSampler(predicate) {
62
- return predicate;
122
+ return predicate;
63
123
  }
124
+ /**
125
+ * Helper: Get span duration in milliseconds
126
+ */
64
127
  function getDurationMs(span) {
65
- const start = span.startTime[0] * 1e3 + span.startTime[1] / 1e6;
66
- const end = span.endTime[0] * 1e3 + span.endTime[1] / 1e6;
67
- return end - start;
128
+ const start = span.startTime[0] * 1e3 + span.startTime[1] / 1e6;
129
+ return span.endTime[0] * 1e3 + span.endTime[1] / 1e6 - start;
68
130
  }
69
- var SamplingPresets = {
70
- /**
71
- * Production: 10% baseline, all errors, all slow (>1s)
72
- * Recommended for most production workloads
73
- */
74
- production: () => createAdaptiveTailSampler({
75
- baselineSampleRate: 0.1,
76
- slowThresholdMs: 1e3
77
- }),
78
- /**
79
- * High-traffic: 1% baseline, all errors, all slow (>2s)
80
- * For high-volume services where cost is a concern
81
- */
82
- highTraffic: () => createAdaptiveTailSampler({
83
- baselineSampleRate: 0.01,
84
- slowThresholdMs: 2e3
85
- }),
86
- /**
87
- * Debugging: All errors, all slow (>500ms), 50% baseline
88
- * For active debugging sessions
89
- */
90
- debugging: () => createAdaptiveTailSampler({
91
- baselineSampleRate: 0.5,
92
- slowThresholdMs: 500
93
- }),
94
- /**
95
- * Development: 100% sampling
96
- * For local development and testing
97
- */
98
- development: () => () => true,
99
- /**
100
- * Errors only: Capture all failures, drop all successes
101
- * For error-focused monitoring
102
- */
103
- errorsOnly: () => createErrorOnlyTailSampler()
131
+ /**
132
+ * Common presets for quick setup
133
+ */
134
+ const SamplingPresets = {
135
+ /**
136
+ * Production: 10% baseline, all errors, all slow (>1s)
137
+ * Recommended for most production workloads
138
+ */
139
+ production: () => createAdaptiveTailSampler({
140
+ baselineSampleRate: .1,
141
+ slowThresholdMs: 1e3
142
+ }),
143
+ /**
144
+ * High-traffic: 1% baseline, all errors, all slow (>2s)
145
+ * For high-volume services where cost is a concern
146
+ */
147
+ highTraffic: () => createAdaptiveTailSampler({
148
+ baselineSampleRate: .01,
149
+ slowThresholdMs: 2e3
150
+ }),
151
+ /**
152
+ * Debugging: All errors, all slow (>500ms), 50% baseline
153
+ * For active debugging sessions
154
+ */
155
+ debugging: () => createAdaptiveTailSampler({
156
+ baselineSampleRate: .5,
157
+ slowThresholdMs: 500
158
+ }),
159
+ /**
160
+ * Development: 100% sampling
161
+ * For local development and testing
162
+ */
163
+ development: () => () => true,
164
+ /**
165
+ * Errors only: Capture all failures, drop all successes
166
+ * For error-focused monitoring
167
+ */
168
+ errorsOnly: () => createErrorOnlyTailSampler()
104
169
  };
105
170
 
171
+ //#endregion
106
172
  export { SamplingPresets, combineTailSamplers, createAdaptiveTailSampler, createCustomTailSampler, createErrorOnlyTailSampler, createRandomTailSampler, createSlowOnlyTailSampler };
107
- //# sourceMappingURL=sampling.js.map
108
173
  //# sourceMappingURL=sampling.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sampling/index.ts"],"names":[],"mappings":"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","file":"sampling.js","sourcesContent":["/**\n * Sampling strategies for autotel-edge\n *\n * Provides intelligent sampling to reduce telemetry costs while capturing critical data.\n *\n * Key strategies:\n * - Always trace errors and slow requests (critical for debugging)\n * - Adaptive sampling based on load\n * - Baseline random sampling for normal traffic\n *\n * @example\n * ```typescript\n * import { createAdaptiveTailSampler } from 'autotel-edge/sampling'\n *\n * export default instrument(handler, {\n * sampling: {\n * tailSampler: createAdaptiveTailSampler({\n * baselineSampleRate: 0.1, // 10% of normal requests\n * slowThresholdMs: 1000, // Requests > 1s are \"slow\"\n * })\n * }\n * })\n * ```\n */\n\nimport type { TailSampleFn, LocalTrace } from '../types';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-base';\n\nexport interface AdaptiveSamplerOptions {\n /**\n * Baseline sample rate for normal (successful, fast) requests\n * @default 0.1 (10%)\n */\n baselineSampleRate?: number;\n\n /**\n * Threshold in milliseconds for \"slow\" requests\n * Requests taking longer than this will always be trace\n * @default 1000ms\n */\n slowThresholdMs?: number;\n\n /**\n * Always trace error spans\n * @default true\n */\n alwaysSampleErrors?: boolean;\n\n /**\n * Always trace slow spans\n * @default true\n */\n alwaysSampleSlow?: boolean;\n}\n\n/**\n * Create an adaptive tail sampler\n *\n * This sampler ensures you never miss critical issues while keeping costs down:\n * - Always traces errors (status code = ERROR)\n * - Always traces slow requests (duration >= slowThresholdMs)\n * - Uses baseline sample rate for successful fast requests\n *\n * **Recommended for production use.**\n *\n * @example\n * ```typescript\n * const tailSampler = createAdaptiveTailSampler({\n * baselineSampleRate: 0.1, // 10% of normal requests\n * slowThresholdMs: 1000, // Requests > 1s are \"slow\"\n * alwaysSampleErrors: true, // Always trace errors\n * alwaysSampleSlow: true // Always trace slow requests\n * })\n * ```\n */\nexport function createAdaptiveTailSampler(\n options: AdaptiveSamplerOptions = {},\n): TailSampleFn {\n const baselineSampleRate = options.baselineSampleRate ?? 0.1;\n const slowThresholdMs = options.slowThresholdMs ?? 1000;\n const alwaysSampleErrors = options.alwaysSampleErrors ?? true;\n const alwaysSampleSlow = options.alwaysSampleSlow ?? true;\n\n if (baselineSampleRate < 0 || baselineSampleRate > 1) {\n throw new Error('Baseline sample rate must be between 0 and 1');\n }\n\n // Store baseline decisions using trace ID\n const baselineDecisions = new Map<string, boolean>();\n\n return (traceInfo: LocalTrace): boolean => {\n const { traceId, localRootSpan } = traceInfo;\n\n // Get or create baseline decision for this trace\n if (!baselineDecisions.has(traceId)) {\n baselineDecisions.set(traceId, Math.random() < baselineSampleRate);\n }\n const baselineDecision = baselineDecisions.get(traceId)!;\n\n // Always keep errors (SpanStatusCode.ERROR = 2)\n if (alwaysSampleErrors && localRootSpan.status.code === 2) {\n return true;\n }\n\n // Always keep slow requests\n if (alwaysSampleSlow) {\n const duration = getDurationMs(localRootSpan);\n if (duration >= slowThresholdMs) {\n return true;\n }\n }\n\n // Otherwise, use baseline decision\n return baselineDecision;\n };\n}\n\n/**\n * Create a simple random tail sampler\n *\n * Samples a fixed percentage of all traces regardless of outcome.\n *\n * @example\n * ```typescript\n * const tailSampler = createRandomTailSampler(0.1) // 10% of all requests\n * ```\n */\nexport function createRandomTailSampler(sampleRate: number): TailSampleFn {\n if (sampleRate < 0 || sampleRate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n\n const decisions = new Map<string, boolean>();\n\n return (traceInfo: LocalTrace): boolean => {\n const { traceId } = traceInfo;\n\n if (!decisions.has(traceId)) {\n decisions.set(traceId, Math.random() < sampleRate);\n }\n\n return decisions.get(traceId)!;\n };\n}\n\n/**\n * Create a tail sampler that keeps all errors\n *\n * Useful for debugging - captures all failures while dropping successful requests.\n *\n * @example\n * ```typescript\n * const tailSampler = createErrorOnlyTailSampler()\n * ```\n */\nexport function createErrorOnlyTailSampler(): TailSampleFn {\n return (traceInfo: LocalTrace): boolean => {\n // SpanStatusCode.ERROR = 2\n return traceInfo.localRootSpan.status.code === 2;\n };\n}\n\n/**\n * Create a tail sampler that keeps slow requests\n *\n * Useful for performance debugging - captures slow requests while dropping fast ones.\n *\n * @example\n * ```typescript\n * const tailSampler = createSlowOnlyTailSampler(1000) // Keep requests > 1s\n * ```\n */\nexport function createSlowOnlyTailSampler(thresholdMs: number): TailSampleFn {\n return (traceInfo: LocalTrace): boolean => {\n const duration = getDurationMs(traceInfo.localRootSpan);\n return duration >= thresholdMs;\n };\n}\n\n/**\n * Combine multiple tail samplers with OR logic\n *\n * Keeps a trace if ANY sampler returns true.\n *\n * @example\n * ```typescript\n * const tailSampler = combineTailSamplers(\n * createErrorOnlyTailSampler(),\n * createSlowOnlyTailSampler(1000),\n * createRandomTailSampler(0.01) // 1% baseline\n * )\n * ```\n */\nexport function combineTailSamplers(...samplers: TailSampleFn[]): TailSampleFn {\n if (samplers.length === 0) {\n throw new Error('combineTailSamplers requires at least one sampler');\n }\n\n return (traceInfo: LocalTrace): boolean => {\n return samplers.some((sampler) => sampler(traceInfo));\n };\n}\n\n/**\n * Create a tail sampler based on custom predicate\n *\n * @example\n * ```typescript\n * // Keep traces with specific attributes\n * const tailSampler = createCustomTailSampler((trace) => {\n * const attrs = trace.localRootSpan.attributes\n * return attrs['user.id'] === 'vip_123'\n * })\n * ```\n */\nexport function createCustomTailSampler(\n predicate: (traceInfo: LocalTrace) => boolean,\n): TailSampleFn {\n return predicate;\n}\n\n/**\n * Helper: Get span duration in milliseconds\n */\nfunction getDurationMs(span: ReadableSpan): number {\n const start = span.startTime[0] * 1000 + span.startTime[1] / 1_000_000;\n const end = span.endTime[0] * 1000 + span.endTime[1] / 1_000_000;\n return end - start;\n}\n\n/**\n * Common presets for quick setup\n */\nexport const SamplingPresets = {\n /**\n * Production: 10% baseline, all errors, all slow (>1s)\n * Recommended for most production workloads\n */\n production: (): TailSampleFn =>\n createAdaptiveTailSampler({\n baselineSampleRate: 0.1,\n slowThresholdMs: 1000,\n }),\n\n /**\n * High-traffic: 1% baseline, all errors, all slow (>2s)\n * For high-volume services where cost is a concern\n */\n highTraffic: (): TailSampleFn =>\n createAdaptiveTailSampler({\n baselineSampleRate: 0.01,\n slowThresholdMs: 2000,\n }),\n\n /**\n * Debugging: All errors, all slow (>500ms), 50% baseline\n * For active debugging sessions\n */\n debugging: (): TailSampleFn =>\n createAdaptiveTailSampler({\n baselineSampleRate: 0.5,\n slowThresholdMs: 500,\n }),\n\n /**\n * Development: 100% sampling\n * For local development and testing\n */\n development: (): TailSampleFn => () => true,\n\n /**\n * Errors only: Capture all failures, drop all successes\n * For error-focused monitoring\n */\n errorsOnly: (): TailSampleFn => createErrorOnlyTailSampler(),\n};\n"]}
1
+ {"version":3,"file":"sampling.js","names":[],"sources":["../src/sampling/index.ts"],"sourcesContent":["/**\n * Sampling strategies for autotel-edge\n *\n * Provides intelligent sampling to reduce telemetry costs while capturing critical data.\n *\n * Key strategies:\n * - Always trace errors and slow requests (critical for debugging)\n * - Adaptive sampling based on load\n * - Baseline random sampling for normal traffic\n *\n * @example\n * ```typescript\n * import { createAdaptiveTailSampler } from 'autotel-edge/sampling'\n *\n * export default instrument(handler, {\n * sampling: {\n * tailSampler: createAdaptiveTailSampler({\n * baselineSampleRate: 0.1, // 10% of normal requests\n * slowThresholdMs: 1000, // Requests > 1s are \"slow\"\n * })\n * }\n * })\n * ```\n */\n\nimport type { TailSampleFn, LocalTrace } from '../types';\nimport type { ReadableSpan } from '@opentelemetry/sdk-trace-base';\n\nexport interface AdaptiveSamplerOptions {\n /**\n * Baseline sample rate for normal (successful, fast) requests\n * @default 0.1 (10%)\n */\n baselineSampleRate?: number;\n\n /**\n * Threshold in milliseconds for \"slow\" requests\n * Requests taking longer than this will always be trace\n * @default 1000ms\n */\n slowThresholdMs?: number;\n\n /**\n * Always trace error spans\n * @default true\n */\n alwaysSampleErrors?: boolean;\n\n /**\n * Always trace slow spans\n * @default true\n */\n alwaysSampleSlow?: boolean;\n}\n\n/**\n * Create an adaptive tail sampler\n *\n * This sampler ensures you never miss critical issues while keeping costs down:\n * - Always traces errors (status code = ERROR)\n * - Always traces slow requests (duration >= slowThresholdMs)\n * - Uses baseline sample rate for successful fast requests\n *\n * **Recommended for production use.**\n *\n * @example\n * ```typescript\n * const tailSampler = createAdaptiveTailSampler({\n * baselineSampleRate: 0.1, // 10% of normal requests\n * slowThresholdMs: 1000, // Requests > 1s are \"slow\"\n * alwaysSampleErrors: true, // Always trace errors\n * alwaysSampleSlow: true // Always trace slow requests\n * })\n * ```\n */\nexport function createAdaptiveTailSampler(\n options: AdaptiveSamplerOptions = {},\n): TailSampleFn {\n const baselineSampleRate = options.baselineSampleRate ?? 0.1;\n const slowThresholdMs = options.slowThresholdMs ?? 1000;\n const alwaysSampleErrors = options.alwaysSampleErrors ?? true;\n const alwaysSampleSlow = options.alwaysSampleSlow ?? true;\n\n if (baselineSampleRate < 0 || baselineSampleRate > 1) {\n throw new Error('Baseline sample rate must be between 0 and 1');\n }\n\n // Store baseline decisions using trace ID\n const baselineDecisions = new Map<string, boolean>();\n\n return (traceInfo: LocalTrace): boolean => {\n const { traceId, localRootSpan } = traceInfo;\n\n // Get or create baseline decision for this trace\n if (!baselineDecisions.has(traceId)) {\n baselineDecisions.set(traceId, Math.random() < baselineSampleRate);\n }\n const baselineDecision = baselineDecisions.get(traceId)!;\n\n // Always keep errors (SpanStatusCode.ERROR = 2)\n if (alwaysSampleErrors && localRootSpan.status.code === 2) {\n return true;\n }\n\n // Always keep slow requests\n if (alwaysSampleSlow) {\n const duration = getDurationMs(localRootSpan);\n if (duration >= slowThresholdMs) {\n return true;\n }\n }\n\n // Otherwise, use baseline decision\n return baselineDecision;\n };\n}\n\n/**\n * Create a simple random tail sampler\n *\n * Samples a fixed percentage of all traces regardless of outcome.\n *\n * @example\n * ```typescript\n * const tailSampler = createRandomTailSampler(0.1) // 10% of all requests\n * ```\n */\nexport function createRandomTailSampler(sampleRate: number): TailSampleFn {\n if (sampleRate < 0 || sampleRate > 1) {\n throw new Error('Sample rate must be between 0 and 1');\n }\n\n const decisions = new Map<string, boolean>();\n\n return (traceInfo: LocalTrace): boolean => {\n const { traceId } = traceInfo;\n\n if (!decisions.has(traceId)) {\n decisions.set(traceId, Math.random() < sampleRate);\n }\n\n return decisions.get(traceId)!;\n };\n}\n\n/**\n * Create a tail sampler that keeps all errors\n *\n * Useful for debugging - captures all failures while dropping successful requests.\n *\n * @example\n * ```typescript\n * const tailSampler = createErrorOnlyTailSampler()\n * ```\n */\nexport function createErrorOnlyTailSampler(): TailSampleFn {\n return (traceInfo: LocalTrace): boolean => {\n // SpanStatusCode.ERROR = 2\n return traceInfo.localRootSpan.status.code === 2;\n };\n}\n\n/**\n * Create a tail sampler that keeps slow requests\n *\n * Useful for performance debugging - captures slow requests while dropping fast ones.\n *\n * @example\n * ```typescript\n * const tailSampler = createSlowOnlyTailSampler(1000) // Keep requests > 1s\n * ```\n */\nexport function createSlowOnlyTailSampler(thresholdMs: number): TailSampleFn {\n return (traceInfo: LocalTrace): boolean => {\n const duration = getDurationMs(traceInfo.localRootSpan);\n return duration >= thresholdMs;\n };\n}\n\n/**\n * Combine multiple tail samplers with OR logic\n *\n * Keeps a trace if ANY sampler returns true.\n *\n * @example\n * ```typescript\n * const tailSampler = combineTailSamplers(\n * createErrorOnlyTailSampler(),\n * createSlowOnlyTailSampler(1000),\n * createRandomTailSampler(0.01) // 1% baseline\n * )\n * ```\n */\nexport function combineTailSamplers(...samplers: TailSampleFn[]): TailSampleFn {\n if (samplers.length === 0) {\n throw new Error('combineTailSamplers requires at least one sampler');\n }\n\n return (traceInfo: LocalTrace): boolean => {\n return samplers.some((sampler) => sampler(traceInfo));\n };\n}\n\n/**\n * Create a tail sampler based on custom predicate\n *\n * @example\n * ```typescript\n * // Keep traces with specific attributes\n * const tailSampler = createCustomTailSampler((trace) => {\n * const attrs = trace.localRootSpan.attributes\n * return attrs['user.id'] === 'vip_123'\n * })\n * ```\n */\nexport function createCustomTailSampler(\n predicate: (traceInfo: LocalTrace) => boolean,\n): TailSampleFn {\n return predicate;\n}\n\n/**\n * Helper: Get span duration in milliseconds\n */\nfunction getDurationMs(span: ReadableSpan): number {\n const start = span.startTime[0] * 1000 + span.startTime[1] / 1_000_000;\n const end = span.endTime[0] * 1000 + span.endTime[1] / 1_000_000;\n return end - start;\n}\n\n/**\n * Common presets for quick setup\n */\nexport const SamplingPresets = {\n /**\n * Production: 10% baseline, all errors, all slow (>1s)\n * Recommended for most production workloads\n */\n production: (): TailSampleFn =>\n createAdaptiveTailSampler({\n baselineSampleRate: 0.1,\n slowThresholdMs: 1000,\n }),\n\n /**\n * High-traffic: 1% baseline, all errors, all slow (>2s)\n * For high-volume services where cost is a concern\n */\n highTraffic: (): TailSampleFn =>\n createAdaptiveTailSampler({\n baselineSampleRate: 0.01,\n slowThresholdMs: 2000,\n }),\n\n /**\n * Debugging: All errors, all slow (>500ms), 50% baseline\n * For active debugging sessions\n */\n debugging: (): TailSampleFn =>\n createAdaptiveTailSampler({\n baselineSampleRate: 0.5,\n slowThresholdMs: 500,\n }),\n\n /**\n * Development: 100% sampling\n * For local development and testing\n */\n development: (): TailSampleFn => () => true,\n\n /**\n * Errors only: Capture all failures, drop all successes\n * For error-focused monitoring\n */\n errorsOnly: (): TailSampleFn => createErrorOnlyTailSampler(),\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2EA,SAAgB,0BACd,UAAkC,CAAC,GACrB;CACd,MAAM,qBAAqB,QAAQ,sBAAsB;CACzD,MAAM,kBAAkB,QAAQ,mBAAmB;CACnD,MAAM,qBAAqB,QAAQ,sBAAsB;CACzD,MAAM,mBAAmB,QAAQ,oBAAoB;CAErD,IAAI,qBAAqB,KAAK,qBAAqB,GACjD,MAAM,IAAI,MAAM,8CAA8C;CAIhE,MAAM,oCAAoB,IAAI,IAAqB;CAEnD,QAAQ,cAAmC;EACzC,MAAM,EAAE,SAAS,kBAAkB;EAGnC,IAAI,CAAC,kBAAkB,IAAI,OAAO,GAChC,kBAAkB,IAAI,SAAS,KAAK,OAAO,IAAI,kBAAkB;EAEnE,MAAM,mBAAmB,kBAAkB,IAAI,OAAO;EAGtD,IAAI,sBAAsB,cAAc,OAAO,SAAS,GACtD,OAAO;EAIT,IAAI,kBAEF;OADiB,cAAc,aACpB,KAAK,iBACd,OAAO;EACT;EAIF,OAAO;CACT;AACF;;;;;;;;;;;AAYA,SAAgB,wBAAwB,YAAkC;CACxE,IAAI,aAAa,KAAK,aAAa,GACjC,MAAM,IAAI,MAAM,qCAAqC;CAGvD,MAAM,4BAAY,IAAI,IAAqB;CAE3C,QAAQ,cAAmC;EACzC,MAAM,EAAE,YAAY;EAEpB,IAAI,CAAC,UAAU,IAAI,OAAO,GACxB,UAAU,IAAI,SAAS,KAAK,OAAO,IAAI,UAAU;EAGnD,OAAO,UAAU,IAAI,OAAO;CAC9B;AACF;;;;;;;;;;;AAYA,SAAgB,6BAA2C;CACzD,QAAQ,cAAmC;EAEzC,OAAO,UAAU,cAAc,OAAO,SAAS;CACjD;AACF;;;;;;;;;;;AAYA,SAAgB,0BAA0B,aAAmC;CAC3E,QAAQ,cAAmC;EAEzC,OADiB,cAAc,UAAU,aAC3B,KAAK;CACrB;AACF;;;;;;;;;;;;;;;AAgBA,SAAgB,oBAAoB,GAAG,UAAwC;CAC7E,IAAI,SAAS,WAAW,GACtB,MAAM,IAAI,MAAM,mDAAmD;CAGrE,QAAQ,cAAmC;EACzC,OAAO,SAAS,MAAM,YAAY,QAAQ,SAAS,CAAC;CACtD;AACF;;;;;;;;;;;;;AAcA,SAAgB,wBACd,WACc;CACd,OAAO;AACT;;;;AAKA,SAAS,cAAc,MAA4B;CACjD,MAAM,QAAQ,KAAK,UAAU,KAAK,MAAO,KAAK,UAAU,KAAK;CAE7D,OADY,KAAK,QAAQ,KAAK,MAAO,KAAK,QAAQ,KAAK,MAC1C;AACf;;;;AAKA,MAAa,kBAAkB;;;;;CAK7B,kBACE,0BAA0B;EACxB,oBAAoB;EACpB,iBAAiB;CACnB,CAAC;;;;;CAMH,mBACE,0BAA0B;EACxB,oBAAoB;EACpB,iBAAiB;CACnB,CAAC;;;;;CAMH,iBACE,0BAA0B;EACxB,oBAAoB;EACpB,iBAAiB;CACnB,CAAC;;;;;CAMH,yBAAuC;;;;;CAMvC,kBAAgC,2BAA2B;AAC7D"}
package/dist/testing.d.ts CHANGED
@@ -1,2 +1 @@
1
-
2
- export { }
1
+ export { };
package/dist/testing.js CHANGED
@@ -1,3 +1 @@
1
-
2
- //# sourceMappingURL=testing.js.map
3
- //# sourceMappingURL=testing.js.map
1
+ export { };
@@ -0,0 +1,214 @@
1
+ import { Attributes, Context, Span, SpanOptions, TextMapPropagator } from "@opentelemetry/api";
2
+ import { ReadableSpan, ReadableSpan as ReadableSpan$1, Sampler, SpanExporter, SpanProcessor } from "@opentelemetry/sdk-trace-base";
3
+
4
+ //#region src/types.d.ts
5
+ /**
6
+ * Trigger types for edge handlers
7
+ * Can be a Request or any vendor-specific trigger type
8
+ */
9
+ type Trigger = Request | DOConstructorTrigger | WorkflowTrigger | 'do-alarm' | unknown;
10
+ interface DOConstructorTrigger {
11
+ id: string;
12
+ name?: string;
13
+ }
14
+ interface WorkflowTrigger {
15
+ type: 'workflow';
16
+ name: string;
17
+ }
18
+ /**
19
+ * Config types
20
+ */
21
+ interface OTLPExporterConfig {
22
+ url: string;
23
+ headers?: Record<string, string>;
24
+ }
25
+ type ExporterConfig = OTLPExporterConfig | SpanExporter;
26
+ interface ServiceConfig {
27
+ name: string;
28
+ namespace?: string;
29
+ version?: string;
30
+ }
31
+ interface ParentRatioSamplingConfig {
32
+ acceptRemote?: boolean;
33
+ ratio: number;
34
+ }
35
+ type HeadSamplerConf = Sampler | ParentRatioSamplingConfig;
36
+ interface SamplingConfig<HS extends HeadSamplerConf = HeadSamplerConf> {
37
+ headSampler?: HS;
38
+ tailSampler?: TailSampleFn;
39
+ }
40
+ interface InstrumentationOptions {
41
+ instrumentGlobalFetch?: boolean;
42
+ instrumentGlobalCache?: boolean;
43
+ /**
44
+ * Disable instrumentation entirely (useful for local development)
45
+ * When enabled, the handler is returned as-is without any instrumentation
46
+ * @default false
47
+ */
48
+ disabled?: boolean;
49
+ }
50
+ /**
51
+ * Utility types
52
+ */
53
+ type OrPromise<T> = T | Promise<T>;
54
+ /**
55
+ * Adapter event types
56
+ */
57
+ type FunnelStepStatus = 'started' | 'completed' | 'abandoned' | 'failed' | (string & {});
58
+ type OutcomeStatus = 'success' | 'failure' | 'partial' | (string & {});
59
+ interface EdgeEventBase {
60
+ [key: string]: unknown;
61
+ service: string;
62
+ timestamp: number;
63
+ attributes: Record<string, unknown>;
64
+ traceId?: string;
65
+ spanId?: string;
66
+ correlationId?: string;
67
+ name: string;
68
+ }
69
+ interface EdgeTrackEvent extends EdgeEventBase {
70
+ type: 'event';
71
+ event: string;
72
+ }
73
+ interface EdgeFunnelStepEvent extends EdgeEventBase {
74
+ type: 'funnel-step';
75
+ funnel: string;
76
+ status: FunnelStepStatus;
77
+ }
78
+ interface EdgeOutcomeEvent extends EdgeEventBase {
79
+ type: 'outcome';
80
+ operation: string;
81
+ outcome: OutcomeStatus;
82
+ }
83
+ interface EdgeValueEvent extends EdgeEventBase {
84
+ type: 'value';
85
+ metric: string;
86
+ value: number;
87
+ }
88
+ type EdgeEvent = EdgeTrackEvent | EdgeFunnelStepEvent | EdgeOutcomeEvent | EdgeValueEvent;
89
+ type EdgeSubscriber = (event: EdgeEvent) => OrPromise<void>;
90
+ interface FetcherConfig {
91
+ includeTraceContext?: boolean | ((request: Request) => boolean);
92
+ }
93
+ interface RouteServiceConfig {
94
+ service: string;
95
+ }
96
+ interface PostProcessParams {
97
+ /**
98
+ * The request object that was passed to the fetch handler.
99
+ */
100
+ request: Request;
101
+ /**
102
+ * The generated response object.
103
+ */
104
+ response: Response;
105
+ /**
106
+ * A readable version of the span object that can be used to access the span's attributes and events.
107
+ */
108
+ readable: ReadableSpan;
109
+ }
110
+ interface FetchHandlerConfig {
111
+ /**
112
+ * Whether to enable context propagation for incoming requests to `fetch`.
113
+ * This enables or disables distributed tracing from W3C Trace Context headers.
114
+ * @default true
115
+ */
116
+ acceptTraceContext?: boolean | ((request: Request) => boolean);
117
+ /**
118
+ * Allows further customization of the generated span, based on the request/response data.
119
+ */
120
+ postProcess?: (span: Span, ctx: PostProcessParams) => void;
121
+ /**
122
+ * Route patterns to include for fetch handler instrumentation.
123
+ * Supports glob patterns like '/api/**'.
124
+ * If not set, all routes are included.
125
+ */
126
+ include?: string[];
127
+ /**
128
+ * Route patterns to exclude from fetch handler instrumentation.
129
+ * Supports glob patterns like '/health' and '/_internal/**'.
130
+ * Exclusions take precedence over inclusions.
131
+ */
132
+ exclude?: string[];
133
+ /**
134
+ * Route-specific service mapping.
135
+ * The first matching pattern wins based on object iteration order.
136
+ */
137
+ routes?: Record<string, RouteServiceConfig>;
138
+ }
139
+ interface HandlerConfig {
140
+ fetch?: FetchHandlerConfig;
141
+ }
142
+ interface DataSafetyConfig {
143
+ /** Redact query parameters from URL attributes (default: false) */
144
+ redactQueryParams?: boolean;
145
+ /** Control D1 SQL statement capture: 'full' (default), 'obfuscated', or 'off' */
146
+ captureDbStatement?: 'off' | 'obfuscated' | 'full';
147
+ /** Only capture these email headers (lowercase). When set, other headers are excluded. */
148
+ emailHeaderAllowlist?: string[];
149
+ }
150
+ interface EdgeConfigBase {
151
+ service: ServiceConfig;
152
+ handlers?: HandlerConfig;
153
+ fetch?: FetcherConfig;
154
+ postProcessor?: PostProcessorFn;
155
+ sampling?: SamplingConfig;
156
+ propagator?: TextMapPropagator;
157
+ instrumentation?: InstrumentationOptions;
158
+ subscribers?: EdgeSubscriber[];
159
+ /** Opt-in data safety controls for sensitive attribute capture */
160
+ dataSafety?: DataSafetyConfig;
161
+ }
162
+ interface EdgeConfigExporter extends EdgeConfigBase {
163
+ exporter: ExporterConfig;
164
+ }
165
+ interface EdgeConfigSpanProcessors extends EdgeConfigBase {
166
+ spanProcessors: SpanProcessor | SpanProcessor[];
167
+ }
168
+ type EdgeConfig = EdgeConfigExporter | EdgeConfigSpanProcessors;
169
+ interface ResolvedEdgeConfig extends EdgeConfigBase {
170
+ handlers: Required<HandlerConfig>;
171
+ fetch: Required<FetcherConfig>;
172
+ postProcessor: PostProcessorFn;
173
+ sampling: Required<SamplingConfig<Sampler>>;
174
+ spanProcessors: SpanProcessor[];
175
+ propagator: TextMapPropagator;
176
+ instrumentation: InstrumentationOptions;
177
+ subscribers: EdgeSubscriber[];
178
+ }
179
+ /**
180
+ * Function types
181
+ */
182
+ type ResolveConfigFn<Env = any> = (env: Env, trigger: Trigger) => EdgeConfig;
183
+ type ConfigurationOption = EdgeConfig | ResolveConfigFn;
184
+ type PostProcessorFn = (spans: ReadableSpan[]) => ReadableSpan[];
185
+ type TailSampleFn = (traceInfo: LocalTrace) => boolean;
186
+ interface LocalTrace {
187
+ traceId: string;
188
+ spans: ReadableSpan[];
189
+ localRootSpan: ReadableSpan;
190
+ }
191
+ /**
192
+ * Span processor with flush support
193
+ */
194
+ type TraceFlushableSpanProcessor = SpanProcessor & {
195
+ forceFlush: (traceId?: string) => Promise<void>;
196
+ };
197
+ /**
198
+ * Handler instrumentation
199
+ */
200
+ interface InitialSpanInfo {
201
+ name: string;
202
+ options: SpanOptions;
203
+ context?: Context;
204
+ }
205
+ interface HandlerInstrumentation<T extends Trigger, R extends any> {
206
+ getInitialSpanInfo: (trigger: T) => InitialSpanInfo;
207
+ getAttributesFromResult?: (result: Awaited<R>) => Attributes;
208
+ instrumentTrigger?: (trigger: T) => T;
209
+ executionSucces?: (span: Span, trigger: T, result: Awaited<R>) => void;
210
+ executionFailed?: (span: Span, trigger: T, error?: any) => void;
211
+ }
212
+ //#endregion
213
+ export { WorkflowTrigger as A, ResolvedEdgeConfig as C, TailSampleFn as D, ServiceConfig as E, TraceFlushableSpanProcessor as O, ResolveConfigFn as S, SamplingConfig as T, OTLPExporterConfig as _, EdgeEvent as a, PostProcessorFn as b, EdgeSubscriber as c, ExporterConfig as d, FunnelStepStatus as f, LocalTrace as g, InstrumentationOptions as h, EdgeConfig as i, Trigger as k, EdgeTrackEvent as l, InitialSpanInfo as m, DOConstructorTrigger as n, EdgeFunnelStepEvent as o, HandlerInstrumentation as p, DataSafetyConfig as r, EdgeOutcomeEvent as s, ConfigurationOption as t, EdgeValueEvent as u, OrPromise as v, RouteServiceConfig as w, ReadableSpan$1 as x, OutcomeStatus as y };
214
+ //# sourceMappingURL=types-HCbsjZzp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-HCbsjZzp.d.ts","names":[],"sources":["../src/types.ts"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autotel-edge",
3
- "version": "3.16.13",
3
+ "version": "3.16.15",
4
4
  "description": "Vendor-agnostic OpenTelemetry for edge runtimes - foundation for Cloudflare, Vercel, Netlify, Deno",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -64,11 +64,11 @@
64
64
  },
65
65
  "devDependencies": {
66
66
  "@opentelemetry/context-async-hooks": "^2.7.1",
67
- "@types/node": "^25.9.1",
67
+ "@types/node": "^25.9.2",
68
68
  "rimraf": "^6.1.3",
69
- "tsup": "^8.5.1",
69
+ "tsdown": "^0.22.2",
70
70
  "typescript": "^6.0.3",
71
- "vitest": "^4.1.7",
71
+ "vitest": "^4.1.8",
72
72
  "vitest-mock-extended": "^4.0.0"
73
73
  },
74
74
  "repository": {
@@ -81,8 +81,8 @@
81
81
  },
82
82
  "homepage": "https://github.com/jagreehal/autotel/tree/main/packages/autotel-edge#readme",
83
83
  "scripts": {
84
- "build": "tsup",
85
- "dev": "tsup --watch",
84
+ "build": "tsdown",
85
+ "dev": "tsdown --watch",
86
86
  "lint": "eslint src/**/*.ts",
87
87
  "lint:fix": "eslint src/**/*.ts --fix",
88
88
  "type-check": "tsc --noEmit",
@@ -11,6 +11,7 @@ import { Buffer } from 'node:buffer';
11
11
  //@ts-ignore
12
12
  globalThis.Buffer = Buffer;
13
13
 
14
-
15
-
16
- export {Buffer} from 'node:buffer';
14
+ // Re-export the single imported binding. Importing AND re-exporting `Buffer`
15
+ // from 'node:buffer' separately makes rolldown (tsdown) emit a dangling
16
+ // `Buffer$1` reference, so keep exactly one binding.
17
+ export { Buffer };
@@ -0,0 +1,55 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { trace } from '@opentelemetry/api';
3
+ import { resourceFromAttributes } from '@opentelemetry/resources';
4
+ import { SamplingDecision, type SpanProcessor } from '@opentelemetry/sdk-trace-base';
5
+ import { WorkerTracerProvider } from './provider';
6
+
7
+ const noopProcessor: SpanProcessor = {
8
+ onStart: () => {},
9
+ onEnd: () => {},
10
+ shutdown: async () => {},
11
+ forceFlush: async () => {},
12
+ };
13
+
14
+ /**
15
+ * Regression guard for Issue 1.1: register() must register the context manager
16
+ * with the global OTel API, otherwise the active span is lost after the first
17
+ * `await` and consumers that resolve trace context from the active span
18
+ * (autotel-agent / autotel-audit inside a handler or Workflow step) break.
19
+ *
20
+ * NOTE: this test registers a global context manager, so it lives in its own
21
+ * file to avoid leaking that global state into other suites.
22
+ */
23
+ describe('WorkerTracerProvider global context propagation', () => {
24
+ it('keeps the active span across an await after register()', async () => {
25
+ const provider = new WorkerTracerProvider(
26
+ [noopProcessor],
27
+ resourceFromAttributes({}),
28
+ );
29
+ provider.register();
30
+
31
+ // The provider's WorkerTracer needs a head sampler (normally set from config).
32
+ (
33
+ provider.getTracer('test') as unknown as {
34
+ setHeadSampler(s: unknown): void;
35
+ }
36
+ ).setHeadSampler({
37
+ shouldSample: () => ({
38
+ decision: SamplingDecision.RECORD_AND_SAMPLED,
39
+ attributes: {},
40
+ traceState: undefined,
41
+ }),
42
+ toString: () => 'AlwaysOn',
43
+ });
44
+
45
+ // Resolve via the global API to prove the global registration took effect.
46
+ const tracer = trace.getTracer('test');
47
+
48
+ await tracer.startActiveSpan('op', async (span) => {
49
+ // Simulate the async work a handler / step.do() callback performs.
50
+ await Promise.resolve();
51
+ expect(trace.getActiveSpan()).toBe(span);
52
+ span.end();
53
+ });
54
+ });
55
+ });