autotel-cloudflare 4.0.7 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -140
- package/dist/actors.d.ts +0 -1
- package/dist/actors.d.ts.map +1 -1
- package/dist/actors.js.map +1 -1
- package/dist/agents.d.ts +0 -1
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js.map +1 -1
- package/dist/{bindings-BG6hzGSN.js → bindings-DznsCwCn.js} +3 -3
- package/dist/bindings-DznsCwCn.js.map +1 -0
- package/dist/bindings-xEZcXo5r.d.ts.map +1 -1
- package/dist/bindings.js +1 -1
- package/dist/common-DiWH6nmG.js.map +1 -1
- package/dist/execution-logger-BxmgP8jF.js.map +1 -1
- package/dist/{execution-logger-tgQmJeeU.d.ts → execution-logger-CCn9HGYC.d.ts} +1 -2
- package/dist/execution-logger-CCn9HGYC.d.ts.map +1 -0
- package/dist/{handlers-C_VojUeA.d.ts → handlers-BRfAgfP7.d.ts} +2 -3
- package/dist/handlers-BRfAgfP7.d.ts.map +1 -0
- package/dist/{handlers-BAe65zoJ.js → handlers-BePc7OJU.js} +2 -2
- package/dist/handlers-BePc7OJU.js.map +1 -0
- package/dist/handlers.d.ts +1 -1
- package/dist/handlers.js +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +1 -1
- package/dist/{native-tracing-DSo5mody.d.ts → native-tracing-DFaGAoR7.d.ts} +1 -2
- package/dist/native-tracing-DFaGAoR7.d.ts.map +1 -0
- package/dist/native.d.ts +1 -1
- package/package.json +12 -12
- package/skills/autotel-cloudflare/SKILL.md +19 -15
- package/dist/bindings-BG6hzGSN.js.map +0 -1
- package/dist/execution-logger-tgQmJeeU.d.ts.map +0 -1
- package/dist/handlers-BAe65zoJ.js.map +0 -1
- package/dist/handlers-C_VojUeA.d.ts.map +0 -1
- package/dist/native-tracing-DSo5mody.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
The package direction is to make Cloudflare observability feel the same across Workers, Queues, Durable Objects, alarms, and Workflows:
|
|
24
24
|
|
|
25
25
|
- use Cloudflare-native wrappers to create the root span
|
|
26
|
-
- use
|
|
26
|
+
- use plain `trace(name?, fn)` for business logic, with ambient `getActiveTraceContext()` or explicit `withTracing({ name })((ctx) => fn)` when span access is needed
|
|
27
27
|
- prefer span attributes and one execution snapshot over scattered info logs
|
|
28
28
|
|
|
29
29
|
See [docs/CLOUDFLARE-DX.md](../../docs/CLOUDFLARE-DX.md) for the design target and review rules.
|
|
30
30
|
|
|
31
31
|
## Cloudflare native tracing (automatic)
|
|
32
32
|
|
|
33
|
-
Cloudflare Workers ship [native tracing](https://developers.cloudflare.com/workers/observability/traces/): enable it in Wrangler and Cloudflare instruments fetch/KV/R2/D1/handlers and exports OTLP to any backend
|
|
33
|
+
Cloudflare Workers ship [native tracing](https://developers.cloudflare.com/workers/observability/traces/): enable it in Wrangler and Cloudflare instruments fetch/KV/R2/D1/handlers and exports OTLP to any backend. No exporter code. autotel integrates **automatically**: the same `trace()`/`span()`/`enterSpan()` code nests inside Cloudflare's native waterfall when native tracing is on, and falls back to autotel's own OTLP pipeline everywhere else (other edge runtimes, native off, local `wrangler dev`).
|
|
34
34
|
|
|
35
35
|
```toml
|
|
36
36
|
# wrangler.toml — that's the only setup
|
|
@@ -40,7 +40,7 @@ enabled = true
|
|
|
40
40
|
|
|
41
41
|
When native tracing is active, autotel **defers to the platform**: it does not proxy-instrument bindings (no duplicate spans) and does not run its own exporter. It routes your custom spans to `tracing.enterSpan()` and surfaces the `cf-ray` id as `ctx.correlationId` + a `correlation.id` span attribute. Controlled by `nativeTracing: 'auto' | 'on' | 'off'` (default `'auto'`).
|
|
42
42
|
|
|
43
|
-
### Same code, both modes
|
|
43
|
+
### Same code, both modes: captured evidence
|
|
44
44
|
|
|
45
45
|
This is real output from [`apps/cloudflare-example`](../../apps/cloudflare-example) (`node scripts/capture-evidence.mjs`). Identical business logic, two runtimes:
|
|
46
46
|
|
|
@@ -64,7 +64,7 @@ This is real output from [`apps/cloudflare-example`](../../apps/cloudflare-examp
|
|
|
64
64
|
• payment.charge [ERROR] error=true exception.message="card declined" correlation.id=8f1c2d3e…-LHR
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
Note the native tree has **no `KV MY_KV: get` span
|
|
67
|
+
Note the native tree has **no `KV MY_KV: get` span**. Cloudflare emits that natively (your custom spans nest above it on deploy), so there are no duplicates.
|
|
68
68
|
|
|
69
69
|
Full details, degradation map, and the forward-compatible trace-id story: [docs/CLOUDFLARE-NATIVE-TRACING.md](../../docs/CLOUDFLARE-NATIVE-TRACING.md).
|
|
70
70
|
|
|
@@ -83,19 +83,19 @@ yarn add autotel-cloudflare
|
|
|
83
83
|
For just structured logs (no tracing setup required), import from `autotel-cloudflare/logger`:
|
|
84
84
|
|
|
85
85
|
```ts
|
|
86
|
-
import { createEdgeLogger } from 'autotel-cloudflare/logger'
|
|
86
|
+
import { createEdgeLogger } from 'autotel-cloudflare/logger';
|
|
87
87
|
|
|
88
|
-
const log = createEdgeLogger('my-worker', { level: 'info' })
|
|
88
|
+
const log = createEdgeLogger('my-worker', { level: 'info' });
|
|
89
89
|
|
|
90
90
|
export default {
|
|
91
91
|
async fetch() {
|
|
92
|
-
log.info({ user_id: 'u1' }, 'request handled')
|
|
93
|
-
return new Response('ok')
|
|
92
|
+
log.info({ user_id: 'u1' }, 'request handled');
|
|
93
|
+
return new Response('ok');
|
|
94
94
|
},
|
|
95
|
-
}
|
|
95
|
+
};
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
`autotel-cloudflare/logger` is the edge-clean entry: it re-exports `createEdgeLogger` from `autotel-edge/logger` plus the Cloudflare execution-logger helpers (`createWorkersLogger`, `getRequestLogger`, `getQueueLogger`). The root `autotel-cloudflare` import pulls in tracing, `AsyncLocalStorage`, and the wrappers
|
|
98
|
+
`autotel-cloudflare/logger` is the edge-clean entry: it re-exports `createEdgeLogger` from `autotel-edge/logger` plus the Cloudflare execution-logger helpers (`createWorkersLogger`, `getRequestLogger`, `getQueueLogger`). The root `autotel-cloudflare` import pulls in tracing, `AsyncLocalStorage`, and the wrappers. Only use it when you want spans.
|
|
99
99
|
|
|
100
100
|
## Quick Start
|
|
101
101
|
|
|
@@ -111,26 +111,26 @@ head_sampling_rate = 1.0 # Let autotel handle sampling
|
|
|
111
111
|
### 2. Instrument Your Worker
|
|
112
112
|
|
|
113
113
|
```typescript
|
|
114
|
-
import { wrapModule, trace } from 'autotel-cloudflare'
|
|
114
|
+
import { wrapModule, trace } from 'autotel-cloudflare';
|
|
115
115
|
|
|
116
116
|
// Zero-boilerplate function tracing
|
|
117
117
|
const processOrder = trace(async (orderId: string, kv: KVNamespace) => {
|
|
118
|
-
const order = await kv.get(orderId)
|
|
119
|
-
return order
|
|
120
|
-
})
|
|
118
|
+
const order = await kv.get(orderId); // Auto-instrumented!
|
|
119
|
+
return order;
|
|
120
|
+
});
|
|
121
121
|
|
|
122
122
|
export default wrapModule(
|
|
123
123
|
{
|
|
124
124
|
service: { name: 'my-worker' },
|
|
125
|
-
instrumentBindings: true,
|
|
126
|
-
sampling: 'adaptive'
|
|
125
|
+
instrumentBindings: true, // Auto-instrument KV, R2, D1, etc.
|
|
126
|
+
sampling: 'adaptive', // 10% baseline, 100% errors/slow
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
129
|
async fetch(req, env, ctx) {
|
|
130
|
-
return Response.json(await processOrder('123', env.ORDERS_KV))
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
)
|
|
130
|
+
return Response.json(await processOrder('123', env.ORDERS_KV));
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
);
|
|
134
134
|
```
|
|
135
135
|
|
|
136
136
|
## API Styles
|
|
@@ -140,33 +140,30 @@ export default wrapModule(
|
|
|
140
140
|
Inspired by workers-honeycomb-logger:
|
|
141
141
|
|
|
142
142
|
```typescript
|
|
143
|
-
import { wrapModule } from 'autotel-cloudflare'
|
|
143
|
+
import { wrapModule } from 'autotel-cloudflare';
|
|
144
144
|
|
|
145
145
|
const handler = {
|
|
146
146
|
async fetch(req, env, ctx) {
|
|
147
|
-
return new Response('Hello')
|
|
148
|
-
}
|
|
149
|
-
}
|
|
147
|
+
return new Response('Hello');
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
150
|
|
|
151
|
-
export default wrapModule(
|
|
152
|
-
{ service: { name: 'my-worker' } },
|
|
153
|
-
handler
|
|
154
|
-
)
|
|
151
|
+
export default wrapModule({ service: { name: 'my-worker' } }, handler);
|
|
155
152
|
```
|
|
156
153
|
|
|
157
154
|
### Style 2: instrument
|
|
158
155
|
|
|
159
156
|
```typescript
|
|
160
|
-
import { instrument } from 'autotel-cloudflare'
|
|
157
|
+
import { instrument } from 'autotel-cloudflare';
|
|
161
158
|
|
|
162
159
|
export default instrument(
|
|
163
160
|
{
|
|
164
161
|
async fetch(req, env, ctx) {
|
|
165
|
-
return new Response('Hello')
|
|
166
|
-
}
|
|
162
|
+
return new Response('Hello');
|
|
163
|
+
},
|
|
167
164
|
},
|
|
168
|
-
{ service: { name: 'my-worker' } }
|
|
169
|
-
)
|
|
165
|
+
{ service: { name: 'my-worker' } },
|
|
166
|
+
);
|
|
170
167
|
```
|
|
171
168
|
|
|
172
169
|
### Fetch Route Controls
|
|
@@ -174,7 +171,7 @@ export default instrument(
|
|
|
174
171
|
Filter which fetch routes are instrumented and map route patterns to service names:
|
|
175
172
|
|
|
176
173
|
```typescript
|
|
177
|
-
import { wrapModule } from 'autotel-cloudflare'
|
|
174
|
+
import { wrapModule } from 'autotel-cloudflare';
|
|
178
175
|
|
|
179
176
|
export default wrapModule(
|
|
180
177
|
{
|
|
@@ -192,10 +189,10 @@ export default wrapModule(
|
|
|
192
189
|
},
|
|
193
190
|
{
|
|
194
191
|
async fetch(req) {
|
|
195
|
-
return new Response('ok')
|
|
192
|
+
return new Response('ok');
|
|
196
193
|
},
|
|
197
194
|
},
|
|
198
|
-
)
|
|
195
|
+
);
|
|
199
196
|
```
|
|
200
197
|
|
|
201
198
|
### Style 3: Functional API (Unique)
|
|
@@ -203,22 +200,24 @@ export default wrapModule(
|
|
|
203
200
|
Zero-boilerplate function tracing:
|
|
204
201
|
|
|
205
202
|
```typescript
|
|
206
|
-
import { trace, span } from 'autotel-cloudflare'
|
|
203
|
+
import { trace, span, withTracing } from 'autotel-cloudflare';
|
|
207
204
|
|
|
208
205
|
// Automatic trace name inference
|
|
209
206
|
export const createUser = trace(async (data: UserData) => {
|
|
210
|
-
return await db.insert(data)
|
|
211
|
-
})
|
|
207
|
+
return await db.insert(data);
|
|
208
|
+
});
|
|
212
209
|
|
|
213
210
|
// Factory pattern for context access
|
|
214
|
-
export const processPayment =
|
|
215
|
-
ctx
|
|
211
|
+
export const processPayment = withTracing({ name: 'payment.process' })(
|
|
212
|
+
(ctx) => async (amount: number) => {
|
|
213
|
+
ctx.setAttribute('amount', amount);
|
|
216
214
|
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
await span('validate.card', () => validateCard());
|
|
216
|
+
await span('charge.card', () => chargeCard(amount));
|
|
219
217
|
|
|
220
|
-
|
|
221
|
-
}
|
|
218
|
+
return { success: true };
|
|
219
|
+
},
|
|
220
|
+
);
|
|
222
221
|
```
|
|
223
222
|
|
|
224
223
|
## Request Logger Bootstrap
|
|
@@ -226,7 +225,7 @@ export const processPayment = trace(ctx => async (amount: number) => {
|
|
|
226
225
|
Use `createWorkersLogger()` for request-scoped snapshots with Cloudflare context pre-filled.
|
|
227
226
|
|
|
228
227
|
```typescript
|
|
229
|
-
import { wrapModule, createWorkersLogger } from 'autotel-cloudflare'
|
|
228
|
+
import { wrapModule, createWorkersLogger } from 'autotel-cloudflare';
|
|
230
229
|
|
|
231
230
|
export default wrapModule(
|
|
232
231
|
{ service: { name: 'checkout-worker' } },
|
|
@@ -234,16 +233,16 @@ export default wrapModule(
|
|
|
234
233
|
async fetch(request) {
|
|
235
234
|
const log = createWorkersLogger(request, {
|
|
236
235
|
headers: ['x-request-id'],
|
|
237
|
-
})
|
|
236
|
+
});
|
|
238
237
|
|
|
239
|
-
log.info('checkout.started')
|
|
240
|
-
log.set({ checkout: { stage: 'validated' } })
|
|
241
|
-
log.emitNow({ status: 200 })
|
|
238
|
+
log.info('checkout.started');
|
|
239
|
+
log.set({ checkout: { stage: 'validated' } });
|
|
240
|
+
log.emitNow({ status: 200 });
|
|
242
241
|
|
|
243
|
-
return new Response('ok')
|
|
242
|
+
return new Response('ok');
|
|
244
243
|
},
|
|
245
244
|
},
|
|
246
|
-
)
|
|
245
|
+
);
|
|
247
246
|
```
|
|
248
247
|
|
|
249
248
|
## Complete Bindings Coverage
|
|
@@ -303,66 +302,74 @@ await env.ANALYTICS.writeDataPoint({ ... }) // → Span: "Analytics: writeDataP
|
|
|
303
302
|
### Adaptive Sampling (Recommended)
|
|
304
303
|
|
|
305
304
|
```typescript
|
|
306
|
-
import { SamplingPresets } from 'autotel-cloudflare/sampling'
|
|
305
|
+
import { SamplingPresets } from 'autotel-cloudflare/sampling';
|
|
307
306
|
|
|
308
307
|
wrapModule(
|
|
309
308
|
{
|
|
310
309
|
service: { name: 'my-worker' },
|
|
311
310
|
sampling: {
|
|
312
|
-
tailSampler: SamplingPresets.production()
|
|
311
|
+
tailSampler: SamplingPresets.production(),
|
|
313
312
|
// 10% baseline, 100% errors, 100% slow requests (>1s)
|
|
314
|
-
}
|
|
313
|
+
},
|
|
315
314
|
},
|
|
316
|
-
handler
|
|
317
|
-
)
|
|
315
|
+
handler,
|
|
316
|
+
);
|
|
318
317
|
```
|
|
319
318
|
|
|
320
319
|
### Available Presets
|
|
321
320
|
|
|
322
321
|
```typescript
|
|
323
322
|
// Development - 100% sampling
|
|
324
|
-
sampling: {
|
|
323
|
+
sampling: {
|
|
324
|
+
tailSampler: SamplingPresets.development();
|
|
325
|
+
}
|
|
325
326
|
|
|
326
327
|
// Production - 10% baseline, all errors, slow >1s
|
|
327
|
-
sampling: {
|
|
328
|
+
sampling: {
|
|
329
|
+
tailSampler: SamplingPresets.production();
|
|
330
|
+
}
|
|
328
331
|
|
|
329
332
|
// High traffic - 1% baseline, all errors, slow >1s
|
|
330
|
-
sampling: {
|
|
333
|
+
sampling: {
|
|
334
|
+
tailSampler: SamplingPresets.highTraffic();
|
|
335
|
+
}
|
|
331
336
|
|
|
332
337
|
// Debugging - errors only
|
|
333
|
-
sampling: {
|
|
338
|
+
sampling: {
|
|
339
|
+
tailSampler: SamplingPresets.debugging();
|
|
340
|
+
}
|
|
334
341
|
|
|
335
342
|
// Or use shorthand
|
|
336
|
-
sampling: 'adaptive'
|
|
337
|
-
sampling: 'error-only'
|
|
343
|
+
sampling: 'adaptive'; // Same as SamplingPresets.production()
|
|
344
|
+
sampling: 'error-only'; // Same as SamplingPresets.debugging()
|
|
338
345
|
```
|
|
339
346
|
|
|
340
347
|
### Custom Sampling
|
|
341
348
|
|
|
342
349
|
```typescript
|
|
343
|
-
import { createCustomTailSampler } from 'autotel-cloudflare/sampling'
|
|
350
|
+
import { createCustomTailSampler } from 'autotel-cloudflare/sampling';
|
|
344
351
|
|
|
345
352
|
const customSampler = createCustomTailSampler((trace) => {
|
|
346
|
-
const span = trace.localRootSpan
|
|
353
|
+
const span = trace.localRootSpan;
|
|
347
354
|
|
|
348
355
|
// Always sample /api/* endpoints
|
|
349
356
|
if (span.attributes['http.route']?.toString().startsWith('/api/')) {
|
|
350
|
-
return true
|
|
357
|
+
return true;
|
|
351
358
|
}
|
|
352
359
|
|
|
353
360
|
// Sample all errors
|
|
354
361
|
if (span.status.code === SpanStatusCode.ERROR) {
|
|
355
|
-
return true
|
|
362
|
+
return true;
|
|
356
363
|
}
|
|
357
364
|
|
|
358
365
|
// Sample slow requests
|
|
359
|
-
const duration = (span.endTime[0] - span.startTime[0]) / 1_000_000
|
|
366
|
+
const duration = (span.endTime[0] - span.startTime[0]) / 1_000_000;
|
|
360
367
|
if (duration > 1000) {
|
|
361
|
-
return true
|
|
368
|
+
return true;
|
|
362
369
|
}
|
|
363
370
|
|
|
364
|
-
return Math.random() < 0.1
|
|
365
|
-
})
|
|
371
|
+
return Math.random() < 0.1; // 10% of everything else
|
|
372
|
+
});
|
|
366
373
|
```
|
|
367
374
|
|
|
368
375
|
## Durable Objects
|
|
@@ -370,26 +377,23 @@ const customSampler = createCustomTailSampler((trace) => {
|
|
|
370
377
|
### Instrument Durable Object Class
|
|
371
378
|
|
|
372
379
|
```typescript
|
|
373
|
-
import { wrapDurableObject } from 'autotel-cloudflare'
|
|
380
|
+
import { wrapDurableObject } from 'autotel-cloudflare';
|
|
374
381
|
|
|
375
382
|
class Counter implements DurableObject {
|
|
376
383
|
async fetch(request: Request) {
|
|
377
384
|
// Auto-traced with span "Counter: fetch"
|
|
378
|
-
const count = await this.state.storage.get('count') || 0
|
|
379
|
-
await this.state.storage.put('count', count + 1)
|
|
380
|
-
return new Response(String(count + 1))
|
|
385
|
+
const count = (await this.state.storage.get('count')) || 0;
|
|
386
|
+
await this.state.storage.put('count', count + 1);
|
|
387
|
+
return new Response(String(count + 1));
|
|
381
388
|
}
|
|
382
389
|
|
|
383
390
|
async alarm() {
|
|
384
391
|
// Auto-traced with span "Counter: alarm"
|
|
385
|
-
console.log('Alarm triggered')
|
|
392
|
+
console.log('Alarm triggered');
|
|
386
393
|
}
|
|
387
394
|
}
|
|
388
395
|
|
|
389
|
-
export default wrapDurableObject(
|
|
390
|
-
{ service: { name: 'counter-do' } },
|
|
391
|
-
Counter
|
|
392
|
-
)
|
|
396
|
+
export default wrapDurableObject({ service: { name: 'counter-do' } }, Counter);
|
|
393
397
|
```
|
|
394
398
|
|
|
395
399
|
## Events Integration
|
|
@@ -397,7 +401,7 @@ export default wrapDurableObject(
|
|
|
397
401
|
Track product events with automatic trace correlation:
|
|
398
402
|
|
|
399
403
|
```typescript
|
|
400
|
-
import { publishEvent } from 'autotel-cloudflare/events'
|
|
404
|
+
import { publishEvent } from 'autotel-cloudflare/events';
|
|
401
405
|
|
|
402
406
|
wrapModule(
|
|
403
407
|
{
|
|
@@ -408,10 +412,10 @@ wrapModule(
|
|
|
408
412
|
// Send to your analytics platform
|
|
409
413
|
await fetch('https://analytics.example.com/events', {
|
|
410
414
|
method: 'POST',
|
|
411
|
-
body: JSON.stringify(event)
|
|
412
|
-
})
|
|
413
|
-
}
|
|
414
|
-
]
|
|
415
|
+
body: JSON.stringify(event),
|
|
416
|
+
});
|
|
417
|
+
},
|
|
418
|
+
],
|
|
415
419
|
},
|
|
416
420
|
{
|
|
417
421
|
async fetch(req, env, ctx) {
|
|
@@ -421,15 +425,15 @@ wrapModule(
|
|
|
421
425
|
userId: '123',
|
|
422
426
|
properties: {
|
|
423
427
|
orderId: 'abc',
|
|
424
|
-
amount: 99.99
|
|
425
|
-
}
|
|
428
|
+
amount: 99.99,
|
|
429
|
+
},
|
|
426
430
|
// Automatically includes current trace ID
|
|
427
|
-
})
|
|
431
|
+
});
|
|
428
432
|
|
|
429
|
-
return new Response('OK')
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
)
|
|
433
|
+
return new Response('OK');
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
);
|
|
433
437
|
```
|
|
434
438
|
|
|
435
439
|
## Configuration
|
|
@@ -437,7 +441,7 @@ wrapModule(
|
|
|
437
441
|
### Complete Example
|
|
438
442
|
|
|
439
443
|
```typescript
|
|
440
|
-
import { wrapModule, SamplingPresets } from 'autotel-cloudflare'
|
|
444
|
+
import { wrapModule, SamplingPresets } from 'autotel-cloudflare';
|
|
441
445
|
|
|
442
446
|
export default wrapModule(
|
|
443
447
|
{
|
|
@@ -445,7 +449,7 @@ export default wrapModule(
|
|
|
445
449
|
service: {
|
|
446
450
|
name: 'my-worker',
|
|
447
451
|
version: '1.0.0',
|
|
448
|
-
namespace: 'production'
|
|
452
|
+
namespace: 'production',
|
|
449
453
|
},
|
|
450
454
|
|
|
451
455
|
// Auto-instrument bindings
|
|
@@ -453,14 +457,14 @@ export default wrapModule(
|
|
|
453
457
|
|
|
454
458
|
// Global instrumentations
|
|
455
459
|
instrumentation: {
|
|
456
|
-
instrumentGlobalFetch: true,
|
|
457
|
-
instrumentGlobalCache: true,
|
|
458
|
-
disabled: false
|
|
460
|
+
instrumentGlobalFetch: true, // Trace all fetch() calls
|
|
461
|
+
instrumentGlobalCache: true, // Trace cache API
|
|
462
|
+
disabled: false, // Set true to disable all tracing
|
|
459
463
|
},
|
|
460
464
|
|
|
461
465
|
// Sampling strategy
|
|
462
466
|
sampling: {
|
|
463
|
-
tailSampler: SamplingPresets.production()
|
|
467
|
+
tailSampler: SamplingPresets.production(),
|
|
464
468
|
},
|
|
465
469
|
|
|
466
470
|
// Handler-specific config
|
|
@@ -468,16 +472,16 @@ export default wrapModule(
|
|
|
468
472
|
fetch: {
|
|
469
473
|
postProcess: (span, { request, response }) => {
|
|
470
474
|
// Add custom attributes
|
|
471
|
-
const url = new URL(request.url)
|
|
475
|
+
const url = new URL(request.url);
|
|
472
476
|
if (url.pathname.startsWith('/api/')) {
|
|
473
|
-
span.setAttribute('api.endpoint', url.pathname)
|
|
477
|
+
span.setAttribute('api.endpoint', url.pathname);
|
|
474
478
|
}
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
},
|
|
478
482
|
},
|
|
479
|
-
handler
|
|
480
|
-
)
|
|
483
|
+
handler,
|
|
484
|
+
);
|
|
481
485
|
```
|
|
482
486
|
|
|
483
487
|
### Dynamic Configuration
|
|
@@ -489,72 +493,76 @@ export default wrapModule(
|
|
|
489
493
|
service: { name: env.SERVICE_NAME || 'my-worker' },
|
|
490
494
|
exporter: {
|
|
491
495
|
url: env.OTEL_ENDPOINT,
|
|
492
|
-
headers: { 'x-api-key': env.API_KEY }
|
|
496
|
+
headers: { 'x-api-key': env.API_KEY },
|
|
493
497
|
},
|
|
494
498
|
sampling: {
|
|
495
|
-
tailSampler:
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
+
tailSampler:
|
|
500
|
+
env.ENVIRONMENT === 'production'
|
|
501
|
+
? SamplingPresets.production()
|
|
502
|
+
: SamplingPresets.development(),
|
|
503
|
+
},
|
|
499
504
|
}),
|
|
500
|
-
handler
|
|
501
|
-
)
|
|
505
|
+
handler,
|
|
506
|
+
);
|
|
502
507
|
```
|
|
503
508
|
|
|
504
509
|
## Entry Points (Tree-Shaking)
|
|
505
510
|
|
|
506
511
|
```typescript
|
|
507
512
|
// Main export (everything — pulls AsyncLocalStorage, needs nodejs_compat)
|
|
508
|
-
import { wrapModule, trace, instrument } from 'autotel-cloudflare'
|
|
513
|
+
import { wrapModule, trace, instrument } from 'autotel-cloudflare';
|
|
509
514
|
|
|
510
515
|
// Tree-shakeable entry points
|
|
511
|
-
import { instrumentKV, instrumentR2 } from 'autotel-cloudflare/bindings'
|
|
512
|
-
import { instrumentDO } from 'autotel-cloudflare/handlers'
|
|
513
|
-
import { SamplingPresets } from 'autotel-cloudflare/sampling'
|
|
514
|
-
import { publishEvent } from 'autotel-cloudflare/events'
|
|
515
|
-
import { createEdgeLogger } from 'autotel-cloudflare/logger'
|
|
516
|
-
import { createTraceCollector } from 'autotel-cloudflare/testing'
|
|
516
|
+
import { instrumentKV, instrumentR2 } from 'autotel-cloudflare/bindings';
|
|
517
|
+
import { instrumentDO } from 'autotel-cloudflare/handlers';
|
|
518
|
+
import { SamplingPresets } from 'autotel-cloudflare/sampling';
|
|
519
|
+
import { publishEvent } from 'autotel-cloudflare/events';
|
|
520
|
+
import { createEdgeLogger } from 'autotel-cloudflare/logger';
|
|
521
|
+
import { createTraceCollector } from 'autotel-cloudflare/testing';
|
|
517
522
|
```
|
|
518
523
|
|
|
519
524
|
## Cloudflare compatibility
|
|
520
525
|
|
|
521
526
|
Workers run on V8 isolates, not Node. Anything that transitively imports `node:async_hooks` (used by `AsyncLocalStorageContextManager` for span context) or `node:buffer` requires `compatibility_flags = ["nodejs_compat"]` in your `wrangler.toml`. The `/logger` subpath stays clear of those.
|
|
522
527
|
|
|
523
|
-
| Entry
|
|
524
|
-
|
|
|
525
|
-
| `autotel-cloudflare`
|
|
526
|
-
| `autotel-cloudflare/logger`
|
|
527
|
-
| `autotel-cloudflare/bindings`
|
|
528
|
-
| `autotel-cloudflare/handlers`
|
|
529
|
-
| `autotel-cloudflare/sampling`
|
|
530
|
-
| `autotel-cloudflare/events`
|
|
531
|
-
| `autotel-cloudflare/testing`
|
|
532
|
-
| `autotel-cloudflare/actors`
|
|
533
|
-
| `autotel-cloudflare/agents`
|
|
534
|
-
| `autotel-cloudflare/parse-error` | Yes
|
|
528
|
+
| Entry | Edge-safe without `nodejs_compat`? | Notes |
|
|
529
|
+
| -------------------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
530
|
+
| `autotel-cloudflare` | No: needs `nodejs_compat` | Pulls `AsyncLocalStorage` (span context) and `Buffer` transitively via `autotel-edge` root |
|
|
531
|
+
| `autotel-cloudflare/logger` | Yes | Edge-clean. `createEdgeLogger`, `createWorkersLogger`, `getRequestLogger`, `getQueueLogger`, `getWorkflowLogger`, `getActorLogger` |
|
|
532
|
+
| `autotel-cloudflare/bindings` | No: needs `nodejs_compat` | Wrappers create spans, require context manager |
|
|
533
|
+
| `autotel-cloudflare/handlers` | No: needs `nodejs_compat` | DO/Workflow wrappers create spans |
|
|
534
|
+
| `autotel-cloudflare/sampling` | Yes | Pure samplers, no runtime imports |
|
|
535
|
+
| `autotel-cloudflare/events` | No: needs `nodejs_compat` | Pulls trace context for correlation |
|
|
536
|
+
| `autotel-cloudflare/testing` | Yes (test-only) | Collectors live in test runtime; do not ship to Workers |
|
|
537
|
+
| `autotel-cloudflare/actors` | No: needs `nodejs_compat` | Builds on DO wrappers |
|
|
538
|
+
| `autotel-cloudflare/agents` | No: needs `nodejs_compat` | Builds on DO wrappers |
|
|
539
|
+
| `autotel-cloudflare/parse-error` | Yes | Pure error normaliser |
|
|
535
540
|
|
|
536
541
|
Rule of thumb: if you only need logs, import `autotel-cloudflare/logger` and skip `nodejs_compat`. If you want spans, add `nodejs_compat` and import from the root.
|
|
537
542
|
|
|
538
543
|
## See also
|
|
539
544
|
|
|
540
|
-
- [autotel-edge](../autotel-edge)
|
|
541
|
-
- [autotel](../autotel)
|
|
542
|
-
- [autotel-drizzle](../autotel-drizzle)
|
|
545
|
+
- [autotel-edge](../autotel-edge): vendor-agnostic foundation re-exported by this package
|
|
546
|
+
- [autotel](../autotel): Node.js entry, full SDK with auto-instrumentation
|
|
547
|
+
- [autotel-drizzle](../autotel-drizzle): Drizzle ORM spans (Node only)
|
|
543
548
|
|
|
544
549
|
## Testing
|
|
545
550
|
|
|
546
551
|
```typescript
|
|
547
|
-
import {
|
|
552
|
+
import {
|
|
553
|
+
createTraceCollector,
|
|
554
|
+
assertTraceCreated,
|
|
555
|
+
} from 'autotel-cloudflare/testing';
|
|
548
556
|
|
|
549
557
|
describe('my worker', () => {
|
|
550
558
|
it('creates traces', async () => {
|
|
551
|
-
const collector = createTraceCollector()
|
|
559
|
+
const collector = createTraceCollector();
|
|
552
560
|
|
|
553
|
-
await myFunction()
|
|
561
|
+
await myFunction();
|
|
554
562
|
|
|
555
|
-
assertTraceCreated(collector, 'myFunction')
|
|
556
|
-
})
|
|
557
|
-
})
|
|
563
|
+
assertTraceCreated(collector, 'myFunction');
|
|
564
|
+
});
|
|
565
|
+
});
|
|
558
566
|
```
|
|
559
567
|
|
|
560
568
|
## Examples
|
package/dist/actors.d.ts
CHANGED
package/dist/actors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actors.d.ts","names":[],"sources":["../src/actors/types.ts","../src/actors/instrument-actor.ts","../src/actors/traced-handler.ts","../src/actors/storage.ts","../src/actors/alarms.ts","../src/actors/sockets.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"actors.d.ts","names":[],"sources":["../src/actors/types.ts","../src/actors/instrument-actor.ts","../src/actors/traced-handler.ts","../src/actors/storage.ts","../src/actors/alarms.ts","../src/actors/sockets.ts"],"mappings":";;;;;UASiB;;;;;EAKf;;;;;EAMA;;;;;EAMA;;;;;EAMA;;;;EAKA,qBAAqB,mBAAmB;;;;;;KAO9B,cAAc;;;;EAIxB,SAAS;;;;;KAMC;;;;;UA2BK;EACf;EACA;EACA;EACA;EACA;EACA,OAAO,SAAS,UAAU,QAAQ;EAClC,OAAO,sBAAsB;;;;;KAMnB,iBAAiB,UAAU,YAAY,kBACjD,OAAO,oBACP,iBACG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC6fW,gBAAgB,UAAU,kBACxC,YAAY,GACZ,QAAQ,gBAAgB,cAAc,sBAAsB,eAC3D;;;;;;UCnkBO,cAAc;EACtB,MAAM,SAAS,SAAS,KAAK,GAAG,KAAK,mBAAmB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoClD,cAAc,GAAG,UAAU,WACzC,YAAY,iBAAiB;EAC3B,iBAAiB,SAAS,UAAU;EACpC,eAAe,SAAS;IACtB,eAAe;;GAGnB,QAAQ,gBAAgB,KAAK,GAAG,sBAAsB,eACrD,cAAc;;;;;;;;;;;;;;;;;;;iBAyKD,YAAY,GAC1B,iBAAiB,cAAc,IAC/B,QAAQ,gBAAgB,KAAK,GAAG,sBAAsB,eACrD,cAAc;;;;;;;;;;iBC9ND,uBACd,kBACA,eAAe,WACf;;;;;;;;;;;;iBCDc,sBACd,iBACA,eAAe,WACf;;;;;;;;;;;iBCJc,uBACd,kBACA,eAAe,WACf"}
|