autotel-cloudflare 18.2.3 → 18.2.4
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 +2 -2
- package/dist/agents.js +1 -1
- package/dist/{bindings-BK2AmtNc.js → bindings-BrIFnhtD.js} +3 -3
- package/dist/bindings.js +1 -1
- package/dist/{exception-D3xOCdBW.js → exception-C4TsJIS8.js} +1 -1
- package/dist/{execution-logger-6IZS5fEz.js → execution-logger-Cy1nsWtK.js} +1 -1
- package/dist/{handlers-7NFDRZT2.js → handlers-DoD2ZcUM.js} +260 -78
- package/dist/handlers.js +1 -1
- package/dist/index.js +7 -204
- package/dist/logger.js +1 -1
- package/dist/{native-tracing-Dgw_-i8X.js → native-tracing-D0J7JO58.js} +1 -1
- package/dist/native.js +1 -1
- package/dist/{values-BC6rdpGG.js → values-Vce1mLQx.js} +11 -1
- package/package.json +5 -5
package/dist/actors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { o as wrap, t as toException } from "./exception-
|
|
1
|
+
import { _ as readProperty, a as asRecord, c as asString, n as asBoolean, p as member, r as asFunction, u as describeValue } from "./values-Vce1mLQx.js";
|
|
2
|
+
import { o as wrap, t as toException } from "./exception-C4TsJIS8.js";
|
|
3
3
|
import { t as workerTracer } from "./tracer-z8zwRBVS.js";
|
|
4
4
|
import { createInitialiser, setConfig } from "autotel-edge";
|
|
5
5
|
import { SpanKind, SpanStatusCode, context, propagation } from "@opentelemetry/api";
|
package/dist/agents.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as readProperty, c as asString, g as readPath, m as nonEmptyString, o as asScalar, r as asFunction, s as asScalarArray } from "./values-Vce1mLQx.js";
|
|
2
2
|
import { t as workerTracer } from "./tracer-z8zwRBVS.js";
|
|
3
3
|
import { WorkerTracer, WorkerTracerProvider, createInitialiser } from "autotel-edge";
|
|
4
4
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { i as setAttr, n as isWrapped, o as wrap, t as toException } from "./exception-
|
|
1
|
+
import { _ as readProperty, a as asRecord, c as asString, d as hasMethod, f as hasMethods, g as readPath, h as numberAt, i as asNumber, l as boundMethod, n as asBoolean, p as member, r as asFunction, v as trapArgs } from "./values-Vce1mLQx.js";
|
|
2
|
+
import { i as setAttr, n as isWrapped, o as wrap, t as toException } from "./exception-C4TsJIS8.js";
|
|
3
3
|
import { t as workerTracer } from "./tracer-z8zwRBVS.js";
|
|
4
4
|
import { getActiveConfig } from "autotel-edge";
|
|
5
5
|
import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
|
|
@@ -804,7 +804,7 @@ function instrumentServiceBinding(fetcher, serviceName) {
|
|
|
804
804
|
}
|
|
805
805
|
const value = member(target, prop);
|
|
806
806
|
const method = asFunction(value);
|
|
807
|
-
if (method !== void 0) return method
|
|
807
|
+
if (method !== void 0) return boundMethod(method, target);
|
|
808
808
|
return value;
|
|
809
809
|
} });
|
|
810
810
|
}
|
package/dist/bindings.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as instrumentKV, c as instrumentImages, d as instrumentHyperdrive, f as instrumentVectorize, i as instrumentD1, l as instrumentAnalyticsEngine, n as instrumentRateLimiter, o as instrumentR2, p as instrumentAI, r as instrumentBindings, s as instrumentServiceBinding, t as instrumentBrowserRendering, u as instrumentQueueProducer } from "./bindings-
|
|
1
|
+
import { a as instrumentKV, c as instrumentImages, d as instrumentHyperdrive, f as instrumentVectorize, i as instrumentD1, l as instrumentAnalyticsEngine, n as instrumentRateLimiter, o as instrumentR2, p as instrumentAI, r as instrumentBindings, s as instrumentServiceBinding, t as instrumentBrowserRendering, u as instrumentQueueProducer } from "./bindings-BrIFnhtD.js";
|
|
2
2
|
|
|
3
3
|
export { instrumentAI, instrumentAnalyticsEngine, instrumentBindings, instrumentBrowserRendering, instrumentD1, instrumentHyperdrive, instrumentImages, instrumentKV, instrumentQueueProducer, instrumentR2, instrumentRateLimiter, instrumentServiceBinding, instrumentVectorize };
|
|
@@ -1,10 +1,214 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as platformNativeTracer } from "./native-tracing-
|
|
3
|
-
import { o as wrap, t as toException } from "./exception-
|
|
1
|
+
import { l as boundMethod, p as member, r as asFunction, t as applyTrap, v as trapArgs } from "./values-Vce1mLQx.js";
|
|
2
|
+
import { r as platformNativeTracer } from "./native-tracing-D0J7JO58.js";
|
|
3
|
+
import { o as wrap, t as toException } from "./exception-C4TsJIS8.js";
|
|
4
4
|
import { t as workerTracer } from "./tracer-z8zwRBVS.js";
|
|
5
|
-
import { createInitialiser, nativeRecordException, setConfig, withoutNativeTracer } from "autotel-edge";
|
|
5
|
+
import { WorkerTracer, WorkerTracerProvider, createInitialiser, getActiveConfig, nativeRecordException, setConfig, withoutNativeTracer } from "autotel-edge";
|
|
6
6
|
import { SpanKind, SpanStatusCode, context, propagation } from "@opentelemetry/api";
|
|
7
|
+
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
7
8
|
|
|
9
|
+
//#region src/global/cache.ts
|
|
10
|
+
/**
|
|
11
|
+
* Global Cache API instrumentation for Cloudflare Workers
|
|
12
|
+
*
|
|
13
|
+
* Automatically traces cache operations:
|
|
14
|
+
* - cache.match() - Read from cache
|
|
15
|
+
* - cache.put() - Write to cache
|
|
16
|
+
* - cache.delete() - Delete from cache
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Sanitize URL for span attributes (remove query params that might contain sensitive data)
|
|
20
|
+
*/
|
|
21
|
+
function sanitizeURL(url) {
|
|
22
|
+
const u = new URL(url);
|
|
23
|
+
return `${u.protocol}//${u.host}${u.pathname}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Instrument a cache method (match, put, delete)
|
|
27
|
+
*/
|
|
28
|
+
function instrumentCacheMethod(fn, cacheName, operation) {
|
|
29
|
+
return wrap(fn, { async apply(target, thisArg, argArray) {
|
|
30
|
+
const tracer = workerTracer("autotel-edge");
|
|
31
|
+
const firstArg = argArray[0];
|
|
32
|
+
const url = firstArg instanceof Request ? firstArg.url : typeof firstArg === "string" ? firstArg : void 0;
|
|
33
|
+
const spanName = `Cache ${cacheName}.${operation}`;
|
|
34
|
+
return tracer.startActiveSpan(spanName, {
|
|
35
|
+
kind: SpanKind.CLIENT,
|
|
36
|
+
attributes: {
|
|
37
|
+
"cache.name": cacheName,
|
|
38
|
+
"cache.operation": operation,
|
|
39
|
+
"cache.key": url ? sanitizeURL(url) : void 0
|
|
40
|
+
}
|
|
41
|
+
}, async (span) => {
|
|
42
|
+
try {
|
|
43
|
+
const result = await target.apply(thisArg, argArray);
|
|
44
|
+
if (operation === "match") span.setAttribute("cache.hit", !!result);
|
|
45
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
46
|
+
return result;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
span.recordException(toException(error));
|
|
49
|
+
span.setStatus({
|
|
50
|
+
code: SpanStatusCode.ERROR,
|
|
51
|
+
message: error instanceof Error ? error.message : String(error)
|
|
52
|
+
});
|
|
53
|
+
throw error;
|
|
54
|
+
} finally {
|
|
55
|
+
span.end();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
} });
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Instrument a Cache instance
|
|
62
|
+
*/
|
|
63
|
+
function instrumentCache(cache, cacheName) {
|
|
64
|
+
return wrap(cache, { get(target, prop) {
|
|
65
|
+
const value = member(target, prop);
|
|
66
|
+
const method = asFunction(value);
|
|
67
|
+
if ((prop === "match" || prop === "put" || prop === "delete") && method !== void 0) return instrumentCacheMethod(method.bind(target), cacheName, prop);
|
|
68
|
+
if (method !== void 0) return method.bind(target);
|
|
69
|
+
return value;
|
|
70
|
+
} });
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Instrument caches.open()
|
|
74
|
+
*/
|
|
75
|
+
function instrumentCachesOpen(openFn) {
|
|
76
|
+
return wrap(openFn, { async apply(target, thisArg, argArray) {
|
|
77
|
+
const cacheName = argArray[0];
|
|
78
|
+
return instrumentCache(await applyTrap(target, thisArg, argArray), cacheName);
|
|
79
|
+
} });
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Instrument the global caches API
|
|
83
|
+
*
|
|
84
|
+
* This wraps globalThis.caches to automatically create spans for all cache operations.
|
|
85
|
+
*
|
|
86
|
+
* **Note:** This is called automatically when the library is initialized with
|
|
87
|
+
* `instrumentation.instrumentGlobalCache: true` (default).
|
|
88
|
+
*/
|
|
89
|
+
function instrumentGlobalCache() {
|
|
90
|
+
globalThis.caches = wrap(caches, { get(target, prop) {
|
|
91
|
+
if (prop === "default") return instrumentCache(target.default, "default");
|
|
92
|
+
else if (prop === "open") {
|
|
93
|
+
const openFn = member(target, prop);
|
|
94
|
+
if (typeof openFn === "function") return instrumentCachesOpen(openFn.bind(target));
|
|
95
|
+
}
|
|
96
|
+
return member(target, prop);
|
|
97
|
+
} });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/global/fetch.ts
|
|
102
|
+
/**
|
|
103
|
+
* Global fetch() instrumentation for autotel-edge
|
|
104
|
+
*
|
|
105
|
+
* Automatically traces all outgoing fetch() calls with:
|
|
106
|
+
* - HTTP method, URL, status code
|
|
107
|
+
* - Request/response headers
|
|
108
|
+
* - Automatic context propagation
|
|
109
|
+
* - Error tracking
|
|
110
|
+
*/
|
|
111
|
+
/**
|
|
112
|
+
* Gather HTTP request attributes following OpenTelemetry semantic conventions
|
|
113
|
+
*/
|
|
114
|
+
function gatherRequestAttributes(request) {
|
|
115
|
+
const url = new URL(request.url);
|
|
116
|
+
const redactQuery = getActiveConfig()?.dataSafety?.redactQueryParams === true;
|
|
117
|
+
return {
|
|
118
|
+
"http.request.method": request.method.toUpperCase(),
|
|
119
|
+
"url.full": redactQuery ? `${url.origin}${url.pathname}` : request.url,
|
|
120
|
+
"url.scheme": url.protocol.replace(":", ""),
|
|
121
|
+
"server.address": url.host,
|
|
122
|
+
"url.path": url.pathname,
|
|
123
|
+
"url.query": redactQuery ? url.search ? "[REDACTED]" : "" : url.search,
|
|
124
|
+
"network.protocol.name": "http",
|
|
125
|
+
"user_agent.original": request.headers.get("user-agent") || void 0
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Gather HTTP response attributes
|
|
130
|
+
*/
|
|
131
|
+
function gatherResponseAttributes(response) {
|
|
132
|
+
return {
|
|
133
|
+
"http.response.status_code": response.status,
|
|
134
|
+
"http.response.body.size": response.headers.get("content-length") || void 0
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Instrument the global fetch function
|
|
139
|
+
*
|
|
140
|
+
* This wraps globalThis.fetch to automatically create spans for all outgoing HTTP requests.
|
|
141
|
+
*
|
|
142
|
+
* **Note:** This is called automatically when the library is initialized with
|
|
143
|
+
* `instrumentation.instrumentGlobalFetch: true` (default).
|
|
144
|
+
*/
|
|
145
|
+
function instrumentGlobalFetch() {
|
|
146
|
+
const originalFetch = globalThis.fetch;
|
|
147
|
+
globalThis.fetch = function fetch(input, init) {
|
|
148
|
+
const request = new Request(input, init);
|
|
149
|
+
if (!request.url.startsWith("http")) return originalFetch(input, init);
|
|
150
|
+
const config = getActiveConfig();
|
|
151
|
+
if (!config) return originalFetch(input, init);
|
|
152
|
+
const tracer = workerTracer("autotel-edge");
|
|
153
|
+
const url = new URL(request.url);
|
|
154
|
+
const spanName = `${request.method} ${url.host}`;
|
|
155
|
+
return tracer.startActiveSpan(spanName, {
|
|
156
|
+
kind: SpanKind.CLIENT,
|
|
157
|
+
attributes: gatherRequestAttributes(request)
|
|
158
|
+
}, async (span) => {
|
|
159
|
+
try {
|
|
160
|
+
if (typeof config.fetch?.includeTraceContext === "function" ? config.fetch.includeTraceContext(request) : config.fetch?.includeTraceContext ?? true) propagation.inject(context.active(), request.headers, { set: (headers, key, value) => {
|
|
161
|
+
if (typeof value === "string") headers.set(key, value);
|
|
162
|
+
} });
|
|
163
|
+
const response = await originalFetch(request);
|
|
164
|
+
span.setAttributes(gatherResponseAttributes(response));
|
|
165
|
+
if (response.ok) span.setStatus({ code: SpanStatusCode.OK });
|
|
166
|
+
else span.setStatus({ code: SpanStatusCode.ERROR });
|
|
167
|
+
return response;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
span.recordException(toException(error));
|
|
170
|
+
span.setStatus({
|
|
171
|
+
code: SpanStatusCode.ERROR,
|
|
172
|
+
message: error instanceof Error ? error.message : String(error)
|
|
173
|
+
});
|
|
174
|
+
throw error;
|
|
175
|
+
} finally {
|
|
176
|
+
span.end();
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region src/provider.ts
|
|
184
|
+
/**
|
|
185
|
+
* The OTLP-mode tracer provider, registered once per isolate by whichever
|
|
186
|
+
* wrapper runs first: a Worker handler, or a Workflow.
|
|
187
|
+
*/
|
|
188
|
+
let providerInitialized = false;
|
|
189
|
+
/**
|
|
190
|
+
* Initialize the tracer provider
|
|
191
|
+
*/
|
|
192
|
+
function initProvider(config) {
|
|
193
|
+
if (providerInitialized) return;
|
|
194
|
+
if (config.instrumentation.instrumentGlobalFetch) instrumentGlobalFetch();
|
|
195
|
+
if (config.instrumentation.instrumentGlobalCache) instrumentGlobalCache();
|
|
196
|
+
propagation.setGlobalPropagator(config.propagator);
|
|
197
|
+
const resource = resourceFromAttributes({
|
|
198
|
+
"service.name": config.service.name,
|
|
199
|
+
"service.version": config.service.version,
|
|
200
|
+
"service.namespace": config.service.namespace,
|
|
201
|
+
"cloud.provider": "cloudflare",
|
|
202
|
+
"cloud.platform": "cloudflare.workers",
|
|
203
|
+
"telemetry.sdk.name": "autotel-edge",
|
|
204
|
+
"telemetry.sdk.language": "js"
|
|
205
|
+
});
|
|
206
|
+
new WorkerTracerProvider(config.spanProcessors, resource).register();
|
|
207
|
+
workerTracer("autotel-edge").setHeadSampler(config.sampling.headSampler);
|
|
208
|
+
providerInitialized = true;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
//#endregion
|
|
8
212
|
//#region src/handlers/durable-objects.ts
|
|
9
213
|
/**
|
|
10
214
|
* Durable Objects instrumentation for Cloudflare Workers
|
|
@@ -237,93 +441,69 @@ function isColdStart(workflowClass) {
|
|
|
237
441
|
return false;
|
|
238
442
|
}
|
|
239
443
|
/**
|
|
240
|
-
*
|
|
444
|
+
* Instrument a Workflow step: a span around each do(), sleep() and
|
|
445
|
+
* sleepUntil(). In workerd `step` is an RPC stub, so every call goes through
|
|
446
|
+
* boundMethod rather than the stub's own apply or bind.
|
|
241
447
|
*/
|
|
242
448
|
function instrumentWorkflowStep(step, workflowName) {
|
|
449
|
+
const traced = (call, describe) => (...args) => {
|
|
450
|
+
const { name, attributes } = describe(args);
|
|
451
|
+
return workerTracer("autotel-edge").startActiveSpan(`Workflow ${workflowName}: ${name}`, {
|
|
452
|
+
kind: SpanKind.INTERNAL,
|
|
453
|
+
attributes: {
|
|
454
|
+
...attributes,
|
|
455
|
+
"workflow.name": workflowName
|
|
456
|
+
}
|
|
457
|
+
}, async (span) => {
|
|
458
|
+
try {
|
|
459
|
+
const result = await call(...args);
|
|
460
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
461
|
+
return result;
|
|
462
|
+
} catch (error) {
|
|
463
|
+
span.recordException(toException(error));
|
|
464
|
+
span.setStatus({
|
|
465
|
+
code: SpanStatusCode.ERROR,
|
|
466
|
+
message: error instanceof Error ? error.message : String(error)
|
|
467
|
+
});
|
|
468
|
+
throw error;
|
|
469
|
+
} finally {
|
|
470
|
+
span.end();
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
};
|
|
243
474
|
return wrap(step, { get(target, prop) {
|
|
244
475
|
const value = member(target, prop);
|
|
245
476
|
const method = asFunction(value);
|
|
246
|
-
if (
|
|
477
|
+
if (!method) return value;
|
|
478
|
+
const call = boundMethod(method, target);
|
|
479
|
+
if (prop === "do") return traced(call, (args) => {
|
|
247
480
|
const [stepName] = trapArgs(args);
|
|
248
|
-
return
|
|
249
|
-
|
|
250
|
-
attributes: {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}, async (span) => {
|
|
255
|
-
try {
|
|
256
|
-
const result = await fnTarget.apply(thisArg, args);
|
|
257
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
258
|
-
return result;
|
|
259
|
-
} catch (error) {
|
|
260
|
-
span.recordException(toException(error));
|
|
261
|
-
span.setStatus({
|
|
262
|
-
code: SpanStatusCode.ERROR,
|
|
263
|
-
message: error instanceof Error ? error.message : String(error)
|
|
264
|
-
});
|
|
265
|
-
throw error;
|
|
266
|
-
} finally {
|
|
267
|
-
span.end();
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
} });
|
|
271
|
-
if (prop === "sleep" && method) return new Proxy(method, { apply: (fnTarget, thisArg, args) => {
|
|
481
|
+
return {
|
|
482
|
+
name: stepName,
|
|
483
|
+
attributes: { "workflow.step.name": stepName }
|
|
484
|
+
};
|
|
485
|
+
});
|
|
486
|
+
if (prop === "sleep") return traced(call, (args) => {
|
|
272
487
|
const [sleepName, duration] = trapArgs(args);
|
|
273
|
-
return
|
|
274
|
-
|
|
488
|
+
return {
|
|
489
|
+
name: `sleep ${sleepName}`,
|
|
275
490
|
attributes: {
|
|
276
491
|
"workflow.sleep.name": sleepName,
|
|
277
|
-
"workflow.sleep.duration": String(duration)
|
|
278
|
-
"workflow.name": workflowName
|
|
279
|
-
}
|
|
280
|
-
}, async (span) => {
|
|
281
|
-
try {
|
|
282
|
-
const result = await fnTarget.apply(thisArg, args);
|
|
283
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
284
|
-
return result;
|
|
285
|
-
} catch (error) {
|
|
286
|
-
span.recordException(toException(error));
|
|
287
|
-
span.setStatus({
|
|
288
|
-
code: SpanStatusCode.ERROR,
|
|
289
|
-
message: error instanceof Error ? error.message : String(error)
|
|
290
|
-
});
|
|
291
|
-
throw error;
|
|
292
|
-
} finally {
|
|
293
|
-
span.end();
|
|
492
|
+
"workflow.sleep.duration": String(duration)
|
|
294
493
|
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (prop === "sleepUntil"
|
|
494
|
+
};
|
|
495
|
+
});
|
|
496
|
+
if (prop === "sleepUntil") return traced(call, (args) => {
|
|
298
497
|
const [sleepName, timestamp] = trapArgs(args);
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
return tracer.startActiveSpan(`Workflow ${workflowName}: sleepUntil ${sleepName}`, {
|
|
302
|
-
kind: SpanKind.INTERNAL,
|
|
498
|
+
return {
|
|
499
|
+
name: `sleepUntil ${sleepName}`,
|
|
303
500
|
attributes: {
|
|
304
501
|
"workflow.sleep.name": sleepName,
|
|
305
|
-
"workflow.sleep.until":
|
|
306
|
-
"workflow.name": workflowName
|
|
502
|
+
"workflow.sleep.until": new Date(timestamp).toISOString()
|
|
307
503
|
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
312
|
-
return result;
|
|
313
|
-
} catch (error) {
|
|
314
|
-
span.recordException(toException(error));
|
|
315
|
-
span.setStatus({
|
|
316
|
-
code: SpanStatusCode.ERROR,
|
|
317
|
-
message: error instanceof Error ? error.message : String(error)
|
|
318
|
-
});
|
|
319
|
-
throw error;
|
|
320
|
-
} finally {
|
|
321
|
-
span.end();
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
} });
|
|
325
|
-
if (method !== void 0) return method.bind(target);
|
|
326
|
-
return value;
|
|
504
|
+
};
|
|
505
|
+
});
|
|
506
|
+
return call;
|
|
327
507
|
} });
|
|
328
508
|
}
|
|
329
509
|
/**
|
|
@@ -356,6 +536,7 @@ function instrumentWorkflowRun(runFn, workflowName, workflowClass) {
|
|
|
356
536
|
throw error;
|
|
357
537
|
} finally {
|
|
358
538
|
span.end();
|
|
539
|
+
if (tracer instanceof WorkerTracer) await tracer.forceFlush(span.spanContext().traceId).catch((error) => console.error("[autotel-cloudflare] Failed to export spans:", error));
|
|
359
540
|
}
|
|
360
541
|
});
|
|
361
542
|
};
|
|
@@ -453,9 +634,10 @@ function instrumentWorkflow(workflowClass, workflowName, config) {
|
|
|
453
634
|
return new target(...args);
|
|
454
635
|
});
|
|
455
636
|
if (platformNativeTracer && workflowConfig.nativeTracing !== "off") return nativeWorkflowInstance(workflowInstance, workflowName, platformNativeTracer);
|
|
637
|
+
initProvider(workflowConfig);
|
|
456
638
|
return instrumentWorkflowInstance(workflowInstance, workflowName, workflowClass);
|
|
457
639
|
} });
|
|
458
640
|
}
|
|
459
641
|
|
|
460
642
|
//#endregion
|
|
461
|
-
export { RUNAWAY_ALARM_EXCEPTION as n, instrumentDO as r, instrumentWorkflow as t };
|
|
643
|
+
export { instrumentGlobalFetch as a, initProvider as i, RUNAWAY_ALARM_EXCEPTION as n, instrumentGlobalCache as o, instrumentDO as r, instrumentWorkflow as t };
|
package/dist/handlers.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as RUNAWAY_ALARM_EXCEPTION, r as instrumentDO, t as instrumentWorkflow } from "./handlers-
|
|
1
|
+
import { n as RUNAWAY_ALARM_EXCEPTION, r as instrumentDO, t as instrumentWorkflow } from "./handlers-DoD2ZcUM.js";
|
|
2
2
|
|
|
3
3
|
export { RUNAWAY_ALARM_EXCEPTION, instrumentDO, instrumentWorkflow };
|
package/dist/index.js
CHANGED
|
@@ -1,190 +1,15 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { a as getWorkflowLogger, i as getRequestLogger, n as getActorLogger, r as getQueueLogger, t as createWorkersLogger } from "./execution-logger-
|
|
3
|
-
import { n as isNativeTracingAvailable, t as getNativeTracerFromCtx } from "./native-tracing-
|
|
4
|
-
import { a as unwrap, o as wrap, r as proxyExecutionContext, t as toException } from "./exception-
|
|
1
|
+
import { _ as readProperty, a as asRecord, c as asString, i as asNumber, n as asBoolean, p as member, r as asFunction, t as applyTrap, v as trapArgs } from "./values-Vce1mLQx.js";
|
|
2
|
+
import { a as getWorkflowLogger, i as getRequestLogger, n as getActorLogger, r as getQueueLogger, t as createWorkersLogger } from "./execution-logger-Cy1nsWtK.js";
|
|
3
|
+
import { n as isNativeTracingAvailable, t as getNativeTracerFromCtx } from "./native-tracing-D0J7JO58.js";
|
|
4
|
+
import { a as unwrap, o as wrap, r as proxyExecutionContext, t as toException } from "./exception-C4TsJIS8.js";
|
|
5
5
|
import { t as workerTracer } from "./tracer-z8zwRBVS.js";
|
|
6
|
-
import { a as instrumentKV, c as instrumentImages, d as instrumentHyperdrive, f as instrumentVectorize, i as instrumentD1, l as instrumentAnalyticsEngine, n as instrumentRateLimiter, o as instrumentR2, p as instrumentAI, r as instrumentBindings, s as instrumentServiceBinding, t as instrumentBrowserRendering, u as instrumentQueueProducer } from "./bindings-
|
|
7
|
-
import { n as RUNAWAY_ALARM_EXCEPTION, r as instrumentDO, t as instrumentWorkflow } from "./handlers-
|
|
8
|
-
import { WorkerTracer,
|
|
6
|
+
import { a as instrumentKV, c as instrumentImages, d as instrumentHyperdrive, f as instrumentVectorize, i as instrumentD1, l as instrumentAnalyticsEngine, n as instrumentRateLimiter, o as instrumentR2, p as instrumentAI, r as instrumentBindings, s as instrumentServiceBinding, t as instrumentBrowserRendering, u as instrumentQueueProducer } from "./bindings-BrIFnhtD.js";
|
|
7
|
+
import { a as instrumentGlobalFetch, i as initProvider, n as RUNAWAY_ALARM_EXCEPTION, o as instrumentGlobalCache, r as instrumentDO, t as instrumentWorkflow } from "./handlers-DoD2ZcUM.js";
|
|
8
|
+
import { WorkerTracer, createInitialiser, createNativeTraceContext, ensureGlobalContextManager, getActiveConfig, getServiceForPath, runWithNativeTraceContext, setConfig, shouldInstrumentPath, withNativeTracer, withoutNativeTracer } from "autotel-edge";
|
|
9
9
|
import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
|
|
10
|
-
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
11
10
|
|
|
12
11
|
export * from "autotel-edge"
|
|
13
12
|
|
|
14
|
-
//#region src/global/fetch.ts
|
|
15
|
-
/**
|
|
16
|
-
* Global fetch() instrumentation for autotel-edge
|
|
17
|
-
*
|
|
18
|
-
* Automatically traces all outgoing fetch() calls with:
|
|
19
|
-
* - HTTP method, URL, status code
|
|
20
|
-
* - Request/response headers
|
|
21
|
-
* - Automatic context propagation
|
|
22
|
-
* - Error tracking
|
|
23
|
-
*/
|
|
24
|
-
/**
|
|
25
|
-
* Gather HTTP request attributes following OpenTelemetry semantic conventions
|
|
26
|
-
*/
|
|
27
|
-
function gatherRequestAttributes(request) {
|
|
28
|
-
const url = new URL(request.url);
|
|
29
|
-
const redactQuery = getActiveConfig()?.dataSafety?.redactQueryParams === true;
|
|
30
|
-
return {
|
|
31
|
-
"http.request.method": request.method.toUpperCase(),
|
|
32
|
-
"url.full": redactQuery ? `${url.origin}${url.pathname}` : request.url,
|
|
33
|
-
"url.scheme": url.protocol.replace(":", ""),
|
|
34
|
-
"server.address": url.host,
|
|
35
|
-
"url.path": url.pathname,
|
|
36
|
-
"url.query": redactQuery ? url.search ? "[REDACTED]" : "" : url.search,
|
|
37
|
-
"network.protocol.name": "http",
|
|
38
|
-
"user_agent.original": request.headers.get("user-agent") || void 0
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Gather HTTP response attributes
|
|
43
|
-
*/
|
|
44
|
-
function gatherResponseAttributes(response) {
|
|
45
|
-
return {
|
|
46
|
-
"http.response.status_code": response.status,
|
|
47
|
-
"http.response.body.size": response.headers.get("content-length") || void 0
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Instrument the global fetch function
|
|
52
|
-
*
|
|
53
|
-
* This wraps globalThis.fetch to automatically create spans for all outgoing HTTP requests.
|
|
54
|
-
*
|
|
55
|
-
* **Note:** This is called automatically when the library is initialized with
|
|
56
|
-
* `instrumentation.instrumentGlobalFetch: true` (default).
|
|
57
|
-
*/
|
|
58
|
-
function instrumentGlobalFetch() {
|
|
59
|
-
const originalFetch = globalThis.fetch;
|
|
60
|
-
globalThis.fetch = function fetch(input, init) {
|
|
61
|
-
const request = new Request(input, init);
|
|
62
|
-
if (!request.url.startsWith("http")) return originalFetch(input, init);
|
|
63
|
-
const config = getActiveConfig();
|
|
64
|
-
if (!config) return originalFetch(input, init);
|
|
65
|
-
const tracer = workerTracer("autotel-edge");
|
|
66
|
-
const url = new URL(request.url);
|
|
67
|
-
const spanName = `${request.method} ${url.host}`;
|
|
68
|
-
return tracer.startActiveSpan(spanName, {
|
|
69
|
-
kind: SpanKind.CLIENT,
|
|
70
|
-
attributes: gatherRequestAttributes(request)
|
|
71
|
-
}, async (span) => {
|
|
72
|
-
try {
|
|
73
|
-
if (typeof config.fetch?.includeTraceContext === "function" ? config.fetch.includeTraceContext(request) : config.fetch?.includeTraceContext ?? true) propagation.inject(context.active(), request.headers, { set: (headers, key, value) => {
|
|
74
|
-
if (typeof value === "string") headers.set(key, value);
|
|
75
|
-
} });
|
|
76
|
-
const response = await originalFetch(request);
|
|
77
|
-
span.setAttributes(gatherResponseAttributes(response));
|
|
78
|
-
if (response.ok) span.setStatus({ code: SpanStatusCode.OK });
|
|
79
|
-
else span.setStatus({ code: SpanStatusCode.ERROR });
|
|
80
|
-
return response;
|
|
81
|
-
} catch (error) {
|
|
82
|
-
span.recordException(toException(error));
|
|
83
|
-
span.setStatus({
|
|
84
|
-
code: SpanStatusCode.ERROR,
|
|
85
|
-
message: error instanceof Error ? error.message : String(error)
|
|
86
|
-
});
|
|
87
|
-
throw error;
|
|
88
|
-
} finally {
|
|
89
|
-
span.end();
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
//#endregion
|
|
96
|
-
//#region src/global/cache.ts
|
|
97
|
-
/**
|
|
98
|
-
* Global Cache API instrumentation for Cloudflare Workers
|
|
99
|
-
*
|
|
100
|
-
* Automatically traces cache operations:
|
|
101
|
-
* - cache.match() - Read from cache
|
|
102
|
-
* - cache.put() - Write to cache
|
|
103
|
-
* - cache.delete() - Delete from cache
|
|
104
|
-
*/
|
|
105
|
-
/**
|
|
106
|
-
* Sanitize URL for span attributes (remove query params that might contain sensitive data)
|
|
107
|
-
*/
|
|
108
|
-
function sanitizeURL(url) {
|
|
109
|
-
const u = new URL(url);
|
|
110
|
-
return `${u.protocol}//${u.host}${u.pathname}`;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Instrument a cache method (match, put, delete)
|
|
114
|
-
*/
|
|
115
|
-
function instrumentCacheMethod(fn, cacheName, operation) {
|
|
116
|
-
return wrap(fn, { async apply(target, thisArg, argArray) {
|
|
117
|
-
const tracer = workerTracer("autotel-edge");
|
|
118
|
-
const firstArg = argArray[0];
|
|
119
|
-
const url = firstArg instanceof Request ? firstArg.url : typeof firstArg === "string" ? firstArg : void 0;
|
|
120
|
-
const spanName = `Cache ${cacheName}.${operation}`;
|
|
121
|
-
return tracer.startActiveSpan(spanName, {
|
|
122
|
-
kind: SpanKind.CLIENT,
|
|
123
|
-
attributes: {
|
|
124
|
-
"cache.name": cacheName,
|
|
125
|
-
"cache.operation": operation,
|
|
126
|
-
"cache.key": url ? sanitizeURL(url) : void 0
|
|
127
|
-
}
|
|
128
|
-
}, async (span) => {
|
|
129
|
-
try {
|
|
130
|
-
const result = await target.apply(thisArg, argArray);
|
|
131
|
-
if (operation === "match") span.setAttribute("cache.hit", !!result);
|
|
132
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
133
|
-
return result;
|
|
134
|
-
} catch (error) {
|
|
135
|
-
span.recordException(toException(error));
|
|
136
|
-
span.setStatus({
|
|
137
|
-
code: SpanStatusCode.ERROR,
|
|
138
|
-
message: error instanceof Error ? error.message : String(error)
|
|
139
|
-
});
|
|
140
|
-
throw error;
|
|
141
|
-
} finally {
|
|
142
|
-
span.end();
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
} });
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Instrument a Cache instance
|
|
149
|
-
*/
|
|
150
|
-
function instrumentCache(cache, cacheName) {
|
|
151
|
-
return wrap(cache, { get(target, prop) {
|
|
152
|
-
const value = member(target, prop);
|
|
153
|
-
const method = asFunction(value);
|
|
154
|
-
if ((prop === "match" || prop === "put" || prop === "delete") && method !== void 0) return instrumentCacheMethod(method.bind(target), cacheName, prop);
|
|
155
|
-
if (method !== void 0) return method.bind(target);
|
|
156
|
-
return value;
|
|
157
|
-
} });
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Instrument caches.open()
|
|
161
|
-
*/
|
|
162
|
-
function instrumentCachesOpen(openFn) {
|
|
163
|
-
return wrap(openFn, { async apply(target, thisArg, argArray) {
|
|
164
|
-
const cacheName = argArray[0];
|
|
165
|
-
return instrumentCache(await applyTrap(target, thisArg, argArray), cacheName);
|
|
166
|
-
} });
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Instrument the global caches API
|
|
170
|
-
*
|
|
171
|
-
* This wraps globalThis.caches to automatically create spans for all cache operations.
|
|
172
|
-
*
|
|
173
|
-
* **Note:** This is called automatically when the library is initialized with
|
|
174
|
-
* `instrumentation.instrumentGlobalCache: true` (default).
|
|
175
|
-
*/
|
|
176
|
-
function instrumentGlobalCache() {
|
|
177
|
-
globalThis.caches = wrap(caches, { get(target, prop) {
|
|
178
|
-
if (prop === "default") return instrumentCache(target.default, "default");
|
|
179
|
-
else if (prop === "open") {
|
|
180
|
-
const openFn = member(target, prop);
|
|
181
|
-
if (typeof openFn === "function") return instrumentCachesOpen(openFn.bind(target));
|
|
182
|
-
}
|
|
183
|
-
return member(target, prop);
|
|
184
|
-
} });
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
//#endregion
|
|
188
13
|
//#region src/wrappers/instrument.ts
|
|
189
14
|
/**
|
|
190
15
|
* Handler instrumentation for Cloudflare Workers
|
|
@@ -608,30 +433,8 @@ function createHandlerProxyWithConfig(_handler, handlerFn, initialiser, createIn
|
|
|
608
433
|
});
|
|
609
434
|
};
|
|
610
435
|
}
|
|
611
|
-
let providerInitialized = false;
|
|
612
436
|
let coldStart = true;
|
|
613
437
|
/**
|
|
614
|
-
* Initialize the tracer provider
|
|
615
|
-
*/
|
|
616
|
-
function initProvider(config) {
|
|
617
|
-
if (providerInitialized) return;
|
|
618
|
-
if (config.instrumentation.instrumentGlobalFetch) instrumentGlobalFetch();
|
|
619
|
-
if (config.instrumentation.instrumentGlobalCache) instrumentGlobalCache();
|
|
620
|
-
propagation.setGlobalPropagator(config.propagator);
|
|
621
|
-
const resource = resourceFromAttributes({
|
|
622
|
-
"service.name": config.service.name,
|
|
623
|
-
"service.version": config.service.version,
|
|
624
|
-
"service.namespace": config.service.namespace,
|
|
625
|
-
"cloud.provider": "cloudflare",
|
|
626
|
-
"cloud.platform": "cloudflare.workers",
|
|
627
|
-
"telemetry.sdk.name": "autotel-edge",
|
|
628
|
-
"telemetry.sdk.language": "js"
|
|
629
|
-
});
|
|
630
|
-
new WorkerTracerProvider(config.spanProcessors, resource).register();
|
|
631
|
-
workerTracer("autotel-edge").setHeadSampler(config.sampling.headSampler);
|
|
632
|
-
providerInitialized = true;
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
438
|
* Instrument a Cloudflare Workers handler
|
|
636
439
|
*
|
|
637
440
|
* @example
|
package/dist/logger.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as getWorkflowLogger, i as getRequestLogger, n as getActorLogger, r as getQueueLogger } from "./execution-logger-
|
|
1
|
+
import { a as getWorkflowLogger, i as getRequestLogger, n as getActorLogger, r as getQueueLogger } from "./execution-logger-Cy1nsWtK.js";
|
|
2
2
|
|
|
3
3
|
export * from "autotel-edge/logger"
|
|
4
4
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WorkerTracerProvider, setDefaultNativeTracer } from "autotel-edge";
|
|
2
|
-
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
3
2
|
import { tracing } from "cloudflare:workers";
|
|
3
|
+
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
4
4
|
|
|
5
5
|
//#region src/native/native-tracing.ts
|
|
6
6
|
/**
|
package/dist/native.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as isNativeTracingAvailable, t as getNativeTracerFromCtx } from "./native-tracing-
|
|
1
|
+
import { n as isNativeTracingAvailable, t as getNativeTracerFromCtx } from "./native-tracing-D0J7JO58.js";
|
|
2
2
|
|
|
3
3
|
export { getNativeTracerFromCtx, isNativeTracingAvailable };
|
|
@@ -29,6 +29,16 @@ function asFunction(value) {
|
|
|
29
29
|
if (typeof value !== "function") return void 0;
|
|
30
30
|
return value;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* A method as a plain function that calls it on `target`.
|
|
34
|
+
*
|
|
35
|
+
* Uses Reflect.apply, which works on RPC stubs such as a Workflow's `step`
|
|
36
|
+
* or an RPC service binding. On a stub every member read names a remote
|
|
37
|
+
* method, including `bind` and `apply`.
|
|
38
|
+
*/
|
|
39
|
+
function boundMethod(method, target) {
|
|
40
|
+
return (...args) => Reflect.apply(method, target, args);
|
|
41
|
+
}
|
|
32
42
|
/** One field of a value, when the value is an object at all. */
|
|
33
43
|
function readProperty(source, key) {
|
|
34
44
|
return asRecord(source)?.[key];
|
|
@@ -105,4 +115,4 @@ function describeValue(value) {
|
|
|
105
115
|
}
|
|
106
116
|
|
|
107
117
|
//#endregion
|
|
108
|
-
export {
|
|
118
|
+
export { readProperty as _, asRecord as a, asString as c, hasMethod as d, hasMethods as f, readPath as g, numberAt as h, asNumber as i, boundMethod as l, nonEmptyString as m, asBoolean as n, asScalar as o, member as p, asFunction as r, asScalarArray as s, applyTrap as t, describeValue as u, trapArgs as v };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-cloudflare",
|
|
3
|
-
"version": "18.2.
|
|
3
|
+
"version": "18.2.4",
|
|
4
4
|
"description": "The #1 OpenTelemetry package for Cloudflare Workers - complete bindings coverage, native CF OTel integration, advanced sampling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -85,8 +85,8 @@
|
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
87
|
"@cloudflare/workers-types": "^5.20260928.1",
|
|
88
|
-
"autotel-edge": "6.1.
|
|
89
|
-
"autotel-genai": "0.16.
|
|
88
|
+
"autotel-edge": "6.1.1",
|
|
89
|
+
"autotel-genai": "0.16.2"
|
|
90
90
|
},
|
|
91
91
|
"peerDependenciesMeta": {
|
|
92
92
|
"autotel-edge": {
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"@cloudflare/workers-types": "^5.20260928.1",
|
|
101
101
|
"@opentelemetry/context-async-hooks": "^2.11.0",
|
|
102
102
|
"@types/node": "^26.6.3",
|
|
103
|
-
"autotel-edge": "6.1.
|
|
104
|
-
"autotel-genai": "0.16.
|
|
103
|
+
"autotel-edge": "6.1.1",
|
|
104
|
+
"autotel-genai": "0.16.2",
|
|
105
105
|
"rimraf": "^6.1.3",
|
|
106
106
|
"tsdown": "^0.23.0",
|
|
107
107
|
"typescript": "^7.0.2",
|