autotel-cloudflare 3.1.0 → 4.0.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.
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +7 -0
- package/dist/agents.js.map +1 -1
- package/package.json +8 -4
- package/src/actors/alarms.ts +0 -225
- package/src/actors/index.ts +0 -36
- package/src/actors/instrument-actor.test.ts +0 -179
- package/src/actors/instrument-actor.ts +0 -574
- package/src/actors/sockets.ts +0 -217
- package/src/actors/storage.ts +0 -263
- package/src/actors/traced-handler.ts +0 -300
- package/src/actors/types.ts +0 -98
- package/src/actors.ts +0 -50
- package/src/agents/agent.ts +0 -327
- package/src/agents/base.ts +0 -26
- package/src/agents/index.ts +0 -46
- package/src/agents/mcp.ts +0 -38
- package/src/agents/observability.ts +0 -145
- package/src/agents/otel-observability.test.ts +0 -269
- package/src/agents/otel-observability.ts +0 -557
- package/src/agents/types.ts +0 -61
- package/src/agents.ts +0 -87
- package/src/bindings/ai.test.ts +0 -170
- package/src/bindings/ai.ts +0 -73
- package/src/bindings/analytics-engine.test.ts +0 -175
- package/src/bindings/analytics-engine.ts +0 -78
- package/src/bindings/bindings-cache.test.ts +0 -80
- package/src/bindings/bindings-detection.test.ts +0 -235
- package/src/bindings/bindings-this-binding.test.ts +0 -294
- package/src/bindings/bindings.ts +0 -720
- package/src/bindings/browser-rendering.test.ts +0 -160
- package/src/bindings/browser-rendering.ts +0 -70
- package/src/bindings/common.ts +0 -84
- package/src/bindings/hyperdrive.test.ts +0 -176
- package/src/bindings/hyperdrive.ts +0 -74
- package/src/bindings/images.test.ts +0 -262
- package/src/bindings/images.ts +0 -182
- package/src/bindings/index.ts +0 -20
- package/src/bindings/queue-producer.test.ts +0 -224
- package/src/bindings/queue-producer.ts +0 -105
- package/src/bindings/rate-limiter.test.ts +0 -140
- package/src/bindings/rate-limiter.ts +0 -69
- package/src/bindings/vectorize.test.ts +0 -362
- package/src/bindings/vectorize.ts +0 -86
- package/src/bindings.ts +0 -6
- package/src/events.ts +0 -6
- package/src/execution-logger.test.ts +0 -127
- package/src/execution-logger.ts +0 -112
- package/src/global/cache.test.ts +0 -292
- package/src/global/cache.ts +0 -164
- package/src/global/fetch.test.ts +0 -399
- package/src/global/fetch.ts +0 -136
- package/src/global/index.ts +0 -7
- package/src/handlers/durable-objects.test.ts +0 -524
- package/src/handlers/durable-objects.ts +0 -250
- package/src/handlers/index.ts +0 -6
- package/src/handlers/workflows.test.ts +0 -411
- package/src/handlers/workflows.ts +0 -345
- package/src/handlers.ts +0 -6
- package/src/index.ts +0 -91
- package/src/logger.ts +0 -15
- package/src/native/native-tracing.test.ts +0 -54
- package/src/native/native-tracing.ts +0 -83
- package/src/native.ts +0 -12
- package/src/parse-error.ts +0 -1
- package/src/sampling.ts +0 -6
- package/src/testing.ts +0 -6
- package/src/wrappers/cf-attributes.test.ts +0 -334
- package/src/wrappers/define-worker-fetch.test.ts +0 -102
- package/src/wrappers/define-worker-fetch.ts +0 -71
- package/src/wrappers/index.ts +0 -13
- package/src/wrappers/instrument.integration.test.ts +0 -578
- package/src/wrappers/instrument.ts +0 -806
- package/src/wrappers/native-instrument.test.ts +0 -153
- package/src/wrappers/wrap-do.ts +0 -34
- package/src/wrappers/wrap-module.ts +0 -37
|
@@ -1,578 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { instrument } from './instrument';
|
|
3
|
-
import { trace } from 'autotel-edge';
|
|
4
|
-
import type { ExportedHandler } from '@cloudflare/workers-types';
|
|
5
|
-
|
|
6
|
-
describe('Handler Instrumentation - Integration Tests', () => {
|
|
7
|
-
interface Env {
|
|
8
|
-
OTLP_ENDPOINT?: string;
|
|
9
|
-
API_KEY?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
describe('instrument() for Fetch Handlers', () => {
|
|
13
|
-
it('should instrument a basic fetch handler', async () => {
|
|
14
|
-
const handler: ExportedHandler<Env> = {
|
|
15
|
-
async fetch(request, env, ctx) {
|
|
16
|
-
return new Response('Hello World', { status: 200 });
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const instrumented = instrument(handler, (env: Env) => ({
|
|
21
|
-
service: {
|
|
22
|
-
name: 'test-worker',
|
|
23
|
-
version: '1.0.0',
|
|
24
|
-
},
|
|
25
|
-
exporter: {
|
|
26
|
-
url: env.OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
|
|
27
|
-
headers: { 'x-api-key': env.API_KEY || 'test-key' },
|
|
28
|
-
},
|
|
29
|
-
}));
|
|
30
|
-
|
|
31
|
-
expect(instrumented).toBeDefined();
|
|
32
|
-
expect(typeof instrumented.fetch).toBe('function');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('should create a new handler that wraps the original', async () => {
|
|
36
|
-
let handlerCalled = false;
|
|
37
|
-
|
|
38
|
-
const handler: ExportedHandler<Env> = {
|
|
39
|
-
async fetch(request, env, ctx) {
|
|
40
|
-
handlerCalled = true;
|
|
41
|
-
return new Response('Hello World', { status: 200 });
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const instrumented = instrument(handler, {
|
|
46
|
-
service: { name: 'test-worker' },
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const request = new Request('http://example.com/test');
|
|
50
|
-
const env = {} as Env;
|
|
51
|
-
const ctx = {
|
|
52
|
-
waitUntil: vi.fn(),
|
|
53
|
-
passThroughOnException: vi.fn(),
|
|
54
|
-
} as any;
|
|
55
|
-
|
|
56
|
-
await instrumented.fetch(request, env, ctx);
|
|
57
|
-
|
|
58
|
-
expect(handlerCalled).toBe(true);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should call waitUntil to flush spans', async () => {
|
|
62
|
-
const handler: ExportedHandler<Env> = {
|
|
63
|
-
async fetch(request, env, ctx) {
|
|
64
|
-
return new Response('Hello World', { status: 200 });
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const instrumented = instrument(handler, {
|
|
69
|
-
service: { name: 'test-worker' },
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const request = new Request('http://example.com/test');
|
|
73
|
-
const env = {} as Env;
|
|
74
|
-
const waitUntilSpy = vi.fn();
|
|
75
|
-
const ctx = {
|
|
76
|
-
waitUntil: waitUntilSpy,
|
|
77
|
-
passThroughOnException: vi.fn(),
|
|
78
|
-
} as any;
|
|
79
|
-
|
|
80
|
-
await instrumented.fetch(request, env, ctx);
|
|
81
|
-
|
|
82
|
-
// waitUntil should be called to flush spans
|
|
83
|
-
expect(waitUntilSpy).toHaveBeenCalled();
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should preserve handler errors', async () => {
|
|
87
|
-
const handler: ExportedHandler<Env> = {
|
|
88
|
-
async fetch(request, env, ctx) {
|
|
89
|
-
throw new Error('Handler error');
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const instrumented = instrument(handler, {
|
|
94
|
-
service: { name: 'test-worker' },
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const request = new Request('http://example.com/test');
|
|
98
|
-
const env = {} as Env;
|
|
99
|
-
const ctx = {
|
|
100
|
-
waitUntil: vi.fn(),
|
|
101
|
-
passThroughOnException: vi.fn(),
|
|
102
|
-
} as any;
|
|
103
|
-
|
|
104
|
-
await expect(instrumented.fetch(request, env, ctx)).rejects.toThrow('Handler error');
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('should work with trace() functions inside handler', async () => {
|
|
108
|
-
const createUser = trace(async function createUser(email: string) {
|
|
109
|
-
return { id: '123', email };
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
const handler: ExportedHandler<Env> = {
|
|
113
|
-
async fetch(request, env, ctx) {
|
|
114
|
-
const user = await createUser('test@example.com');
|
|
115
|
-
return Response.json(user);
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const instrumented = instrument(handler, {
|
|
120
|
-
service: { name: 'test-worker' },
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
const request = new Request('http://example.com/users');
|
|
124
|
-
const env = {} as Env;
|
|
125
|
-
const ctx = {
|
|
126
|
-
waitUntil: vi.fn(),
|
|
127
|
-
passThroughOnException: vi.fn(),
|
|
128
|
-
} as any;
|
|
129
|
-
|
|
130
|
-
const response = await instrumented.fetch(request, env, ctx);
|
|
131
|
-
const data = await response.json();
|
|
132
|
-
|
|
133
|
-
expect(data).toEqual({ id: '123', email: 'test@example.com' });
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('should accept static config object', async () => {
|
|
137
|
-
const handler: ExportedHandler<Env> = {
|
|
138
|
-
async fetch(request, env, ctx) {
|
|
139
|
-
return new Response('Hello', { status: 200 });
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const instrumented = instrument(handler, {
|
|
144
|
-
service: {
|
|
145
|
-
name: 'test-worker',
|
|
146
|
-
version: '1.0.0',
|
|
147
|
-
namespace: 'testing',
|
|
148
|
-
},
|
|
149
|
-
exporter: {
|
|
150
|
-
url: 'http://localhost:4318/v1/traces',
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
expect(instrumented).toBeDefined();
|
|
155
|
-
expect(typeof instrumented.fetch).toBe('function');
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should accept config function', async () => {
|
|
159
|
-
const handler: ExportedHandler<Env> = {
|
|
160
|
-
async fetch(request, env, ctx) {
|
|
161
|
-
return new Response('Hello', { status: 200 });
|
|
162
|
-
},
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
const instrumented = instrument(handler, (env: Env) => ({
|
|
166
|
-
service: { name: env.OTLP_ENDPOINT ? 'prod-worker' : 'dev-worker' },
|
|
167
|
-
}));
|
|
168
|
-
|
|
169
|
-
expect(instrumented).toBeDefined();
|
|
170
|
-
expect(typeof instrumented.fetch).toBe('function');
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
describe('Handler with Scheduled Events', () => {
|
|
175
|
-
it('should instrument scheduled handler', async () => {
|
|
176
|
-
let scheduledCalled = false;
|
|
177
|
-
|
|
178
|
-
const handler: ExportedHandler<Env> = {
|
|
179
|
-
async fetch(request, env, ctx) {
|
|
180
|
-
return new Response('Hello', { status: 200 });
|
|
181
|
-
},
|
|
182
|
-
async scheduled(event, env, ctx) {
|
|
183
|
-
scheduledCalled = true;
|
|
184
|
-
},
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
const instrumented = instrument(handler, {
|
|
188
|
-
service: { name: 'test-worker' },
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
expect(instrumented.scheduled).toBeDefined();
|
|
192
|
-
|
|
193
|
-
if (instrumented.scheduled) {
|
|
194
|
-
const event = { scheduledTime: Date.now(), cron: '0 0 * * *' } as ScheduledController;
|
|
195
|
-
const env = {} as Env;
|
|
196
|
-
const ctx = {
|
|
197
|
-
waitUntil: vi.fn(),
|
|
198
|
-
passThroughOnException: vi.fn(),
|
|
199
|
-
} as any;
|
|
200
|
-
|
|
201
|
-
await instrumented.scheduled(event, env, ctx);
|
|
202
|
-
|
|
203
|
-
expect(scheduledCalled).toBe(true);
|
|
204
|
-
expect(ctx.waitUntil).toHaveBeenCalled();
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
describe('Handler with Queue Events', () => {
|
|
210
|
-
it('should instrument queue handler', async () => {
|
|
211
|
-
let queueCalled = false;
|
|
212
|
-
let messageCount = 0;
|
|
213
|
-
|
|
214
|
-
const handler: ExportedHandler<Env> = {
|
|
215
|
-
async queue(batch, env, ctx) {
|
|
216
|
-
queueCalled = true;
|
|
217
|
-
messageCount = batch.messages.length;
|
|
218
|
-
},
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
const instrumented = instrument(handler, {
|
|
222
|
-
service: { name: 'test-worker' },
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
expect(instrumented.queue).toBeDefined();
|
|
226
|
-
|
|
227
|
-
if (instrumented.queue) {
|
|
228
|
-
const batch = {
|
|
229
|
-
messages: [
|
|
230
|
-
{ id: '1', body: 'message1', timestamp: new Date() },
|
|
231
|
-
{ id: '2', body: 'message2', timestamp: new Date() },
|
|
232
|
-
],
|
|
233
|
-
queue: 'test-queue',
|
|
234
|
-
ackAll: vi.fn(),
|
|
235
|
-
retryAll: vi.fn(),
|
|
236
|
-
} as MessageBatch;
|
|
237
|
-
const env = {} as Env;
|
|
238
|
-
const ctx = {
|
|
239
|
-
waitUntil: vi.fn(),
|
|
240
|
-
passThroughOnException: vi.fn(),
|
|
241
|
-
} as any;
|
|
242
|
-
|
|
243
|
-
await instrumented.queue(batch, env, ctx);
|
|
244
|
-
|
|
245
|
-
expect(queueCalled).toBe(true);
|
|
246
|
-
expect(messageCount).toBe(2);
|
|
247
|
-
expect(ctx.waitUntil).toHaveBeenCalled();
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
it('should track message ack operations', async () => {
|
|
252
|
-
const handler: ExportedHandler<Env> = {
|
|
253
|
-
async queue(batch, env, ctx) {
|
|
254
|
-
// Ack individual messages
|
|
255
|
-
batch.messages[0].ack();
|
|
256
|
-
batch.messages[1].ack();
|
|
257
|
-
},
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
const instrumented = instrument(handler, {
|
|
261
|
-
service: { name: 'test-worker' },
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
if (instrumented.queue) {
|
|
265
|
-
const messages = [
|
|
266
|
-
{ id: '1', body: 'message1', timestamp: new Date(), ack: vi.fn(), retry: vi.fn() },
|
|
267
|
-
{ id: '2', body: 'message2', timestamp: new Date(), ack: vi.fn(), retry: vi.fn() },
|
|
268
|
-
];
|
|
269
|
-
const batch = {
|
|
270
|
-
messages,
|
|
271
|
-
queue: 'test-queue',
|
|
272
|
-
ackAll: vi.fn(),
|
|
273
|
-
retryAll: vi.fn(),
|
|
274
|
-
} as MessageBatch;
|
|
275
|
-
const env = {} as Env;
|
|
276
|
-
const ctx = {
|
|
277
|
-
waitUntil: vi.fn(),
|
|
278
|
-
passThroughOnException: vi.fn(),
|
|
279
|
-
} as any;
|
|
280
|
-
|
|
281
|
-
await instrumented.queue(batch, env, ctx);
|
|
282
|
-
|
|
283
|
-
// Verify ack was called on both messages
|
|
284
|
-
expect(messages[0].ack).toHaveBeenCalled();
|
|
285
|
-
expect(messages[1].ack).toHaveBeenCalled();
|
|
286
|
-
}
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
it('should track message retry operations', async () => {
|
|
290
|
-
const handler: ExportedHandler<Env> = {
|
|
291
|
-
async queue(batch, env, ctx) {
|
|
292
|
-
// Retry a message
|
|
293
|
-
batch.messages[0].retry();
|
|
294
|
-
},
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
const instrumented = instrument(handler, {
|
|
298
|
-
service: { name: 'test-worker' },
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
if (instrumented.queue) {
|
|
302
|
-
const messages = [
|
|
303
|
-
{ id: '1', body: 'message1', timestamp: new Date(), ack: vi.fn(), retry: vi.fn() },
|
|
304
|
-
];
|
|
305
|
-
const batch = {
|
|
306
|
-
messages,
|
|
307
|
-
queue: 'test-queue',
|
|
308
|
-
ackAll: vi.fn(),
|
|
309
|
-
retryAll: vi.fn(),
|
|
310
|
-
} as MessageBatch;
|
|
311
|
-
const env = {} as Env;
|
|
312
|
-
const ctx = {
|
|
313
|
-
waitUntil: vi.fn(),
|
|
314
|
-
passThroughOnException: vi.fn(),
|
|
315
|
-
} as any;
|
|
316
|
-
|
|
317
|
-
await instrumented.queue(batch, env, ctx);
|
|
318
|
-
|
|
319
|
-
// Verify retry was called
|
|
320
|
-
expect(messages[0].retry).toHaveBeenCalled();
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
it('should track ackAll operation', async () => {
|
|
325
|
-
const handler: ExportedHandler<Env> = {
|
|
326
|
-
async queue(batch, env, ctx) {
|
|
327
|
-
batch.ackAll();
|
|
328
|
-
},
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
const instrumented = instrument(handler, {
|
|
332
|
-
service: { name: 'test-worker' },
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
if (instrumented.queue) {
|
|
336
|
-
const ackAllFn = vi.fn();
|
|
337
|
-
const batch = {
|
|
338
|
-
messages: [
|
|
339
|
-
{ id: '1', body: 'message1', timestamp: new Date() },
|
|
340
|
-
{ id: '2', body: 'message2', timestamp: new Date() },
|
|
341
|
-
],
|
|
342
|
-
queue: 'test-queue',
|
|
343
|
-
ackAll: ackAllFn,
|
|
344
|
-
retryAll: vi.fn(),
|
|
345
|
-
} as MessageBatch;
|
|
346
|
-
const env = {} as Env;
|
|
347
|
-
const ctx = {
|
|
348
|
-
waitUntil: vi.fn(),
|
|
349
|
-
passThroughOnException: vi.fn(),
|
|
350
|
-
} as any;
|
|
351
|
-
|
|
352
|
-
await instrumented.queue(batch, env, ctx);
|
|
353
|
-
|
|
354
|
-
expect(ackAllFn).toHaveBeenCalled();
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
describe('Handler with Email Events', () => {
|
|
360
|
-
it('should instrument email handler', async () => {
|
|
361
|
-
let emailCalled = false;
|
|
362
|
-
|
|
363
|
-
const handler: ExportedHandler<Env> = {
|
|
364
|
-
async email(message, env, ctx) {
|
|
365
|
-
emailCalled = true;
|
|
366
|
-
},
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
const instrumented = instrument(handler, {
|
|
370
|
-
service: { name: 'test-worker' },
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
expect(instrumented.email).toBeDefined();
|
|
374
|
-
|
|
375
|
-
if (instrumented.email) {
|
|
376
|
-
const message = {
|
|
377
|
-
from: 'sender@example.com',
|
|
378
|
-
to: 'recipient@example.com',
|
|
379
|
-
headers: new Headers({ subject: 'Test Email' }),
|
|
380
|
-
} as ForwardableEmailMessage;
|
|
381
|
-
const env = {} as Env;
|
|
382
|
-
const ctx = {
|
|
383
|
-
waitUntil: vi.fn(),
|
|
384
|
-
passThroughOnException: vi.fn(),
|
|
385
|
-
} as any;
|
|
386
|
-
|
|
387
|
-
await instrumented.email(message, env, ctx);
|
|
388
|
-
|
|
389
|
-
expect(emailCalled).toBe(true);
|
|
390
|
-
expect(ctx.waitUntil).toHaveBeenCalled();
|
|
391
|
-
}
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
describe('Context Propagation', () => {
|
|
396
|
-
it('should propagate trace context from request headers', async () => {
|
|
397
|
-
const incomingTraceId = '0af7651916cd43dd8448eb211c80319c';
|
|
398
|
-
const incomingSpanId = 'b7ad6b7169203331';
|
|
399
|
-
let capturedTraceId: string | undefined;
|
|
400
|
-
let capturedParentSpanId: string | undefined;
|
|
401
|
-
|
|
402
|
-
const handler: ExportedHandler<Env> = {
|
|
403
|
-
async fetch(_request, _env, _ctx) {
|
|
404
|
-
const { trace: traceApi, context: contextApi } = await import('@opentelemetry/api');
|
|
405
|
-
const span = traceApi.getActiveSpan();
|
|
406
|
-
capturedTraceId = span?.spanContext().traceId;
|
|
407
|
-
capturedParentSpanId = (span as any)?.parentSpanId;
|
|
408
|
-
return new Response('OK', { status: 200 });
|
|
409
|
-
},
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
const instrumented = instrument(handler, {
|
|
413
|
-
service: { name: 'test-worker' },
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
const request = new Request('http://example.com/test', {
|
|
417
|
-
headers: {
|
|
418
|
-
'traceparent': `00-${incomingTraceId}-${incomingSpanId}-01`,
|
|
419
|
-
},
|
|
420
|
-
});
|
|
421
|
-
const env = {} as Env;
|
|
422
|
-
const ctx = {
|
|
423
|
-
waitUntil: vi.fn(),
|
|
424
|
-
passThroughOnException: vi.fn(),
|
|
425
|
-
} as any;
|
|
426
|
-
|
|
427
|
-
await instrumented.fetch(request, env, ctx);
|
|
428
|
-
|
|
429
|
-
// The server span must inherit the traceId from the incoming traceparent header
|
|
430
|
-
expect(capturedTraceId).toBe(incomingTraceId);
|
|
431
|
-
// The server span's parent must be the incoming spanId
|
|
432
|
-
expect(capturedParentSpanId).toBe(incomingSpanId);
|
|
433
|
-
});
|
|
434
|
-
});
|
|
435
|
-
|
|
436
|
-
describe('Fetch handler span status based on HTTP status code', () => {
|
|
437
|
-
it('should set OK status for 2xx responses', async () => {
|
|
438
|
-
const handler: ExportedHandler<Env> = {
|
|
439
|
-
async fetch(request, env, ctx) {
|
|
440
|
-
return new Response('OK', { status: 200 });
|
|
441
|
-
},
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
const instrumented = instrument(handler, {
|
|
445
|
-
service: { name: 'test-worker' },
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
const request = new Request('http://example.com/test');
|
|
449
|
-
const env = {} as Env;
|
|
450
|
-
const ctx = {
|
|
451
|
-
waitUntil: vi.fn(),
|
|
452
|
-
passThroughOnException: vi.fn(),
|
|
453
|
-
} as any;
|
|
454
|
-
|
|
455
|
-
const response = await instrumented.fetch(request, env, ctx);
|
|
456
|
-
expect(response.status).toBe(200);
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
it('should set OK status for 404 responses (client error, not server fault)', async () => {
|
|
460
|
-
const handler: ExportedHandler<Env> = {
|
|
461
|
-
async fetch(request, env, ctx) {
|
|
462
|
-
return new Response('Not Found', { status: 404 });
|
|
463
|
-
},
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
const instrumented = instrument(handler, {
|
|
467
|
-
service: { name: 'test-worker' },
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
const request = new Request('http://example.com/missing');
|
|
471
|
-
const env = {} as Env;
|
|
472
|
-
const ctx = {
|
|
473
|
-
waitUntil: vi.fn(),
|
|
474
|
-
passThroughOnException: vi.fn(),
|
|
475
|
-
} as any;
|
|
476
|
-
|
|
477
|
-
const response = await instrumented.fetch(request, env, ctx);
|
|
478
|
-
expect(response.status).toBe(404);
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
it('should return 500 responses correctly (span ERROR status applied internally)', async () => {
|
|
482
|
-
const handler: ExportedHandler<Env> = {
|
|
483
|
-
async fetch(request, env, ctx) {
|
|
484
|
-
return new Response('Internal Server Error', { status: 500 });
|
|
485
|
-
},
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
const instrumented = instrument(handler, {
|
|
489
|
-
service: { name: 'test-worker' },
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
const request = new Request('http://example.com/fail');
|
|
493
|
-
const env = {} as Env;
|
|
494
|
-
const ctx = {
|
|
495
|
-
waitUntil: vi.fn(),
|
|
496
|
-
passThroughOnException: vi.fn(),
|
|
497
|
-
} as any;
|
|
498
|
-
|
|
499
|
-
const response = await instrumented.fetch(request, env, ctx);
|
|
500
|
-
expect(response.status).toBe(500);
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
it('should still call postProcess after setting span status', async () => {
|
|
504
|
-
let postProcessCalled = false;
|
|
505
|
-
let postProcessResponse: Response | undefined;
|
|
506
|
-
|
|
507
|
-
const handler: ExportedHandler<Env> = {
|
|
508
|
-
async fetch(request, env, ctx) {
|
|
509
|
-
return new Response('Server Error', { status: 503 });
|
|
510
|
-
},
|
|
511
|
-
};
|
|
512
|
-
|
|
513
|
-
const instrumented = instrument(handler, (env: Env) => ({
|
|
514
|
-
service: { name: 'test-worker' },
|
|
515
|
-
handlers: {
|
|
516
|
-
fetch: {
|
|
517
|
-
postProcess(span, { response }) {
|
|
518
|
-
postProcessCalled = true;
|
|
519
|
-
postProcessResponse = response;
|
|
520
|
-
},
|
|
521
|
-
},
|
|
522
|
-
},
|
|
523
|
-
}));
|
|
524
|
-
|
|
525
|
-
const request = new Request('http://example.com/fail');
|
|
526
|
-
const env = {} as Env;
|
|
527
|
-
const ctx = {
|
|
528
|
-
waitUntil: vi.fn(),
|
|
529
|
-
passThroughOnException: vi.fn(),
|
|
530
|
-
} as any;
|
|
531
|
-
|
|
532
|
-
const response = await instrumented.fetch(request, env, ctx);
|
|
533
|
-
expect(response.status).toBe(503);
|
|
534
|
-
expect(postProcessCalled).toBe(true);
|
|
535
|
-
expect(postProcessResponse?.status).toBe(503);
|
|
536
|
-
});
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
describe('Multiple Handlers', () => {
|
|
540
|
-
it('should instrument multiple handlers independently', async () => {
|
|
541
|
-
const handler1: ExportedHandler<Env> = {
|
|
542
|
-
async fetch(request, env, ctx) {
|
|
543
|
-
return new Response('Handler 1', { status: 200 });
|
|
544
|
-
},
|
|
545
|
-
};
|
|
546
|
-
|
|
547
|
-
const handler2: ExportedHandler<Env> = {
|
|
548
|
-
async fetch(request, env, ctx) {
|
|
549
|
-
return new Response('Handler 2', { status: 200 });
|
|
550
|
-
},
|
|
551
|
-
};
|
|
552
|
-
|
|
553
|
-
const instrumented1 = instrument(handler1, {
|
|
554
|
-
service: { name: 'worker-1' },
|
|
555
|
-
});
|
|
556
|
-
|
|
557
|
-
const instrumented2 = instrument(handler2, {
|
|
558
|
-
service: { name: 'worker-2' },
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
const request = new Request('http://example.com/test');
|
|
562
|
-
const env = {} as Env;
|
|
563
|
-
const ctx = {
|
|
564
|
-
waitUntil: vi.fn(),
|
|
565
|
-
passThroughOnException: vi.fn(),
|
|
566
|
-
} as any;
|
|
567
|
-
|
|
568
|
-
const response1 = await instrumented1.fetch(request, env, ctx);
|
|
569
|
-
const response2 = await instrumented2.fetch(request, env, ctx);
|
|
570
|
-
|
|
571
|
-
const text1 = await response1.text();
|
|
572
|
-
const text2 = await response2.text();
|
|
573
|
-
|
|
574
|
-
expect(text1).toBe('Handler 1');
|
|
575
|
-
expect(text2).toBe('Handler 2');
|
|
576
|
-
});
|
|
577
|
-
});
|
|
578
|
-
});
|