autotel-cloudflare 2.12.0 → 2.13.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/dist/actors.js +1 -1
- package/dist/bindings.d.ts +113 -1
- package/dist/bindings.js +2 -2
- package/dist/chunk-4UG2QCPQ.js +1060 -0
- package/dist/chunk-4UG2QCPQ.js.map +1 -0
- package/dist/{chunk-5NL62W4L.js → chunk-O4IYKWPJ.js} +8 -3
- package/dist/chunk-O4IYKWPJ.js.map +1 -0
- package/dist/{chunk-ADWSZ5GY.js → chunk-ZJPX4N7S.js} +3 -3
- package/dist/{chunk-ADWSZ5GY.js.map → chunk-ZJPX4N7S.js.map} +1 -1
- package/dist/handlers.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +34 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/bindings/ai.test.ts +156 -0
- package/src/bindings/ai.ts +71 -0
- package/src/bindings/analytics-engine.test.ts +160 -0
- package/src/bindings/analytics-engine.ts +78 -0
- package/src/bindings/bindings-detection.test.ts +235 -0
- package/src/bindings/bindings.ts +98 -47
- package/src/bindings/browser-rendering.test.ts +144 -0
- package/src/bindings/browser-rendering.ts +70 -0
- package/src/bindings/common.ts +9 -0
- package/src/bindings/hyperdrive.test.ts +154 -0
- package/src/bindings/hyperdrive.ts +74 -0
- package/src/bindings/images.test.ts +229 -0
- package/src/bindings/images.ts +182 -0
- package/src/bindings/index.ts +8 -0
- package/src/bindings/queue-producer.test.ts +192 -0
- package/src/bindings/queue-producer.ts +105 -0
- package/src/bindings/rate-limiter.test.ts +124 -0
- package/src/bindings/rate-limiter.ts +69 -0
- package/src/bindings/vectorize.test.ts +340 -0
- package/src/bindings/vectorize.ts +86 -0
- package/src/index.ts +8 -0
- package/src/wrappers/cf-attributes.test.ts +275 -0
- package/src/wrappers/instrument.ts +38 -0
- package/dist/chunk-5NL62W4L.js.map +0 -1
- package/dist/chunk-UPQE3J4I.js +0 -520
- package/dist/chunk-UPQE3J4I.js.map +0 -1
|
@@ -0,0 +1,1060 @@
|
|
|
1
|
+
import { wrap, isWrapped, setAttr } from './chunk-O4IYKWPJ.js';
|
|
2
|
+
import { trace, SpanKind, SpanStatusCode } from '@opentelemetry/api';
|
|
3
|
+
|
|
4
|
+
function instrumentAI(ai, bindingName) {
|
|
5
|
+
const name = bindingName || "ai";
|
|
6
|
+
const handler = {
|
|
7
|
+
get(target, prop) {
|
|
8
|
+
const value = Reflect.get(target, prop);
|
|
9
|
+
if (prop === "run" && typeof value === "function") {
|
|
10
|
+
return new Proxy(value, {
|
|
11
|
+
apply: (fnTarget, thisArg, args) => {
|
|
12
|
+
const [model] = args;
|
|
13
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
14
|
+
return tracer.startActiveSpan(
|
|
15
|
+
`AI ${name}: run ${model}`,
|
|
16
|
+
{
|
|
17
|
+
kind: SpanKind.CLIENT,
|
|
18
|
+
attributes: {
|
|
19
|
+
"gen_ai.system": "cloudflare-workers-ai",
|
|
20
|
+
"gen_ai.operation.name": "run",
|
|
21
|
+
"gen_ai.request.model": model
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
async (span) => {
|
|
25
|
+
try {
|
|
26
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
27
|
+
if (result?.usage?.prompt_tokens !== void 0) {
|
|
28
|
+
setAttr(span, "gen_ai.usage.input_tokens", Number(result.usage.prompt_tokens));
|
|
29
|
+
}
|
|
30
|
+
if (result?.usage?.completion_tokens !== void 0) {
|
|
31
|
+
setAttr(span, "gen_ai.usage.output_tokens", Number(result.usage.completion_tokens));
|
|
32
|
+
}
|
|
33
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
34
|
+
return result;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
span.recordException(error);
|
|
37
|
+
span.setStatus({
|
|
38
|
+
code: SpanStatusCode.ERROR,
|
|
39
|
+
message: error instanceof Error ? error.message : String(error)
|
|
40
|
+
});
|
|
41
|
+
throw error;
|
|
42
|
+
} finally {
|
|
43
|
+
span.end();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
return wrap(ai, handler);
|
|
54
|
+
}
|
|
55
|
+
var TRACED_METHODS = ["query", "insert", "upsert", "deleteByIds", "getByIds", "describe"];
|
|
56
|
+
function instrumentVectorize(vectorize, indexName) {
|
|
57
|
+
const name = indexName || "vectorize";
|
|
58
|
+
const handler = {
|
|
59
|
+
get(target, prop) {
|
|
60
|
+
const value = Reflect.get(target, prop);
|
|
61
|
+
if (typeof prop === "string" && TRACED_METHODS.includes(prop) && typeof value === "function") {
|
|
62
|
+
return new Proxy(value, {
|
|
63
|
+
apply: (fnTarget, thisArg, args) => {
|
|
64
|
+
const operation = prop;
|
|
65
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
66
|
+
const attributes = {
|
|
67
|
+
"db.system": "cloudflare-vectorize",
|
|
68
|
+
"db.operation": operation,
|
|
69
|
+
"db.collection.name": name
|
|
70
|
+
};
|
|
71
|
+
if (operation === "query") {
|
|
72
|
+
const queryInput = args[0];
|
|
73
|
+
if (queryInput?.topK !== void 0) {
|
|
74
|
+
attributes["db.vectorize.top_k"] = queryInput.topK;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if ((operation === "insert" || operation === "upsert") && Array.isArray(args[0])) {
|
|
78
|
+
attributes["db.vectorize.vectors_count"] = args[0].length;
|
|
79
|
+
}
|
|
80
|
+
return tracer.startActiveSpan(
|
|
81
|
+
`Vectorize ${name}: ${operation}`,
|
|
82
|
+
{
|
|
83
|
+
kind: SpanKind.CLIENT,
|
|
84
|
+
attributes
|
|
85
|
+
},
|
|
86
|
+
async (span) => {
|
|
87
|
+
try {
|
|
88
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
89
|
+
if (operation === "query" && result?.matches) {
|
|
90
|
+
setAttr(span, "db.vectorize.matches_count", result.matches.length);
|
|
91
|
+
}
|
|
92
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
93
|
+
return result;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
span.recordException(error);
|
|
96
|
+
span.setStatus({
|
|
97
|
+
code: SpanStatusCode.ERROR,
|
|
98
|
+
message: error instanceof Error ? error.message : String(error)
|
|
99
|
+
});
|
|
100
|
+
throw error;
|
|
101
|
+
} finally {
|
|
102
|
+
span.end();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
return wrap(vectorize, handler);
|
|
113
|
+
}
|
|
114
|
+
function instrumentHyperdrive(hyperdrive, bindingName) {
|
|
115
|
+
const name = bindingName || "hyperdrive";
|
|
116
|
+
const handler = {
|
|
117
|
+
get(target, prop) {
|
|
118
|
+
const value = Reflect.get(target, prop);
|
|
119
|
+
if (prop === "connect" && typeof value === "function") {
|
|
120
|
+
return new Proxy(value, {
|
|
121
|
+
apply: (fnTarget, thisArg, args) => {
|
|
122
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
123
|
+
const attributes = {
|
|
124
|
+
"db.system": "cloudflare-hyperdrive",
|
|
125
|
+
"db.operation": "connect"
|
|
126
|
+
};
|
|
127
|
+
try {
|
|
128
|
+
setAttr({ setAttribute: (k, v) => {
|
|
129
|
+
if (v !== void 0 && v !== null) attributes[k] = v;
|
|
130
|
+
} }, "server.address", target.host);
|
|
131
|
+
setAttr({ setAttribute: (k, v) => {
|
|
132
|
+
if (v !== void 0 && v !== null) attributes[k] = v;
|
|
133
|
+
} }, "server.port", target.port);
|
|
134
|
+
setAttr({ setAttribute: (k, v) => {
|
|
135
|
+
if (v !== void 0 && v !== null) attributes[k] = v;
|
|
136
|
+
} }, "db.user", target.user);
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
return tracer.startActiveSpan(
|
|
140
|
+
`Hyperdrive ${name}: connect`,
|
|
141
|
+
{
|
|
142
|
+
kind: SpanKind.CLIENT,
|
|
143
|
+
attributes
|
|
144
|
+
},
|
|
145
|
+
async (span) => {
|
|
146
|
+
try {
|
|
147
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
148
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
149
|
+
return result;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
span.recordException(error);
|
|
152
|
+
span.setStatus({
|
|
153
|
+
code: SpanStatusCode.ERROR,
|
|
154
|
+
message: error instanceof Error ? error.message : String(error)
|
|
155
|
+
});
|
|
156
|
+
throw error;
|
|
157
|
+
} finally {
|
|
158
|
+
span.end();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return value;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
return wrap(hyperdrive, handler);
|
|
169
|
+
}
|
|
170
|
+
function instrumentQueueProducer(queue, queueName) {
|
|
171
|
+
const name = queueName || "queue";
|
|
172
|
+
const handler = {
|
|
173
|
+
get(target, prop) {
|
|
174
|
+
const value = Reflect.get(target, prop);
|
|
175
|
+
if (prop === "send" && typeof value === "function") {
|
|
176
|
+
return new Proxy(value, {
|
|
177
|
+
apply: (fnTarget, thisArg, args) => {
|
|
178
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
179
|
+
return tracer.startActiveSpan(
|
|
180
|
+
`Queue ${name}: send`,
|
|
181
|
+
{
|
|
182
|
+
kind: SpanKind.PRODUCER,
|
|
183
|
+
attributes: {
|
|
184
|
+
"messaging.system": "cloudflare-queues",
|
|
185
|
+
"messaging.operation.type": "publish",
|
|
186
|
+
"messaging.operation": "send",
|
|
187
|
+
"messaging.destination.name": name
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
async (span) => {
|
|
191
|
+
try {
|
|
192
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
193
|
+
setAttr(span, "messaging.message.id", result?.messageId);
|
|
194
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
195
|
+
return result;
|
|
196
|
+
} catch (error) {
|
|
197
|
+
span.recordException(error);
|
|
198
|
+
span.setStatus({
|
|
199
|
+
code: SpanStatusCode.ERROR,
|
|
200
|
+
message: error instanceof Error ? error.message : String(error)
|
|
201
|
+
});
|
|
202
|
+
throw error;
|
|
203
|
+
} finally {
|
|
204
|
+
span.end();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (prop === "sendBatch" && typeof value === "function") {
|
|
212
|
+
return new Proxy(value, {
|
|
213
|
+
apply: (fnTarget, thisArg, args) => {
|
|
214
|
+
const [messages] = args;
|
|
215
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
216
|
+
return tracer.startActiveSpan(
|
|
217
|
+
`Queue ${name}: sendBatch`,
|
|
218
|
+
{
|
|
219
|
+
kind: SpanKind.PRODUCER,
|
|
220
|
+
attributes: {
|
|
221
|
+
"messaging.system": "cloudflare-queues",
|
|
222
|
+
"messaging.operation.type": "publish",
|
|
223
|
+
"messaging.operation": "sendBatch",
|
|
224
|
+
"messaging.destination.name": name,
|
|
225
|
+
"messaging.batch.message_count": Array.isArray(messages) ? messages.length : 0
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
async (span) => {
|
|
229
|
+
try {
|
|
230
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
231
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
232
|
+
return result;
|
|
233
|
+
} catch (error) {
|
|
234
|
+
span.recordException(error);
|
|
235
|
+
span.setStatus({
|
|
236
|
+
code: SpanStatusCode.ERROR,
|
|
237
|
+
message: error instanceof Error ? error.message : String(error)
|
|
238
|
+
});
|
|
239
|
+
throw error;
|
|
240
|
+
} finally {
|
|
241
|
+
span.end();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
return value;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
return wrap(queue, handler);
|
|
252
|
+
}
|
|
253
|
+
function instrumentAnalyticsEngine(ae, datasetName) {
|
|
254
|
+
const name = datasetName || "analytics-engine";
|
|
255
|
+
const handler = {
|
|
256
|
+
get(target, prop) {
|
|
257
|
+
const value = Reflect.get(target, prop);
|
|
258
|
+
if (prop === "writeDataPoint" && typeof value === "function") {
|
|
259
|
+
return new Proxy(value, {
|
|
260
|
+
apply: (fnTarget, thisArg, args) => {
|
|
261
|
+
const [dataPoint] = args;
|
|
262
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
263
|
+
const attributes = {
|
|
264
|
+
"analytics.system": "cloudflare-analytics-engine",
|
|
265
|
+
"analytics.operation": "writeDataPoint"
|
|
266
|
+
};
|
|
267
|
+
if (dataPoint) {
|
|
268
|
+
if (dataPoint.indexes) {
|
|
269
|
+
attributes["analytics.indexes_count"] = Array.isArray(dataPoint.indexes) ? dataPoint.indexes.length : 1;
|
|
270
|
+
}
|
|
271
|
+
if (dataPoint.doubles) {
|
|
272
|
+
attributes["analytics.doubles_count"] = dataPoint.doubles.length;
|
|
273
|
+
}
|
|
274
|
+
if (dataPoint.blobs) {
|
|
275
|
+
attributes["analytics.blobs_count"] = dataPoint.blobs.length;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return tracer.startActiveSpan(
|
|
279
|
+
`AnalyticsEngine ${name}: writeDataPoint`,
|
|
280
|
+
{
|
|
281
|
+
kind: SpanKind.CLIENT,
|
|
282
|
+
attributes
|
|
283
|
+
},
|
|
284
|
+
(span) => {
|
|
285
|
+
try {
|
|
286
|
+
Reflect.apply(fnTarget, thisArg, args);
|
|
287
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
288
|
+
} catch (error) {
|
|
289
|
+
span.recordException(error);
|
|
290
|
+
span.setStatus({
|
|
291
|
+
code: SpanStatusCode.ERROR,
|
|
292
|
+
message: error instanceof Error ? error.message : String(error)
|
|
293
|
+
});
|
|
294
|
+
throw error;
|
|
295
|
+
} finally {
|
|
296
|
+
span.end();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
return value;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
return wrap(ae, handler);
|
|
307
|
+
}
|
|
308
|
+
var pipelineMetaSymbol = /* @__PURE__ */ Symbol("images-pipeline-meta");
|
|
309
|
+
function proxyTransformer(transformer, meta, bindingName) {
|
|
310
|
+
const handler = {
|
|
311
|
+
get(target, prop) {
|
|
312
|
+
const value = Reflect.get(target, prop);
|
|
313
|
+
if ((prop === "transform" || prop === "draw") && typeof value === "function") {
|
|
314
|
+
return new Proxy(value, {
|
|
315
|
+
apply: (fnTarget, _thisArg, args) => {
|
|
316
|
+
meta.operationCount++;
|
|
317
|
+
const result = Reflect.apply(fnTarget, target, args);
|
|
318
|
+
if (result === target || result && typeof result === "object" && "output" in result) {
|
|
319
|
+
return proxyTransformer(result, meta, bindingName);
|
|
320
|
+
}
|
|
321
|
+
return result;
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
if (prop === "output" && typeof value === "function") {
|
|
326
|
+
return new Proxy(value, {
|
|
327
|
+
apply: (fnTarget, _thisArg, args) => {
|
|
328
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
329
|
+
const [formatOrOptions] = args;
|
|
330
|
+
const attributes = {
|
|
331
|
+
"images.system": "cloudflare-images",
|
|
332
|
+
"images.pipeline.operation_count": meta.operationCount
|
|
333
|
+
};
|
|
334
|
+
if (typeof formatOrOptions === "string") {
|
|
335
|
+
attributes["images.output.format"] = formatOrOptions;
|
|
336
|
+
} else if (formatOrOptions && typeof formatOrOptions === "object") {
|
|
337
|
+
const fmt = formatOrOptions.format;
|
|
338
|
+
if (fmt) attributes["images.output.format"] = fmt;
|
|
339
|
+
}
|
|
340
|
+
return tracer.startActiveSpan(
|
|
341
|
+
`Images ${bindingName}: output`,
|
|
342
|
+
{
|
|
343
|
+
kind: SpanKind.CLIENT,
|
|
344
|
+
attributes
|
|
345
|
+
},
|
|
346
|
+
async (span) => {
|
|
347
|
+
try {
|
|
348
|
+
const result = await Reflect.apply(fnTarget, target, args);
|
|
349
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
350
|
+
return result;
|
|
351
|
+
} catch (error) {
|
|
352
|
+
span.recordException(error);
|
|
353
|
+
span.setStatus({
|
|
354
|
+
code: SpanStatusCode.ERROR,
|
|
355
|
+
message: error instanceof Error ? error.message : String(error)
|
|
356
|
+
});
|
|
357
|
+
throw error;
|
|
358
|
+
} finally {
|
|
359
|
+
span.end();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
return value;
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
const proxy = new Proxy(transformer, handler);
|
|
370
|
+
Object.defineProperty(proxy, pipelineMetaSymbol, {
|
|
371
|
+
value: meta,
|
|
372
|
+
writable: false,
|
|
373
|
+
enumerable: false,
|
|
374
|
+
configurable: false
|
|
375
|
+
});
|
|
376
|
+
return proxy;
|
|
377
|
+
}
|
|
378
|
+
function instrumentImages(images, bindingName) {
|
|
379
|
+
const name = bindingName || "images";
|
|
380
|
+
const handler = {
|
|
381
|
+
get(target, prop) {
|
|
382
|
+
const value = Reflect.get(target, prop);
|
|
383
|
+
if (prop === "info" && typeof value === "function") {
|
|
384
|
+
return new Proxy(value, {
|
|
385
|
+
apply: (fnTarget, thisArg, args) => {
|
|
386
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
387
|
+
return tracer.startActiveSpan(
|
|
388
|
+
`Images ${name}: info`,
|
|
389
|
+
{
|
|
390
|
+
kind: SpanKind.CLIENT,
|
|
391
|
+
attributes: {
|
|
392
|
+
"images.system": "cloudflare-images",
|
|
393
|
+
"images.operation": "info"
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
async (span) => {
|
|
397
|
+
try {
|
|
398
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
399
|
+
setAttr(span, "images.width", result?.width);
|
|
400
|
+
setAttr(span, "images.height", result?.height);
|
|
401
|
+
setAttr(span, "images.format", result?.format);
|
|
402
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
403
|
+
return result;
|
|
404
|
+
} catch (error) {
|
|
405
|
+
span.recordException(error);
|
|
406
|
+
span.setStatus({
|
|
407
|
+
code: SpanStatusCode.ERROR,
|
|
408
|
+
message: error instanceof Error ? error.message : String(error)
|
|
409
|
+
});
|
|
410
|
+
throw error;
|
|
411
|
+
} finally {
|
|
412
|
+
span.end();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
if (prop === "input" && typeof value === "function") {
|
|
420
|
+
return new Proxy(value, {
|
|
421
|
+
apply: (fnTarget, thisArg, args) => {
|
|
422
|
+
const transformer = Reflect.apply(fnTarget, thisArg, args);
|
|
423
|
+
const meta = { operationCount: 0 };
|
|
424
|
+
return proxyTransformer(transformer, meta, name);
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
return value;
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
return wrap(images, handler);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// src/bindings/bindings.ts
|
|
435
|
+
function instrumentKV(kv, namespaceName) {
|
|
436
|
+
const name = namespaceName || "kv";
|
|
437
|
+
const kvHandler = {
|
|
438
|
+
get(target, prop) {
|
|
439
|
+
const value = Reflect.get(target, prop);
|
|
440
|
+
if (prop === "get" && typeof value === "function") {
|
|
441
|
+
return new Proxy(value, {
|
|
442
|
+
apply: (fnTarget, thisArg, args) => {
|
|
443
|
+
const [key, options] = args;
|
|
444
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
445
|
+
return tracer.startActiveSpan(
|
|
446
|
+
`KV ${name}: get`,
|
|
447
|
+
{
|
|
448
|
+
kind: SpanKind.CLIENT,
|
|
449
|
+
attributes: {
|
|
450
|
+
"db.system": "cloudflare-kv",
|
|
451
|
+
"db.operation": "get",
|
|
452
|
+
"db.namespace": name,
|
|
453
|
+
"db.key": key,
|
|
454
|
+
"db.cache_hit": options?.cacheTtl !== void 0
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
async (span) => {
|
|
458
|
+
try {
|
|
459
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
460
|
+
span.setAttribute("db.result.type", result === null ? "null" : typeof result);
|
|
461
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
462
|
+
return result;
|
|
463
|
+
} catch (error) {
|
|
464
|
+
span.recordException(error);
|
|
465
|
+
span.setStatus({
|
|
466
|
+
code: SpanStatusCode.ERROR,
|
|
467
|
+
message: error instanceof Error ? error.message : String(error)
|
|
468
|
+
});
|
|
469
|
+
throw error;
|
|
470
|
+
} finally {
|
|
471
|
+
span.end();
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
if (prop === "put" && typeof value === "function") {
|
|
479
|
+
return new Proxy(value, {
|
|
480
|
+
apply: (fnTarget, thisArg, args) => {
|
|
481
|
+
const [key] = args;
|
|
482
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
483
|
+
return tracer.startActiveSpan(
|
|
484
|
+
`KV ${name}: put`,
|
|
485
|
+
{
|
|
486
|
+
kind: SpanKind.CLIENT,
|
|
487
|
+
attributes: {
|
|
488
|
+
"db.system": "cloudflare-kv",
|
|
489
|
+
"db.operation": "put",
|
|
490
|
+
"db.namespace": name,
|
|
491
|
+
"db.key": key
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
async (span) => {
|
|
495
|
+
try {
|
|
496
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
497
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
498
|
+
return result;
|
|
499
|
+
} catch (error) {
|
|
500
|
+
span.recordException(error);
|
|
501
|
+
span.setStatus({
|
|
502
|
+
code: SpanStatusCode.ERROR,
|
|
503
|
+
message: error instanceof Error ? error.message : String(error)
|
|
504
|
+
});
|
|
505
|
+
throw error;
|
|
506
|
+
} finally {
|
|
507
|
+
span.end();
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
if (prop === "delete" && typeof value === "function") {
|
|
515
|
+
return new Proxy(value, {
|
|
516
|
+
apply: (fnTarget, thisArg, args) => {
|
|
517
|
+
const [key] = args;
|
|
518
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
519
|
+
return tracer.startActiveSpan(
|
|
520
|
+
`KV ${name}: delete`,
|
|
521
|
+
{
|
|
522
|
+
kind: SpanKind.CLIENT,
|
|
523
|
+
attributes: {
|
|
524
|
+
"db.system": "cloudflare-kv",
|
|
525
|
+
"db.operation": "delete",
|
|
526
|
+
"db.namespace": name,
|
|
527
|
+
"db.key": key
|
|
528
|
+
}
|
|
529
|
+
},
|
|
530
|
+
async (span) => {
|
|
531
|
+
try {
|
|
532
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
533
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
534
|
+
return result;
|
|
535
|
+
} catch (error) {
|
|
536
|
+
span.recordException(error);
|
|
537
|
+
span.setStatus({
|
|
538
|
+
code: SpanStatusCode.ERROR,
|
|
539
|
+
message: error instanceof Error ? error.message : String(error)
|
|
540
|
+
});
|
|
541
|
+
throw error;
|
|
542
|
+
} finally {
|
|
543
|
+
span.end();
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
if (prop === "list" && typeof value === "function") {
|
|
551
|
+
return new Proxy(value, {
|
|
552
|
+
apply: (fnTarget, thisArg, args) => {
|
|
553
|
+
const [options] = args;
|
|
554
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
555
|
+
return tracer.startActiveSpan(
|
|
556
|
+
`KV ${name}: list`,
|
|
557
|
+
{
|
|
558
|
+
kind: SpanKind.CLIENT,
|
|
559
|
+
attributes: {
|
|
560
|
+
"db.system": "cloudflare-kv",
|
|
561
|
+
"db.operation": "list",
|
|
562
|
+
"db.namespace": name,
|
|
563
|
+
"db.prefix": options?.prefix || void 0,
|
|
564
|
+
"db.limit": options?.limit || void 0
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
async (span) => {
|
|
568
|
+
try {
|
|
569
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
570
|
+
span.setAttribute("db.result.keys_count", result.keys.length);
|
|
571
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
572
|
+
return result;
|
|
573
|
+
} catch (error) {
|
|
574
|
+
span.recordException(error);
|
|
575
|
+
span.setStatus({
|
|
576
|
+
code: SpanStatusCode.ERROR,
|
|
577
|
+
message: error instanceof Error ? error.message : String(error)
|
|
578
|
+
});
|
|
579
|
+
throw error;
|
|
580
|
+
} finally {
|
|
581
|
+
span.end();
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
return value;
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
return wrap(kv, kvHandler);
|
|
592
|
+
}
|
|
593
|
+
function instrumentR2(r2, bucketName) {
|
|
594
|
+
const name = bucketName || "r2";
|
|
595
|
+
const r2Handler = {
|
|
596
|
+
get(target, prop) {
|
|
597
|
+
const value = Reflect.get(target, prop);
|
|
598
|
+
if (prop === "get" && typeof value === "function") {
|
|
599
|
+
return new Proxy(value, {
|
|
600
|
+
apply: (fnTarget, thisArg, args) => {
|
|
601
|
+
const [key] = args;
|
|
602
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
603
|
+
return tracer.startActiveSpan(
|
|
604
|
+
`R2 ${name}: get`,
|
|
605
|
+
{
|
|
606
|
+
kind: SpanKind.CLIENT,
|
|
607
|
+
attributes: {
|
|
608
|
+
"db.system": "cloudflare-r2",
|
|
609
|
+
"db.operation": "get",
|
|
610
|
+
"db.bucket": name,
|
|
611
|
+
"db.key": key
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
async (span) => {
|
|
615
|
+
try {
|
|
616
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
617
|
+
if (result) {
|
|
618
|
+
span.setAttribute("db.result.size", result.size);
|
|
619
|
+
span.setAttribute("db.result.etag", result.etag);
|
|
620
|
+
span.setAttribute("db.result.content_type", result.httpMetadata?.contentType);
|
|
621
|
+
} else {
|
|
622
|
+
span.setAttribute("db.result.exists", false);
|
|
623
|
+
}
|
|
624
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
625
|
+
return result;
|
|
626
|
+
} catch (error) {
|
|
627
|
+
span.recordException(error);
|
|
628
|
+
span.setStatus({
|
|
629
|
+
code: SpanStatusCode.ERROR,
|
|
630
|
+
message: error instanceof Error ? error.message : String(error)
|
|
631
|
+
});
|
|
632
|
+
throw error;
|
|
633
|
+
} finally {
|
|
634
|
+
span.end();
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
if (prop === "put" && typeof value === "function") {
|
|
642
|
+
return new Proxy(value, {
|
|
643
|
+
apply: (fnTarget, thisArg, args) => {
|
|
644
|
+
const [key] = args;
|
|
645
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
646
|
+
return tracer.startActiveSpan(
|
|
647
|
+
`R2 ${name}: put`,
|
|
648
|
+
{
|
|
649
|
+
kind: SpanKind.CLIENT,
|
|
650
|
+
attributes: {
|
|
651
|
+
"db.system": "cloudflare-r2",
|
|
652
|
+
"db.operation": "put",
|
|
653
|
+
"db.bucket": name,
|
|
654
|
+
"db.key": key
|
|
655
|
+
}
|
|
656
|
+
},
|
|
657
|
+
async (span) => {
|
|
658
|
+
try {
|
|
659
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
660
|
+
span.setAttribute("db.result.etag", result.etag);
|
|
661
|
+
span.setAttribute("db.result.uploaded", result.uploaded);
|
|
662
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
663
|
+
return result;
|
|
664
|
+
} catch (error) {
|
|
665
|
+
span.recordException(error);
|
|
666
|
+
span.setStatus({
|
|
667
|
+
code: SpanStatusCode.ERROR,
|
|
668
|
+
message: error instanceof Error ? error.message : String(error)
|
|
669
|
+
});
|
|
670
|
+
throw error;
|
|
671
|
+
} finally {
|
|
672
|
+
span.end();
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
if (prop === "delete" && typeof value === "function") {
|
|
680
|
+
return new Proxy(value, {
|
|
681
|
+
apply: (fnTarget, thisArg, args) => {
|
|
682
|
+
const keys = args;
|
|
683
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
684
|
+
return tracer.startActiveSpan(
|
|
685
|
+
`R2 ${name}: delete`,
|
|
686
|
+
{
|
|
687
|
+
kind: SpanKind.CLIENT,
|
|
688
|
+
attributes: {
|
|
689
|
+
"db.system": "cloudflare-r2",
|
|
690
|
+
"db.operation": "delete",
|
|
691
|
+
"db.bucket": name,
|
|
692
|
+
"db.keys_count": keys.length
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
async (span) => {
|
|
696
|
+
try {
|
|
697
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
698
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
699
|
+
return result;
|
|
700
|
+
} catch (error) {
|
|
701
|
+
span.recordException(error);
|
|
702
|
+
span.setStatus({
|
|
703
|
+
code: SpanStatusCode.ERROR,
|
|
704
|
+
message: error instanceof Error ? error.message : String(error)
|
|
705
|
+
});
|
|
706
|
+
throw error;
|
|
707
|
+
} finally {
|
|
708
|
+
span.end();
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
if (prop === "list" && typeof value === "function") {
|
|
716
|
+
return new Proxy(value, {
|
|
717
|
+
apply: (fnTarget, thisArg, args) => {
|
|
718
|
+
const [options] = args;
|
|
719
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
720
|
+
return tracer.startActiveSpan(
|
|
721
|
+
`R2 ${name}: list`,
|
|
722
|
+
{
|
|
723
|
+
kind: SpanKind.CLIENT,
|
|
724
|
+
attributes: {
|
|
725
|
+
"db.system": "cloudflare-r2",
|
|
726
|
+
"db.operation": "list",
|
|
727
|
+
"db.bucket": name,
|
|
728
|
+
"db.prefix": options?.prefix || void 0,
|
|
729
|
+
"db.limit": options?.limit || void 0
|
|
730
|
+
}
|
|
731
|
+
},
|
|
732
|
+
async (span) => {
|
|
733
|
+
try {
|
|
734
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
735
|
+
span.setAttribute("db.result.objects_count", result.objects.length);
|
|
736
|
+
span.setAttribute("db.result.truncated", result.truncated);
|
|
737
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
738
|
+
return result;
|
|
739
|
+
} catch (error) {
|
|
740
|
+
span.recordException(error);
|
|
741
|
+
span.setStatus({
|
|
742
|
+
code: SpanStatusCode.ERROR,
|
|
743
|
+
message: error instanceof Error ? error.message : String(error)
|
|
744
|
+
});
|
|
745
|
+
throw error;
|
|
746
|
+
} finally {
|
|
747
|
+
span.end();
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
return value;
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
return wrap(r2, r2Handler);
|
|
758
|
+
}
|
|
759
|
+
function instrumentD1(d1, databaseName) {
|
|
760
|
+
const name = databaseName || "d1";
|
|
761
|
+
const d1Handler = {
|
|
762
|
+
get(target, prop) {
|
|
763
|
+
const value = Reflect.get(target, prop);
|
|
764
|
+
if (prop === "prepare" && typeof value === "function") {
|
|
765
|
+
return new Proxy(value, {
|
|
766
|
+
apply: (fnTarget, thisArg, args) => {
|
|
767
|
+
const [query] = args;
|
|
768
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
769
|
+
const prepared = Reflect.apply(fnTarget, thisArg, args);
|
|
770
|
+
const preparedHandler = {
|
|
771
|
+
get(target2, prop2) {
|
|
772
|
+
const value2 = Reflect.get(target2, prop2);
|
|
773
|
+
if (prop2 === "first" || prop2 === "run" || prop2 === "all" || prop2 === "raw") {
|
|
774
|
+
return new Proxy(value2, {
|
|
775
|
+
apply: (fnTarget2, thisArg2, args2) => {
|
|
776
|
+
return tracer.startActiveSpan(
|
|
777
|
+
`D1 ${name}: ${prop2}`,
|
|
778
|
+
{
|
|
779
|
+
kind: SpanKind.CLIENT,
|
|
780
|
+
attributes: {
|
|
781
|
+
"db.system": "cloudflare-d1",
|
|
782
|
+
"db.operation": prop2,
|
|
783
|
+
"db.name": name,
|
|
784
|
+
"db.statement": query
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
async (span) => {
|
|
788
|
+
try {
|
|
789
|
+
const result = await Reflect.apply(fnTarget2, thisArg2, args2);
|
|
790
|
+
if (prop2 === "all" && Array.isArray(result)) {
|
|
791
|
+
span.setAttribute("db.result.rows_count", result.length);
|
|
792
|
+
} else if (prop2 === "first" && result) {
|
|
793
|
+
span.setAttribute("db.result.exists", true);
|
|
794
|
+
}
|
|
795
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
796
|
+
return result;
|
|
797
|
+
} catch (error) {
|
|
798
|
+
span.recordException(error);
|
|
799
|
+
span.setStatus({
|
|
800
|
+
code: SpanStatusCode.ERROR,
|
|
801
|
+
message: error instanceof Error ? error.message : String(error)
|
|
802
|
+
});
|
|
803
|
+
throw error;
|
|
804
|
+
} finally {
|
|
805
|
+
span.end();
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
return value2;
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
return wrap(prepared, preparedHandler);
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
if (prop === "exec" && typeof value === "function") {
|
|
820
|
+
return new Proxy(value, {
|
|
821
|
+
apply: (fnTarget, thisArg, args) => {
|
|
822
|
+
const [query] = args;
|
|
823
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
824
|
+
return tracer.startActiveSpan(
|
|
825
|
+
`D1 ${name}: exec`,
|
|
826
|
+
{
|
|
827
|
+
kind: SpanKind.CLIENT,
|
|
828
|
+
attributes: {
|
|
829
|
+
"db.system": "cloudflare-d1",
|
|
830
|
+
"db.operation": "exec",
|
|
831
|
+
"db.name": name,
|
|
832
|
+
"db.statement": query
|
|
833
|
+
}
|
|
834
|
+
},
|
|
835
|
+
async (span) => {
|
|
836
|
+
try {
|
|
837
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
838
|
+
span.setAttribute("db.result.count", result.count);
|
|
839
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
840
|
+
return result;
|
|
841
|
+
} catch (error) {
|
|
842
|
+
span.recordException(error);
|
|
843
|
+
span.setStatus({
|
|
844
|
+
code: SpanStatusCode.ERROR,
|
|
845
|
+
message: error instanceof Error ? error.message : String(error)
|
|
846
|
+
});
|
|
847
|
+
throw error;
|
|
848
|
+
} finally {
|
|
849
|
+
span.end();
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
return value;
|
|
857
|
+
}
|
|
858
|
+
};
|
|
859
|
+
return wrap(d1, d1Handler);
|
|
860
|
+
}
|
|
861
|
+
function instrumentServiceBinding(fetcher, serviceName) {
|
|
862
|
+
const name = serviceName || "service";
|
|
863
|
+
const fetcherHandler = {
|
|
864
|
+
get(target, prop) {
|
|
865
|
+
const value = Reflect.get(target, prop);
|
|
866
|
+
if (prop === "fetch" && typeof value === "function") {
|
|
867
|
+
return new Proxy(value, {
|
|
868
|
+
apply: (fnTarget, thisArg, args) => {
|
|
869
|
+
const [input, init] = args;
|
|
870
|
+
const request = new Request(input, init);
|
|
871
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
872
|
+
return tracer.startActiveSpan(
|
|
873
|
+
`Service ${name}: ${request.method}`,
|
|
874
|
+
{
|
|
875
|
+
kind: SpanKind.CLIENT,
|
|
876
|
+
attributes: {
|
|
877
|
+
"rpc.system": "cloudflare-service-binding",
|
|
878
|
+
"rpc.service": name,
|
|
879
|
+
"http.request.method": request.method,
|
|
880
|
+
"url.full": request.url
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
async (span) => {
|
|
884
|
+
try {
|
|
885
|
+
const response = await Reflect.apply(fnTarget, thisArg, args);
|
|
886
|
+
span.setAttribute("http.response.status_code", response.status);
|
|
887
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
888
|
+
return response;
|
|
889
|
+
} catch (error) {
|
|
890
|
+
span.recordException(error);
|
|
891
|
+
span.setStatus({
|
|
892
|
+
code: SpanStatusCode.ERROR,
|
|
893
|
+
message: error instanceof Error ? error.message : String(error)
|
|
894
|
+
});
|
|
895
|
+
throw error;
|
|
896
|
+
} finally {
|
|
897
|
+
span.end();
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
return value;
|
|
905
|
+
}
|
|
906
|
+
};
|
|
907
|
+
return wrap(fetcher, fetcherHandler);
|
|
908
|
+
}
|
|
909
|
+
var hasMethod = (obj, m) => typeof obj?.[m] === "function";
|
|
910
|
+
var hasExactMethods = (obj, methods) => methods.every((m) => hasMethod(obj, m));
|
|
911
|
+
function instrumentBindings(env) {
|
|
912
|
+
const instrumented = {};
|
|
913
|
+
for (const [key, value] of Object.entries(env)) {
|
|
914
|
+
if (!value || typeof value !== "object") {
|
|
915
|
+
instrumented[key] = value;
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
if (isWrapped(value)) {
|
|
919
|
+
instrumented[key] = value;
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
if (hasExactMethods(value, ["get", "put", "delete", "list", "head"])) {
|
|
923
|
+
instrumented[key] = instrumentR2(value, key);
|
|
924
|
+
continue;
|
|
925
|
+
}
|
|
926
|
+
if (hasExactMethods(value, ["get", "put", "delete", "list"]) && !("head" in value)) {
|
|
927
|
+
instrumented[key] = instrumentKV(value, key);
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
if (hasExactMethods(value, ["prepare", "exec"])) {
|
|
931
|
+
instrumented[key] = instrumentD1(value, key);
|
|
932
|
+
continue;
|
|
933
|
+
}
|
|
934
|
+
if (hasExactMethods(value, ["query", "insert", "upsert", "describe"])) {
|
|
935
|
+
instrumented[key] = instrumentVectorize(value, key);
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
if (hasMethod(value, "run") && ("gateway" in value || "models" in value)) {
|
|
939
|
+
instrumented[key] = instrumentAI(value, key);
|
|
940
|
+
continue;
|
|
941
|
+
}
|
|
942
|
+
if (hasMethod(value, "connect") && "connectionString" in value && "host" in value) {
|
|
943
|
+
instrumented[key] = instrumentHyperdrive(value, key);
|
|
944
|
+
continue;
|
|
945
|
+
}
|
|
946
|
+
if (hasExactMethods(value, ["send", "sendBatch"]) && !("get" in value)) {
|
|
947
|
+
instrumented[key] = instrumentQueueProducer(value, key);
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
950
|
+
if (hasMethod(value, "writeDataPoint")) {
|
|
951
|
+
instrumented[key] = instrumentAnalyticsEngine(value, key);
|
|
952
|
+
continue;
|
|
953
|
+
}
|
|
954
|
+
if (hasExactMethods(value, ["info", "input"])) {
|
|
955
|
+
instrumented[key] = instrumentImages(value, key);
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
if (hasMethod(value, "fetch")) {
|
|
959
|
+
instrumented[key] = instrumentServiceBinding(value, key);
|
|
960
|
+
continue;
|
|
961
|
+
}
|
|
962
|
+
instrumented[key] = value;
|
|
963
|
+
}
|
|
964
|
+
return instrumented;
|
|
965
|
+
}
|
|
966
|
+
function instrumentRateLimiter(limiter, bindingName) {
|
|
967
|
+
const name = bindingName || "rate-limiter";
|
|
968
|
+
const handler = {
|
|
969
|
+
get(target, prop) {
|
|
970
|
+
const value = Reflect.get(target, prop);
|
|
971
|
+
if (prop === "limit" && typeof value === "function") {
|
|
972
|
+
return new Proxy(value, {
|
|
973
|
+
apply: (fnTarget, thisArg, args) => {
|
|
974
|
+
const [options] = args;
|
|
975
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
976
|
+
return tracer.startActiveSpan(
|
|
977
|
+
`RateLimiter ${name}: limit`,
|
|
978
|
+
{
|
|
979
|
+
kind: SpanKind.CLIENT,
|
|
980
|
+
attributes: {
|
|
981
|
+
"rate_limiter.system": "cloudflare-rate-limiter",
|
|
982
|
+
"rate_limiter.key": options?.key
|
|
983
|
+
}
|
|
984
|
+
},
|
|
985
|
+
async (span) => {
|
|
986
|
+
try {
|
|
987
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
988
|
+
setAttr(span, "rate_limiter.success", result?.success);
|
|
989
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
990
|
+
return result;
|
|
991
|
+
} catch (error) {
|
|
992
|
+
span.recordException(error);
|
|
993
|
+
span.setStatus({
|
|
994
|
+
code: SpanStatusCode.ERROR,
|
|
995
|
+
message: error instanceof Error ? error.message : String(error)
|
|
996
|
+
});
|
|
997
|
+
throw error;
|
|
998
|
+
} finally {
|
|
999
|
+
span.end();
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
return value;
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
return wrap(limiter, handler);
|
|
1010
|
+
}
|
|
1011
|
+
function instrumentBrowserRendering(browser, bindingName) {
|
|
1012
|
+
const name = bindingName || "browser";
|
|
1013
|
+
const handler = {
|
|
1014
|
+
get(target, prop) {
|
|
1015
|
+
const value = Reflect.get(target, prop);
|
|
1016
|
+
if (prop === "fetch" && typeof value === "function") {
|
|
1017
|
+
return new Proxy(value, {
|
|
1018
|
+
apply: (fnTarget, thisArg, args) => {
|
|
1019
|
+
const [input] = args;
|
|
1020
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
1021
|
+
const tracer = trace.getTracer("autotel-edge");
|
|
1022
|
+
return tracer.startActiveSpan(
|
|
1023
|
+
`BrowserRendering ${name}: fetch`,
|
|
1024
|
+
{
|
|
1025
|
+
kind: SpanKind.CLIENT,
|
|
1026
|
+
attributes: {
|
|
1027
|
+
"browser.system": "cloudflare-browser-rendering",
|
|
1028
|
+
"url.full": url
|
|
1029
|
+
}
|
|
1030
|
+
},
|
|
1031
|
+
async (span) => {
|
|
1032
|
+
try {
|
|
1033
|
+
const result = await Reflect.apply(fnTarget, thisArg, args);
|
|
1034
|
+
setAttr(span, "http.response.status_code", result?.status);
|
|
1035
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
1036
|
+
return result;
|
|
1037
|
+
} catch (error) {
|
|
1038
|
+
span.recordException(error);
|
|
1039
|
+
span.setStatus({
|
|
1040
|
+
code: SpanStatusCode.ERROR,
|
|
1041
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1042
|
+
});
|
|
1043
|
+
throw error;
|
|
1044
|
+
} finally {
|
|
1045
|
+
span.end();
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
);
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
return value;
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
return wrap(browser, handler);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
export { instrumentAI, instrumentAnalyticsEngine, instrumentBindings, instrumentBrowserRendering, instrumentD1, instrumentHyperdrive, instrumentImages, instrumentKV, instrumentQueueProducer, instrumentR2, instrumentRateLimiter, instrumentServiceBinding, instrumentVectorize };
|
|
1059
|
+
//# sourceMappingURL=chunk-4UG2QCPQ.js.map
|
|
1060
|
+
//# sourceMappingURL=chunk-4UG2QCPQ.js.map
|