@inference-net/otel-cf-workers 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3664 @@
1
+ import { Buffer } from 'node:buffer';
2
+ import { TraceFlags, SpanStatusCode, context, ROOT_CONTEXT, SpanKind, trace, propagation } from '@opentelemetry/api';
3
+ import { TraceIdRatioBasedSampler, ParentBasedSampler, RandomIdGenerator, SamplingDecision } from '@opentelemetry/sdk-trace-base';
4
+ import { resourceFromAttributes } from '@opentelemetry/resources';
5
+ import { ExportResultCode, sanitizeAttributes, isAttributeValue, isTimeInput, hrTimeDuration, W3CTraceContextPropagator } from '@opentelemetry/core';
6
+ import { OTLPExporterError } from '@opentelemetry/otlp-exporter-base';
7
+ import { JsonTraceSerializer } from '@opentelemetry/otlp-transformer';
8
+ import { AsyncLocalStorage } from 'node:async_hooks';
9
+ import { EventEmitter } from 'node:events';
10
+ import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
11
+ import { FAAS_TRIGGER_VALUE_PUBSUB, ATTR_FAAS_TRIGGER, FAAS_TRIGGER_VALUE_TIMER, ATTR_FAAS_TIME, ATTR_FAAS_CRON, ATTR_MESSAGING_DESTINATION_NAME, ATTR_RPC_MESSAGE_ID } from '@opentelemetry/semantic-conventions/incubating';
12
+ import { DurableObject, env } from 'cloudflare:workers';
13
+
14
+ globalThis.Buffer = Buffer;
15
+
16
+ function multiTailSampler(samplers) {
17
+ return (traceInfo) => {
18
+ return samplers.reduce((result, sampler) => result || sampler(traceInfo), false);
19
+ };
20
+ }
21
+ const isHeadSampled = (traceInfo) => {
22
+ const localRootSpan = traceInfo.localRootSpan;
23
+ return (localRootSpan.spanContext().traceFlags & TraceFlags.SAMPLED) === TraceFlags.SAMPLED;
24
+ };
25
+ const isRootErrorSpan = (traceInfo) => {
26
+ const localRootSpan = traceInfo.localRootSpan;
27
+ return localRootSpan.status.code === SpanStatusCode.ERROR;
28
+ };
29
+ function createSampler(conf) {
30
+ const ratioSampler = new TraceIdRatioBasedSampler(conf.ratio);
31
+ if (typeof conf.acceptRemote === "boolean" && !conf.acceptRemote) {
32
+ return new ParentBasedSampler({
33
+ root: ratioSampler,
34
+ remoteParentSampled: ratioSampler,
35
+ remoteParentNotSampled: ratioSampler
36
+ });
37
+ } else {
38
+ return new ParentBasedSampler({ root: ratioSampler });
39
+ }
40
+ }
41
+
42
+ function isSpanProcessorConfig(config) {
43
+ return !!config.spanProcessors;
44
+ }
45
+
46
+ const unwrapSymbol = Symbol("unwrap");
47
+ function isWrapped(item) {
48
+ return item && !!item[unwrapSymbol];
49
+ }
50
+ function isProxyable(item) {
51
+ return item !== null && typeof item === "object" || typeof item === "function";
52
+ }
53
+ function wrap(item, handler, autoPassthrough = true) {
54
+ if (isWrapped(item) || !isProxyable(item)) {
55
+ return item;
56
+ }
57
+ const proxyHandler = Object.assign({}, handler);
58
+ proxyHandler.get = (target, prop, receiver) => {
59
+ if (prop === unwrapSymbol) {
60
+ return item;
61
+ } else {
62
+ if (handler.get) {
63
+ return handler.get(target, prop, receiver);
64
+ } else if (prop === "bind") {
65
+ return () => receiver;
66
+ } else if (autoPassthrough) {
67
+ return passthroughGet(target, prop);
68
+ }
69
+ }
70
+ };
71
+ proxyHandler.apply = (target, thisArg, argArray) => {
72
+ if (handler.apply) {
73
+ return handler.apply(unwrap(target), unwrap(thisArg), argArray);
74
+ }
75
+ };
76
+ return new Proxy(item, proxyHandler);
77
+ }
78
+ function unwrap(item) {
79
+ if (item && isWrapped(item)) {
80
+ return item[unwrapSymbol];
81
+ } else {
82
+ return item;
83
+ }
84
+ }
85
+ function passthroughGet(target, prop, thisArg) {
86
+ const unwrappedTarget = unwrap(target);
87
+ thisArg = unwrap(thisArg) || unwrappedTarget;
88
+ const value = Reflect.get(unwrappedTarget, prop);
89
+ if (typeof value === "function") {
90
+ if (value.constructor.name === "RpcProperty") {
91
+ return (...args) => unwrappedTarget[prop](...args);
92
+ }
93
+ return value.bind(thisArg);
94
+ } else {
95
+ return value;
96
+ }
97
+ }
98
+
99
+ const PACKAGE_VERSION = "2.0.0";
100
+ const PACKAGE_NAME = "@inference-net/otel-cf-workers";
101
+ const ATTR_CLOUDFLARE_COLO = "cloudflare.colo";
102
+ const ATTR_CLOUDFLARE_RAY_ID = "cloudflare.ray_id";
103
+ const ATTR_CLOUDFLARE_HANDLER_TYPE = "cloudflare.handler_type";
104
+ const ATTR_CLOUDFLARE_EXECUTION_MODEL = "cloudflare.execution_model";
105
+ const ATTR_CLOUDFLARE_VERIFIED_BOT_CATEGORY = "cloudflare.verified_bot_category";
106
+ const ATTR_CLOUDFLARE_ASN = "cloudflare.asn";
107
+ const ATTR_GEO_TIMEZONE = "geo.timezone";
108
+ const ATTR_GEO_CONTINENT_CODE = "geo.continent.code";
109
+ const ATTR_GEO_COUNTRY_CODE = "geo.country.code";
110
+ const ATTR_GEO_LOCALITY_NAME = "geo.locality.name";
111
+ const ATTR_GEO_LOCALITY_REGION = "geo.locality.region";
112
+ const ATTR_USER_AGENT_OS_NAME = "user_agent.os.name";
113
+ const ATTR_USER_AGENT_OS_VERSION = "user_agent.os.version";
114
+ const ATTR_USER_AGENT_BROWSER_NAME = "user_agent.browser.name";
115
+ const ATTR_USER_AGENT_BROWSER_MAJOR_VERSION = "user_agent.browser.major_version";
116
+ const ATTR_USER_AGENT_BROWSER_VERSION = "user_agent.browser.version";
117
+ const ATTR_USER_AGENT_ENGINE_NAME = "user_agent.engine.name";
118
+ const ATTR_USER_AGENT_ENGINE_VERSION = "user_agent.engine.version";
119
+ const ATTR_USER_AGENT_DEVICE_TYPE = "user_agent.device.type";
120
+ const ATTR_USER_AGENT_DEVICE_VENDOR = "user_agent.device.vendor";
121
+ const ATTR_USER_AGENT_DEVICE_MODEL = "user_agent.device.model";
122
+ const ATTR_HTTP_REQUEST_HEADER_CONTENT_TYPE = "http.request.header.content-type";
123
+ const ATTR_HTTP_REQUEST_HEADER_CONTENT_LENGTH = "http.request.header.content-length";
124
+ const ATTR_HTTP_REQUEST_HEADER_ACCEPT = "http.request.header.accept";
125
+ const ATTR_HTTP_REQUEST_HEADER_ACCEPT_ENCODING = "http.request.header.accept-encoding";
126
+ const ATTR_HTTP_REQUEST_HEADER_ACCEPT_LANGUAGE = "http.request.header.accept-language";
127
+ const ATTR_CLOUDFLARE_SCHEDULED_TIME = "cloudflare.scheduled_time";
128
+ const ATTR_CLOUDFLARE_QUEUE_NAME = "cloudflare.queue.name";
129
+ const ATTR_CLOUDFLARE_QUEUE_BATCH_SIZE = "cloudflare.queue.batch_size";
130
+ const ATTR_CLOUDFLARE_EMAIL_FROM = "cloudflare.email.from";
131
+ const ATTR_CLOUDFLARE_EMAIL_TO = "cloudflare.email.to";
132
+ const ATTR_CLOUDFLARE_EMAIL_SIZE = "cloudflare.email.size";
133
+ const ATTR_CLOUDFLARE_BINDING_TYPE = "cloudflare.binding.type";
134
+ const ATTR_CLOUDFLARE_BINDING_NAME = "cloudflare.binding.name";
135
+ const ATTR_DB_SYSTEM_NAME = "db.system.name";
136
+ const ATTR_DB_OPERATION_NAME = "db.operation.name";
137
+ const ATTR_DB_QUERY_TEXT = "db.query.text";
138
+ const ATTR_DB_OPERATION_BATCH_SIZE = "db.operation.batch.size";
139
+ const ATTR_CLOUDFLARE_D1_RESPONSE_SIZE_AFTER = "cloudflare.d1.response.size_after";
140
+ const ATTR_CLOUDFLARE_D1_RESPONSE_ROWS_READ = "cloudflare.d1.response.rows_read";
141
+ const ATTR_CLOUDFLARE_D1_RESPONSE_ROWS_WRITTEN = "cloudflare.d1.response.rows_written";
142
+ const ATTR_CLOUDFLARE_D1_RESPONSE_LAST_ROW_ID = "cloudflare.d1.response.last_row_id";
143
+ const ATTR_CLOUDFLARE_D1_RESPONSE_CHANGED_DB = "cloudflare.d1.response.changed_db";
144
+ const ATTR_CLOUDFLARE_D1_RESPONSE_CHANGES = "cloudflare.d1.response.changes";
145
+ const ATTR_CLOUDFLARE_D1_RESPONSE_SQL_DURATION_MS = "cloudflare.d1.response.sql_duration_ms";
146
+ const ATTR_CLOUDFLARE_KV_QUERY_KEYS = "cloudflare.kv.query.keys";
147
+ const ATTR_CLOUDFLARE_KV_QUERY_KEYS_COUNT = "cloudflare.kv.query.keys.count";
148
+ const ATTR_CLOUDFLARE_KV_QUERY_TYPE = "cloudflare.kv.query.type";
149
+ const ATTR_CLOUDFLARE_KV_QUERY_CACHE_TTL = "cloudflare.kv.query.cache_ttl";
150
+ const ATTR_CLOUDFLARE_KV_QUERY_VALUE_TYPE = "cloudflare.kv.query.value_type";
151
+ const ATTR_CLOUDFLARE_KV_QUERY_EXPIRATION = "cloudflare.kv.query.expiration";
152
+ const ATTR_CLOUDFLARE_KV_QUERY_EXPIRATION_TTL = "cloudflare.kv.query.expiration_ttl";
153
+ const ATTR_CLOUDFLARE_KV_QUERY_METADATA = "cloudflare.kv.query.metadata";
154
+ const ATTR_CLOUDFLARE_KV_QUERY_PREFIX = "cloudflare.kv.query.prefix";
155
+ const ATTR_CLOUDFLARE_KV_QUERY_LIMIT = "cloudflare.kv.query.limit";
156
+ const ATTR_CLOUDFLARE_KV_QUERY_CURSOR = "cloudflare.kv.query.cursor";
157
+ const ATTR_CLOUDFLARE_KV_RESPONSE_METADATA = "cloudflare.kv.response.metadata";
158
+ const ATTR_CLOUDFLARE_KV_RESPONSE_CACHE_STATUS = "cloudflare.kv.response.cache_status";
159
+ const ATTR_CLOUDFLARE_KV_RESPONSE_LIST_COMPLETE = "cloudflare.kv.response.list_complete";
160
+ const ATTR_CLOUDFLARE_KV_RESPONSE_CURSOR = "cloudflare.kv.response.cursor";
161
+ const ATTR_CLOUDFLARE_R2_QUERY_KEY = "cloudflare.r2.query.key";
162
+ const ATTR_CLOUDFLARE_R2_QUERY_PREFIX = "cloudflare.r2.query.prefix";
163
+ const ATTR_CLOUDFLARE_R2_QUERY_LIMIT = "cloudflare.r2.query.limit";
164
+ const ATTR_CLOUDFLARE_R2_QUERY_DELIMITER = "cloudflare.r2.query.delimiter";
165
+ const ATTR_CLOUDFLARE_R2_QUERY_START_AFTER = "cloudflare.r2.query.start_after";
166
+ const ATTR_CLOUDFLARE_R2_QUERY_INCLUDE = "cloudflare.r2.query.include";
167
+ const ATTR_CLOUDFLARE_R2_QUERY_OFFSET = "cloudflare.r2.query.offset";
168
+ const ATTR_CLOUDFLARE_R2_QUERY_LENGTH = "cloudflare.r2.query.length";
169
+ const ATTR_CLOUDFLARE_R2_QUERY_SUFFIX = "cloudflare.r2.query.suffix";
170
+ const ATTR_CLOUDFLARE_R2_QUERY_ONLY_IF = "cloudflare.r2.query.only_if";
171
+ const ATTR_CLOUDFLARE_R2_PUT_HTTP_METADATA = "cloudflare.r2.put.http_metadata";
172
+ const ATTR_CLOUDFLARE_R2_PUT_CUSTOM_METADATA = "cloudflare.r2.put.custom_metadata";
173
+ const ATTR_CLOUDFLARE_R2_PUT_MD5 = "cloudflare.r2.put.md5";
174
+ const ATTR_CLOUDFLARE_R2_PUT_SHA1 = "cloudflare.r2.put.sha1";
175
+ const ATTR_CLOUDFLARE_R2_PUT_SHA256 = "cloudflare.r2.put.sha256";
176
+ const ATTR_CLOUDFLARE_R2_PUT_SHA384 = "cloudflare.r2.put.sha384";
177
+ const ATTR_CLOUDFLARE_R2_PUT_SHA512 = "cloudflare.r2.put.sha512";
178
+ const ATTR_CLOUDFLARE_R2_PUT_STORAGE_CLASS = "cloudflare.r2.put.storage_class";
179
+ const ATTR_CLOUDFLARE_R2_RESPONSE_SIZE = "cloudflare.r2.response.size";
180
+ const ATTR_CLOUDFLARE_R2_RESPONSE_ETAG = "cloudflare.r2.response.etag";
181
+ const ATTR_CLOUDFLARE_R2_RESPONSE_VERSION = "cloudflare.r2.response.version";
182
+ const ATTR_CLOUDFLARE_R2_RESPONSE_UPLOADED = "cloudflare.r2.response.uploaded";
183
+ const ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CONTENT_TYPE = "cloudflare.r2.response.http_metadata.content_type";
184
+ const ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CONTENT_LANGUAGE = "cloudflare.r2.response.http_metadata.content_language";
185
+ const ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CONTENT_DISPOSITION = "cloudflare.r2.response.http_metadata.content_disposition";
186
+ const ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CONTENT_ENCODING = "cloudflare.r2.response.http_metadata.content_encoding";
187
+ const ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CACHE_CONTROL = "cloudflare.r2.response.http_metadata.cache_control";
188
+ const ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CACHE_EXPIRY = "cloudflare.r2.response.http_metadata.cache_expiry";
189
+ const ATTR_CLOUDFLARE_R2_RESPONSE_CUSTOM_METADATA_KEYS = "cloudflare.r2.response.custom_metadata.keys";
190
+ const ATTR_CLOUDFLARE_R2_RESPONSE_RANGE = "cloudflare.r2.response.range";
191
+ const ATTR_CLOUDFLARE_R2_RESPONSE_STORAGE_CLASS = "cloudflare.r2.response.storage_class";
192
+ const ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_MD5 = "cloudflare.r2.response.checksums.md5";
193
+ const ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_SHA1 = "cloudflare.r2.response.checksums.sha1";
194
+ const ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_SHA256 = "cloudflare.r2.response.checksums.sha256";
195
+ const ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_SHA384 = "cloudflare.r2.response.checksums.sha384";
196
+ const ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_SHA512 = "cloudflare.r2.response.checksums.sha512";
197
+ const ATTR_CLOUDFLARE_R2_LIST_TRUNCATED = "cloudflare.r2.list.truncated";
198
+ const ATTR_CLOUDFLARE_R2_LIST_OBJECTS_COUNT = "cloudflare.r2.list.objects.count";
199
+ const ATTR_CLOUDFLARE_R2_LIST_DELIMITED_PREFIXES_COUNT = "cloudflare.r2.list.delimited_prefixes.count";
200
+ const ATTR_CLOUDFLARE_R2_LIST_CURSOR = "cloudflare.r2.list.cursor";
201
+ const ATTR_CLOUDFLARE_R2_MULTIPART_UPLOAD_ID = "cloudflare.r2.multipart.upload_id";
202
+ const ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS = "cloudflare.durable_object.kv.query.keys";
203
+ const ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS_COUNT = "cloudflare.durable_object.kv.query.keys.count";
204
+ const ATTR_CLOUDFLARE_DO_KV_QUERY_START = "cloudflare.durable_object.kv.query.start";
205
+ const ATTR_CLOUDFLARE_DO_KV_QUERY_START_AFTER = "cloudflare.durable_object.kv.query.startAfter";
206
+ const ATTR_CLOUDFLARE_DO_KV_QUERY_END = "cloudflare.durable_object.kv.query.end";
207
+ const ATTR_CLOUDFLARE_DO_KV_QUERY_PREFIX = "cloudflare.durable_object.kv.query.prefix";
208
+ const ATTR_CLOUDFLARE_DO_KV_QUERY_REVERSE = "cloudflare.durable_object.kv.query.reverse";
209
+ const ATTR_CLOUDFLARE_DO_KV_QUERY_LIMIT = "cloudflare.durable_object.kv.query.limit";
210
+ const ATTR_CLOUDFLARE_DO_KV_RESPONSE_DELETED_COUNT = "cloudflare.durable_object.kv.response.deleted_count";
211
+ const ATTR_CLOUDFLARE_DO_ALLOW_CONCURRENCY = "cloudflare.durable_object.allow_concurrency";
212
+ const ATTR_CLOUDFLARE_DO_ALLOW_UNCONFIRMED = "cloudflare.durable_object.allow_unconfirmed";
213
+ const ATTR_CLOUDFLARE_DO_NO_CACHE = "cloudflare.durable_object.no_cache";
214
+ const ATTR_CLOUDFLARE_DO_SQL_QUERY_BINDINGS = "cloudflare.durable_object.query.bindings";
215
+ const ATTR_CLOUDFLARE_DO_SQL_RESPONSE_ROWS_READ = "cloudflare.durable_object.response.rows_read";
216
+ const ATTR_CLOUDFLARE_DO_SQL_RESPONSE_ROWS_WRITTEN = "cloudflare.durable_object.response.rows_written";
217
+ const ATTR_CLOUDFLARE_IMAGES_KEY = "cloudflare.images.key";
218
+ const ATTR_CLOUDFLARE_IMAGES_VARIANTS_COUNT = "cloudflare.images.variants.count";
219
+ const ATTR_CLOUDFLARE_IMAGES_UPLOADED = "cloudflare.images.uploaded";
220
+ const ATTR_CLOUDFLARE_IMAGES_RESPONSE_ID = "cloudflare.images.response.id";
221
+ const ATTR_CLOUDFLARE_IMAGES_RESPONSE_FILENAME = "cloudflare.images.response.filename";
222
+ const ATTR_CLOUDFLARE_IMAGES_METADATA_KEYS = "cloudflare.images.metadata.keys";
223
+ const ATTR_CLOUDFLARE_IMAGES_REQUIRE_SIGNED_URLS = "cloudflare.images.require_signed_urls";
224
+ const ATTR_CLOUDFLARE_RATE_LIMIT_KEY = "cloudflare.rate_limit.key";
225
+ const ATTR_CLOUDFLARE_RATE_LIMIT_ALLOWED = "cloudflare.rate_limit.allowed";
226
+ const ATTR_CLOUDFLARE_RATE_LIMIT_SUCCESS = "cloudflare.rate_limit.success";
227
+ const DEFAULT_OTLP_HEADERS = {
228
+ accept: "application/json",
229
+ "content-type": "application/json",
230
+ "user-agent": `Cloudflare Worker ${PACKAGE_NAME} v${PACKAGE_VERSION}`
231
+ };
232
+ const SEVERITY_NUMBERS = {
233
+ TRACE: 1,
234
+ TRACE2: 2,
235
+ TRACE3: 3,
236
+ TRACE4: 4,
237
+ DEBUG: 5,
238
+ DEBUG2: 6,
239
+ DEBUG3: 7,
240
+ DEBUG4: 8,
241
+ INFO: 9,
242
+ INFO2: 10,
243
+ INFO3: 11,
244
+ INFO4: 12,
245
+ WARN: 13,
246
+ WARN2: 14,
247
+ WARN3: 15,
248
+ WARN4: 16,
249
+ ERROR: 17,
250
+ ERROR2: 18,
251
+ ERROR3: 19,
252
+ ERROR4: 20,
253
+ FATAL: 21,
254
+ FATAL2: 22,
255
+ FATAL3: 23,
256
+ FATAL4: 24
257
+ };
258
+
259
+ class OTLPExporter {
260
+ headers;
261
+ url;
262
+ constructor(config) {
263
+ this.url = config.url;
264
+ this.headers = Object.assign({}, DEFAULT_OTLP_HEADERS, config.headers);
265
+ }
266
+ export(items, resultCallback) {
267
+ this._export(items).then(() => {
268
+ resultCallback({ code: ExportResultCode.SUCCESS });
269
+ }).catch((error) => {
270
+ resultCallback({ code: ExportResultCode.FAILED, error });
271
+ });
272
+ }
273
+ _export(items) {
274
+ return new Promise((resolve, reject) => {
275
+ try {
276
+ this.send(items, resolve, reject);
277
+ } catch (e) {
278
+ reject(e);
279
+ }
280
+ });
281
+ }
282
+ send(items, onSuccess, onError) {
283
+ const decoder = new TextDecoder();
284
+ const exportMessage = JsonTraceSerializer.serializeRequest(items);
285
+ const body = decoder.decode(exportMessage);
286
+ const params = {
287
+ method: "POST",
288
+ headers: this.headers,
289
+ body
290
+ };
291
+ unwrap(fetch)(this.url, params).then((response) => {
292
+ if (response.ok) {
293
+ onSuccess();
294
+ } else {
295
+ onError(new OTLPExporterError(`Exporter received a statusCode: ${response.status}`));
296
+ }
297
+ }).catch((error) => {
298
+ onError(new OTLPExporterError(`Exception during export: ${error.toString()}`, error.code, error.stack));
299
+ });
300
+ }
301
+ async shutdown() {
302
+ }
303
+ }
304
+
305
+ function getSampler() {
306
+ const conf = getActiveConfig();
307
+ if (!conf) {
308
+ console.log("Could not find config for sampling, sending everything by default");
309
+ }
310
+ return conf ? conf.sampling.tailSampler : () => true;
311
+ }
312
+ class TraceState {
313
+ unexportedSpans = [];
314
+ inprogressSpans = /* @__PURE__ */ new Set();
315
+ exporter;
316
+ exportPromises = [];
317
+ localRootSpan;
318
+ traceDecision;
319
+ constructor(exporter) {
320
+ this.exporter = exporter;
321
+ }
322
+ addSpan(span) {
323
+ const readableSpan = span;
324
+ this.localRootSpan = this.localRootSpan || readableSpan;
325
+ this.unexportedSpans.push(readableSpan);
326
+ this.inprogressSpans.add(span.spanContext().spanId);
327
+ }
328
+ endSpan(span) {
329
+ this.inprogressSpans.delete(span.spanContext().spanId);
330
+ if (this.inprogressSpans.size === 0) {
331
+ this.flush();
332
+ }
333
+ }
334
+ sample() {
335
+ if (this.traceDecision === void 0 && this.unexportedSpans.length > 0) {
336
+ const sampler = getSampler();
337
+ this.traceDecision = sampler({
338
+ traceId: this.localRootSpan.spanContext().traceId,
339
+ localRootSpan: this.localRootSpan,
340
+ spans: this.unexportedSpans
341
+ });
342
+ }
343
+ this.unexportedSpans = this.traceDecision ? this.unexportedSpans : [];
344
+ }
345
+ async flush() {
346
+ if (this.unexportedSpans.length > 0) {
347
+ const unfinishedSpans = this.unexportedSpans.filter((span) => this.isSpanInProgress(span));
348
+ for (const span of unfinishedSpans) {
349
+ console.log(`Span ${span.spanContext().spanId} was not ended properly`);
350
+ span.end();
351
+ }
352
+ this.sample();
353
+ this.exportPromises.push(this.exportSpans(this.unexportedSpans));
354
+ this.unexportedSpans = [];
355
+ }
356
+ if (this.exportPromises.length > 0) {
357
+ await Promise.allSettled(this.exportPromises);
358
+ }
359
+ }
360
+ isSpanInProgress(span) {
361
+ return this.inprogressSpans.has(span.spanContext().spanId);
362
+ }
363
+ async exportSpans(spans) {
364
+ await scheduler.wait(1);
365
+ const promise = new Promise((resolve, reject) => {
366
+ this.exporter.export(spans, (result) => {
367
+ if (result.code === ExportResultCode.SUCCESS) {
368
+ resolve();
369
+ } else {
370
+ console.log("exporting spans failed! " + result.error);
371
+ reject(result.error);
372
+ }
373
+ });
374
+ });
375
+ await promise;
376
+ }
377
+ }
378
+ class BatchTraceSpanProcessor {
379
+ constructor(exporter) {
380
+ this.exporter = exporter;
381
+ }
382
+ traces = {};
383
+ getTraceState(traceId) {
384
+ const traceState = this.traces[traceId] || new TraceState(this.exporter);
385
+ this.traces[traceId] = traceState;
386
+ return traceState;
387
+ }
388
+ onStart(span, _parentContext) {
389
+ const traceId = span.spanContext().traceId;
390
+ this.getTraceState(traceId).addSpan(span);
391
+ }
392
+ onEnd(span) {
393
+ const traceId = span.spanContext().traceId;
394
+ this.getTraceState(traceId).endSpan(span);
395
+ }
396
+ async forceFlush(traceId) {
397
+ if (traceId) {
398
+ await this.getTraceState(traceId).flush();
399
+ } else {
400
+ const promises = Object.values(this.traces).map((traceState) => traceState.flush);
401
+ await Promise.allSettled(promises);
402
+ }
403
+ }
404
+ async shutdown() {
405
+ await this.forceFlush();
406
+ }
407
+ }
408
+
409
+ class ImmediateLogRecordProcessor {
410
+ transport;
411
+ exportPromises = [];
412
+ constructor(transport) {
413
+ this.transport = transport;
414
+ }
415
+ onEmit(logRecord, _context) {
416
+ this.exportPromises.push(this.exportLog(logRecord));
417
+ }
418
+ async exportLog(logRecord) {
419
+ await scheduler.wait(1);
420
+ return new Promise((resolve, reject) => {
421
+ this.transport.export([logRecord], (result) => {
422
+ if (result.code === ExportResultCode.SUCCESS) {
423
+ resolve();
424
+ } else {
425
+ console.error("Failed to export log:", result.error);
426
+ reject(result.error);
427
+ }
428
+ });
429
+ });
430
+ }
431
+ async forceFlush() {
432
+ if (this.exportPromises.length > 0) {
433
+ await Promise.allSettled(this.exportPromises);
434
+ this.exportPromises = [];
435
+ }
436
+ }
437
+ async shutdown() {
438
+ await this.forceFlush();
439
+ await this.transport.shutdown();
440
+ }
441
+ }
442
+ class BatchSizeLogRecordProcessor {
443
+ transport;
444
+ logRecords = [];
445
+ exportPromises = [];
446
+ maxQueueSize;
447
+ maxExportBatchSize;
448
+ constructor(transport, config) {
449
+ this.transport = transport;
450
+ this.maxQueueSize = config?.maxQueueSize ?? 512;
451
+ this.maxExportBatchSize = config?.maxExportBatchSize ?? this.maxQueueSize;
452
+ }
453
+ onEmit(logRecord, _context) {
454
+ this.logRecords.push(logRecord);
455
+ if (this.logRecords.length >= this.maxQueueSize) {
456
+ this.exportPromises.push(this.export());
457
+ }
458
+ }
459
+ async forceFlush() {
460
+ if (this.logRecords.length > 0) {
461
+ this.exportPromises.push(this.export());
462
+ }
463
+ if (this.exportPromises.length > 0) {
464
+ await Promise.allSettled(this.exportPromises);
465
+ this.exportPromises = [];
466
+ }
467
+ }
468
+ async export() {
469
+ const batch = this.logRecords.splice(0, this.maxExportBatchSize);
470
+ if (batch.length === 0) {
471
+ return;
472
+ }
473
+ await scheduler.wait(1);
474
+ return new Promise((resolve, reject) => {
475
+ this.transport.export(batch, (result) => {
476
+ if (result.code === ExportResultCode.SUCCESS) {
477
+ resolve();
478
+ } else {
479
+ console.error("Failed to export logs:", result.error);
480
+ reject(result.error);
481
+ }
482
+ });
483
+ });
484
+ }
485
+ async shutdown() {
486
+ await this.forceFlush();
487
+ await this.transport.shutdown();
488
+ }
489
+ }
490
+ class MultiTransportLogRecordProcessor {
491
+ processors;
492
+ constructor(transports, config) {
493
+ this.processors = transports.map((transport) => {
494
+ return createLogProcessor(transport, config);
495
+ });
496
+ }
497
+ onEmit(logRecord, context) {
498
+ this.processors.forEach((p) => p.onEmit(logRecord, context));
499
+ }
500
+ async forceFlush() {
501
+ await Promise.allSettled(this.processors.map((p) => p.forceFlush()));
502
+ }
503
+ async shutdown() {
504
+ await Promise.allSettled(this.processors.map((p) => p.shutdown()));
505
+ }
506
+ }
507
+ function createLogProcessor(transport, config) {
508
+ const strategy = config?.strategy ?? "size";
509
+ switch (strategy) {
510
+ case "immediate":
511
+ return new ImmediateLogRecordProcessor(transport);
512
+ case "size":
513
+ return new BatchSizeLogRecordProcessor(transport, config);
514
+ default:
515
+ throw new Error(`Unknown batch strategy: ${strategy}`);
516
+ }
517
+ }
518
+
519
+ const traceConfigSymbol = Symbol("Otel Workers Tracing Configuration");
520
+ const logsConfigSymbol = Symbol("Otel Workers Logs Configuration");
521
+ function setConfig(config, ctx = context.active()) {
522
+ let newCtx = ctx;
523
+ if (config.trace) {
524
+ newCtx = newCtx.setValue(traceConfigSymbol, config.trace);
525
+ }
526
+ if (config.logs) {
527
+ newCtx = newCtx.setValue(logsConfigSymbol, config.logs);
528
+ }
529
+ return newCtx;
530
+ }
531
+ function getActiveConfig() {
532
+ const config = context.active().getValue(traceConfigSymbol);
533
+ return config || void 0;
534
+ }
535
+ function isSpanExporter(exporterConfig) {
536
+ return !!exporterConfig.export;
537
+ }
538
+ function isSampler(sampler) {
539
+ return !!sampler.shouldSample;
540
+ }
541
+ function parseConfig(supplied) {
542
+ const config = {};
543
+ if (supplied.trace) {
544
+ config.trace = parseTraceConfig(supplied.trace, supplied.propagator);
545
+ }
546
+ if (supplied.logs) {
547
+ config.logs = parseLogsConfig(supplied.logs);
548
+ }
549
+ return config;
550
+ }
551
+ function parseTraceConfig(supplied, propagator) {
552
+ if (isSpanProcessorConfig(supplied)) {
553
+ const headSampleConf = supplied.sampling?.headSampler || { ratio: 1 };
554
+ const headSampler = isSampler(headSampleConf) ? headSampleConf : createSampler(headSampleConf);
555
+ const spanProcessors = Array.isArray(supplied.spanProcessors) ? supplied.spanProcessors : [supplied.spanProcessors];
556
+ if (spanProcessors.length === 0) {
557
+ console.log(
558
+ "Warning! You must either specify an exporter or your own SpanProcessor(s)/Exporter combination in the open-telemetry configuration."
559
+ );
560
+ }
561
+ return {
562
+ fetch: {
563
+ includeTraceContext: supplied.fetch?.includeTraceContext ?? true
564
+ },
565
+ handlers: {
566
+ fetch: {
567
+ acceptTraceContext: supplied.handlers?.fetch?.acceptTraceContext ?? true
568
+ }
569
+ },
570
+ postProcessor: supplied.postProcessor || ((spans) => spans),
571
+ sampling: {
572
+ headSampler,
573
+ tailSampler: supplied.sampling?.tailSampler || multiTailSampler([isHeadSampled, isRootErrorSpan])
574
+ },
575
+ spanProcessors,
576
+ instrumentation: {
577
+ instrumentGlobalCache: supplied.instrumentation?.instrumentGlobalCache ?? true,
578
+ instrumentGlobalFetch: supplied.instrumentation?.instrumentGlobalFetch ?? true
579
+ },
580
+ batching: {
581
+ strategy: supplied.batching?.strategy ?? "trace",
582
+ maxQueueSize: supplied.batching?.maxQueueSize,
583
+ maxExportBatchSize: supplied.batching?.maxExportBatchSize
584
+ }
585
+ };
586
+ } else {
587
+ const exporter = isSpanExporter(supplied.exporter) ? supplied.exporter : new OTLPExporter(supplied.exporter);
588
+ const spanProcessors = [new BatchTraceSpanProcessor(exporter)];
589
+ const newConfig = Object.assign({}, supplied, { exporter: void 0, spanProcessors });
590
+ return parseTraceConfig(newConfig);
591
+ }
592
+ }
593
+ function parseLogsConfig(supplied) {
594
+ const processors = supplied.transports && supplied.transports.length > 0 ? [new MultiTransportLogRecordProcessor(supplied.transports, supplied.batching)] : [];
595
+ return {
596
+ processors,
597
+ instrumentation: {
598
+ instrumentConsole: supplied.instrumentation?.instrumentConsole ?? false
599
+ }
600
+ };
601
+ }
602
+
603
+ const ADD_LISTENER_METHODS = [
604
+ "addListener",
605
+ "on",
606
+ "once",
607
+ "prependListener",
608
+ "prependOnceListener"
609
+ ];
610
+ class AbstractAsyncHooksContextManager {
611
+ /**
612
+ * Binds a the certain context or the active one to the target function and then returns the target
613
+ * @param context A context (span) to be bind to target
614
+ * @param target a function or event emitter. When target or one of its callbacks is called,
615
+ * the provided context will be used as the active context for the duration of the call.
616
+ */
617
+ bind(context, target) {
618
+ if (target instanceof EventEmitter) {
619
+ return this._bindEventEmitter(context, target);
620
+ }
621
+ if (typeof target === "function") {
622
+ return this._bindFunction(context, target);
623
+ }
624
+ return target;
625
+ }
626
+ _bindFunction(context, target) {
627
+ const manager = this;
628
+ const contextWrapper = function(...args) {
629
+ return manager.with(context, () => target.apply(this, args));
630
+ };
631
+ Object.defineProperty(contextWrapper, "length", {
632
+ enumerable: false,
633
+ configurable: true,
634
+ writable: false,
635
+ value: target.length
636
+ });
637
+ return contextWrapper;
638
+ }
639
+ /**
640
+ * By default, EventEmitter call their callback with their context, which we do
641
+ * not want, instead we will bind a specific context to all callbacks that
642
+ * go through it.
643
+ * @param context the context we want to bind
644
+ * @param ee EventEmitter an instance of EventEmitter to patch
645
+ */
646
+ _bindEventEmitter(context, ee) {
647
+ const map = this._getPatchMap(ee);
648
+ if (map !== void 0) return ee;
649
+ this._createPatchMap(ee);
650
+ ADD_LISTENER_METHODS.forEach((methodName) => {
651
+ if (ee[methodName] === void 0) return;
652
+ ee[methodName] = this._patchAddListener(ee, ee[methodName], context);
653
+ });
654
+ if (typeof ee.removeListener === "function") {
655
+ ee.removeListener = this._patchRemoveListener(ee, ee.removeListener);
656
+ }
657
+ if (typeof ee.off === "function") {
658
+ ee.off = this._patchRemoveListener(ee, ee.off);
659
+ }
660
+ if (typeof ee.removeAllListeners === "function") {
661
+ ee.removeAllListeners = this._patchRemoveAllListeners(ee, ee.removeAllListeners);
662
+ }
663
+ return ee;
664
+ }
665
+ /**
666
+ * Patch methods that remove a given listener so that we match the "patched"
667
+ * version of that listener (the one that propagate context).
668
+ * @param ee EventEmitter instance
669
+ * @param original reference to the patched method
670
+ */
671
+ _patchRemoveListener(ee, original) {
672
+ const contextManager = this;
673
+ return function(event, listener) {
674
+ const events = contextManager._getPatchMap(ee)?.[event];
675
+ if (events === void 0) {
676
+ return original.call(this, event, listener);
677
+ }
678
+ const patchedListener = events.get(listener);
679
+ return original.call(this, event, patchedListener || listener);
680
+ };
681
+ }
682
+ /**
683
+ * Patch methods that remove all listeners so we remove our
684
+ * internal references for a given event.
685
+ * @param ee EventEmitter instance
686
+ * @param original reference to the patched method
687
+ */
688
+ _patchRemoveAllListeners(ee, original) {
689
+ const contextManager = this;
690
+ return function(event) {
691
+ const map = contextManager._getPatchMap(ee);
692
+ if (map !== void 0) {
693
+ if (arguments.length === 0) {
694
+ contextManager._createPatchMap(ee);
695
+ } else if (map[event] !== void 0) {
696
+ delete map[event];
697
+ }
698
+ }
699
+ return original.apply(this, arguments);
700
+ };
701
+ }
702
+ /**
703
+ * Patch methods on an event emitter instance that can add listeners so we
704
+ * can force them to propagate a given context.
705
+ * @param ee EventEmitter instance
706
+ * @param original reference to the patched method
707
+ * @param [context] context to propagate when calling listeners
708
+ */
709
+ _patchAddListener(ee, original, context) {
710
+ const contextManager = this;
711
+ return function(event, listener) {
712
+ if (contextManager._wrapped) {
713
+ return original.call(this, event, listener);
714
+ }
715
+ let map = contextManager._getPatchMap(ee);
716
+ if (map === void 0) {
717
+ map = contextManager._createPatchMap(ee);
718
+ }
719
+ let listeners = map[event];
720
+ if (listeners === void 0) {
721
+ listeners = /* @__PURE__ */ new WeakMap();
722
+ map[event] = listeners;
723
+ }
724
+ const patchedListener = contextManager.bind(context, listener);
725
+ listeners.set(listener, patchedListener);
726
+ contextManager._wrapped = true;
727
+ try {
728
+ return original.call(this, event, patchedListener);
729
+ } finally {
730
+ contextManager._wrapped = false;
731
+ }
732
+ };
733
+ }
734
+ _createPatchMap(ee) {
735
+ const map = /* @__PURE__ */ Object.create(null);
736
+ ee[this._kOtListeners] = map;
737
+ return map;
738
+ }
739
+ _getPatchMap(ee) {
740
+ return ee[this._kOtListeners];
741
+ }
742
+ _kOtListeners = Symbol("OtListeners");
743
+ _wrapped = false;
744
+ }
745
+ class AsyncLocalStorageContextManager extends AbstractAsyncHooksContextManager {
746
+ _asyncLocalStorage;
747
+ constructor() {
748
+ super();
749
+ this._asyncLocalStorage = new AsyncLocalStorage();
750
+ }
751
+ active() {
752
+ return this._asyncLocalStorage.getStore() ?? ROOT_CONTEXT;
753
+ }
754
+ with(context, fn, thisArg, ...args) {
755
+ const cb = thisArg == null ? fn : fn.bind(thisArg);
756
+ return this._asyncLocalStorage.run(context, cb, ...args);
757
+ }
758
+ enable() {
759
+ return this;
760
+ }
761
+ disable() {
762
+ this._asyncLocalStorage.disable();
763
+ return this;
764
+ }
765
+ }
766
+
767
+ function transformExceptionAttributes(exception) {
768
+ const attributes = {};
769
+ if (typeof exception === "string") {
770
+ attributes[SemanticAttributes.EXCEPTION_MESSAGE] = exception;
771
+ } else {
772
+ if (exception.code) {
773
+ attributes[SemanticAttributes.EXCEPTION_TYPE] = exception.code.toString();
774
+ } else if (exception.name) {
775
+ attributes[SemanticAttributes.EXCEPTION_TYPE] = exception.name;
776
+ }
777
+ if (exception.message) {
778
+ attributes[SemanticAttributes.EXCEPTION_MESSAGE] = exception.message;
779
+ }
780
+ if (exception.stack) {
781
+ attributes[SemanticAttributes.EXCEPTION_STACKTRACE] = exception.stack;
782
+ }
783
+ }
784
+ return attributes;
785
+ }
786
+ function millisToHr$1(millis) {
787
+ return [Math.trunc(millis / 1e3), millis % 1e3 * 1e6];
788
+ }
789
+ function getHrTime$1(input) {
790
+ const now = Date.now();
791
+ if (!input) {
792
+ return millisToHr$1(now);
793
+ } else if (input instanceof Date) {
794
+ return millisToHr$1(input.getTime());
795
+ } else if (typeof input === "number") {
796
+ return millisToHr$1(input);
797
+ } else if (Array.isArray(input)) {
798
+ return input;
799
+ }
800
+ const v = input;
801
+ throw new Error(`unreachable value: ${JSON.stringify(v)}`);
802
+ }
803
+ function isAttributeKey(key) {
804
+ return typeof key === "string" && key.length > 0;
805
+ }
806
+ class SpanImpl {
807
+ name;
808
+ _spanContext;
809
+ onEnd;
810
+ parentSpanId;
811
+ parentSpanContext;
812
+ kind;
813
+ attributes;
814
+ status = {
815
+ code: SpanStatusCode.UNSET
816
+ };
817
+ endTime = [0, 0];
818
+ _duration = [0, 0];
819
+ startTime;
820
+ events = [];
821
+ links;
822
+ resource;
823
+ instrumentationScope = { name: "@inference-net/otel-cf-workers" };
824
+ _ended = false;
825
+ _droppedAttributesCount = 0;
826
+ _droppedEventsCount = 0;
827
+ _droppedLinksCount = 0;
828
+ constructor(init) {
829
+ this.name = init.name;
830
+ this._spanContext = init.spanContext;
831
+ this.parentSpanId = init.parentSpanId;
832
+ this.parentSpanContext = init.parentSpanContext;
833
+ this.kind = init.spanKind || SpanKind.INTERNAL;
834
+ this.attributes = sanitizeAttributes(init.attributes);
835
+ this.startTime = getHrTime$1(init.startTime);
836
+ this.links = init.links || [];
837
+ this.resource = init.resource;
838
+ this.onEnd = init.onEnd;
839
+ }
840
+ addLink(link) {
841
+ this.links.push(link);
842
+ return this;
843
+ }
844
+ addLinks(links) {
845
+ this.links.push(...links);
846
+ return this;
847
+ }
848
+ spanContext() {
849
+ return this._spanContext;
850
+ }
851
+ setAttribute(key, value) {
852
+ if (isAttributeKey(key) && isAttributeValue(value)) {
853
+ this.attributes[key] = value;
854
+ }
855
+ return this;
856
+ }
857
+ setAttributes(attributes) {
858
+ for (const [key, value] of Object.entries(attributes)) {
859
+ this.setAttribute(key, value);
860
+ }
861
+ return this;
862
+ }
863
+ addEvent(name, attributesOrStartTime, startTime) {
864
+ if (isTimeInput(attributesOrStartTime)) {
865
+ startTime = attributesOrStartTime;
866
+ attributesOrStartTime = void 0;
867
+ }
868
+ const attributes = sanitizeAttributes(attributesOrStartTime);
869
+ const time = getHrTime$1(startTime);
870
+ this.events.push({ name, attributes, time });
871
+ return this;
872
+ }
873
+ setStatus(status) {
874
+ this.status = status;
875
+ return this;
876
+ }
877
+ updateName(name) {
878
+ this.name = name;
879
+ return this;
880
+ }
881
+ end(endTime) {
882
+ if (this._ended) {
883
+ return;
884
+ }
885
+ this._ended = true;
886
+ this.endTime = getHrTime$1(endTime);
887
+ this._duration = hrTimeDuration(this.startTime, this.endTime);
888
+ this.onEnd(this);
889
+ }
890
+ isRecording() {
891
+ return !this._ended;
892
+ }
893
+ recordException(exception, time) {
894
+ const attributes = transformExceptionAttributes(exception);
895
+ this.addEvent("exception", attributes, time);
896
+ }
897
+ get duration() {
898
+ return this._duration;
899
+ }
900
+ get ended() {
901
+ return this._ended;
902
+ }
903
+ get droppedAttributesCount() {
904
+ return this._droppedAttributesCount;
905
+ }
906
+ get droppedEventsCount() {
907
+ return this._droppedEventsCount;
908
+ }
909
+ get droppedLinksCount() {
910
+ return this._droppedLinksCount;
911
+ }
912
+ }
913
+
914
+ const idGenerator = new RandomIdGenerator();
915
+ let withNextSpanAttributes;
916
+ function getFlagAt(flagSequence, position) {
917
+ return (flagSequence >> position - 1 & 1) * position;
918
+ }
919
+ class WorkerTracer {
920
+ spanProcessors;
921
+ resource;
922
+ constructor(spanProcessors, resource) {
923
+ this.spanProcessors = spanProcessors;
924
+ this.resource = resource;
925
+ }
926
+ async forceFlush(traceId) {
927
+ const promises = this.spanProcessors.map(async (spanProcessor) => {
928
+ await spanProcessor.forceFlush(traceId);
929
+ });
930
+ await Promise.allSettled(promises);
931
+ }
932
+ addToResource(extra) {
933
+ this.resource.merge(extra);
934
+ }
935
+ startSpan(name, options = {}, context$1 = context.active()) {
936
+ if (options.root) {
937
+ context$1 = trace.deleteSpan(context$1);
938
+ }
939
+ const config = getActiveConfig();
940
+ if (!config) throw new Error("Config is undefined. This is a bug in the instrumentation logic");
941
+ const parentSpanContext = trace.getSpan(context$1)?.spanContext();
942
+ const { traceId, randomTraceFlag } = getTraceInfo(parentSpanContext);
943
+ const spanKind = options.kind || SpanKind.INTERNAL;
944
+ const sanitisedAttrs = sanitizeAttributes(options.attributes);
945
+ const sampler = config.sampling.headSampler;
946
+ const samplingDecision = sampler.shouldSample(context$1, traceId, name, spanKind, sanitisedAttrs, []);
947
+ const { decision, traceState, attributes: attrs } = samplingDecision;
948
+ const attributes = Object.assign({}, options.attributes, attrs, withNextSpanAttributes);
949
+ withNextSpanAttributes = {};
950
+ const spanId = idGenerator.generateSpanId();
951
+ const parentSpanId = parentSpanContext?.spanId;
952
+ const sampleFlag = decision === SamplingDecision.RECORD_AND_SAMPLED ? TraceFlags.SAMPLED : TraceFlags.NONE;
953
+ const traceFlags = sampleFlag + randomTraceFlag;
954
+ const spanContext = { traceId, spanId, traceFlags, traceState };
955
+ const span = new SpanImpl({
956
+ attributes: sanitizeAttributes(attributes),
957
+ name,
958
+ onEnd: (span2) => {
959
+ this.spanProcessors.forEach((sp) => {
960
+ sp.onEnd(span2);
961
+ });
962
+ },
963
+ resource: this.resource,
964
+ spanContext,
965
+ parentSpanContext,
966
+ parentSpanId,
967
+ spanKind,
968
+ startTime: options.startTime
969
+ });
970
+ this.spanProcessors.forEach((sp) => {
971
+ sp.onStart(span, context$1);
972
+ });
973
+ return span;
974
+ }
975
+ startActiveSpan(name, ...args) {
976
+ const options = args.length > 1 ? args[0] : void 0;
977
+ const parentContext = args.length > 2 ? args[1] : context.active();
978
+ const fn = args[args.length - 1];
979
+ const span = this.startSpan(name, options, parentContext);
980
+ const contextWithSpanSet = trace.setSpan(parentContext, span);
981
+ return context.with(contextWithSpanSet, fn, void 0, span);
982
+ }
983
+ }
984
+ function withNextSpan(attrs) {
985
+ withNextSpanAttributes = Object.assign({}, withNextSpanAttributes, attrs);
986
+ }
987
+ function getTraceInfo(parentSpanContext) {
988
+ if (parentSpanContext && trace.isSpanContextValid(parentSpanContext)) {
989
+ const { traceId, traceFlags } = parentSpanContext;
990
+ return { traceId, randomTraceFlag: getFlagAt(traceFlags, 2) };
991
+ } else {
992
+ return { traceId: idGenerator.generateTraceId(), randomTraceFlag: 2 /* RANDOM_TRACE_ID_SET */ };
993
+ }
994
+ }
995
+
996
+ class WorkerTracerProvider {
997
+ spanProcessors;
998
+ resource;
999
+ tracers = {};
1000
+ constructor(spanProcessors, resource) {
1001
+ this.spanProcessors = spanProcessors;
1002
+ this.resource = resource;
1003
+ }
1004
+ getTracer(name, version, options) {
1005
+ const key = `${name}@${version || ""}:${options?.schemaUrl || ""}`;
1006
+ if (!this.tracers[key]) {
1007
+ this.tracers[key] = new WorkerTracer(this.spanProcessors, this.resource);
1008
+ }
1009
+ return this.tracers[key];
1010
+ }
1011
+ register() {
1012
+ trace.setGlobalTracerProvider(this);
1013
+ context.setGlobalContextManager(new AsyncLocalStorageContextManager());
1014
+ }
1015
+ }
1016
+
1017
+ function millisToHr(millis) {
1018
+ return [Math.trunc(millis / 1e3), millis % 1e3 * 1e6];
1019
+ }
1020
+ function getHrTime(input) {
1021
+ const now = Date.now();
1022
+ if (!input) {
1023
+ return millisToHr(now);
1024
+ } else if (input instanceof Date) {
1025
+ return millisToHr(input.getTime());
1026
+ } else if (typeof input === "number") {
1027
+ return millisToHr(input);
1028
+ } else if (Array.isArray(input)) {
1029
+ return input;
1030
+ }
1031
+ const v = input;
1032
+ throw new Error(`unreachable value: ${JSON.stringify(v)}`);
1033
+ }
1034
+ class LogRecordImpl {
1035
+ timeUnixNano;
1036
+ observedTimeUnixNano;
1037
+ severityNumber;
1038
+ severityText;
1039
+ body;
1040
+ attributes;
1041
+ traceId;
1042
+ spanId;
1043
+ traceFlags;
1044
+ resource;
1045
+ instrumentationScope;
1046
+ droppedAttributesCount = 0;
1047
+ constructor(init) {
1048
+ this.timeUnixNano = getHrTime(init.timestamp);
1049
+ this.observedTimeUnixNano = getHrTime(init.observedTimestamp);
1050
+ this.severityNumber = init.severityNumber;
1051
+ this.severityText = init.severityText;
1052
+ this.body = init.body;
1053
+ this.attributes = sanitizeAttributes(init.attributes || {});
1054
+ this.resource = init.resource;
1055
+ this.instrumentationScope = init.instrumentationScope || {
1056
+ name: "@inference-net/otel-cf-workers"
1057
+ };
1058
+ const activeSpan = trace.getActiveSpan();
1059
+ if (activeSpan && !init.traceId) {
1060
+ const spanContext = activeSpan.spanContext();
1061
+ this.traceId = spanContext.traceId;
1062
+ this.spanId = spanContext.spanId;
1063
+ this.traceFlags = spanContext.traceFlags;
1064
+ } else {
1065
+ this.traceId = init.traceId;
1066
+ this.spanId = init.spanId;
1067
+ this.traceFlags = init.traceFlags;
1068
+ }
1069
+ }
1070
+ }
1071
+
1072
+ class WorkerLogger {
1073
+ processors;
1074
+ resource;
1075
+ name;
1076
+ version;
1077
+ inheritedAttributes;
1078
+ constructor(name, processors, resource, version, inheritedAttributes) {
1079
+ this.name = name;
1080
+ this.processors = processors;
1081
+ this.resource = resource;
1082
+ this.version = version;
1083
+ this.inheritedAttributes = inheritedAttributes || {};
1084
+ }
1085
+ emit(logRecord) {
1086
+ const mergedAttributes = {
1087
+ ...this.inheritedAttributes,
1088
+ ...logRecord.attributes || {}
1089
+ };
1090
+ const record = new LogRecordImpl({
1091
+ ...logRecord,
1092
+ attributes: mergedAttributes,
1093
+ resource: this.resource,
1094
+ instrumentationScope: {
1095
+ name: this.name,
1096
+ version: this.version
1097
+ }
1098
+ });
1099
+ const context$1 = context.active();
1100
+ this.processors.forEach((processor) => {
1101
+ processor.onEmit(record, context$1);
1102
+ });
1103
+ }
1104
+ trace(message, attributes) {
1105
+ this.emit({
1106
+ severityNumber: SEVERITY_NUMBERS.TRACE,
1107
+ severityText: "TRACE",
1108
+ body: message,
1109
+ attributes
1110
+ });
1111
+ }
1112
+ debug(message, attributes) {
1113
+ this.emit({
1114
+ severityNumber: SEVERITY_NUMBERS.DEBUG,
1115
+ severityText: "DEBUG",
1116
+ body: message,
1117
+ attributes
1118
+ });
1119
+ }
1120
+ info(message, attributes) {
1121
+ this.emit({
1122
+ severityNumber: SEVERITY_NUMBERS.INFO,
1123
+ severityText: "INFO",
1124
+ body: message,
1125
+ attributes
1126
+ });
1127
+ }
1128
+ warn(message, attributes) {
1129
+ this.emit({
1130
+ severityNumber: SEVERITY_NUMBERS.WARN,
1131
+ severityText: "WARN",
1132
+ body: message,
1133
+ attributes
1134
+ });
1135
+ }
1136
+ error(message, attributes) {
1137
+ let body;
1138
+ let attrs = { ...attributes };
1139
+ if (message instanceof Error) {
1140
+ body = message.message;
1141
+ attrs = {
1142
+ ...attrs,
1143
+ "exception.type": message.name,
1144
+ "exception.message": message.message,
1145
+ "exception.stacktrace": message.stack
1146
+ };
1147
+ } else {
1148
+ body = message;
1149
+ }
1150
+ this.emit({
1151
+ severityNumber: SEVERITY_NUMBERS.ERROR,
1152
+ severityText: "ERROR",
1153
+ body,
1154
+ attributes: attrs
1155
+ });
1156
+ }
1157
+ fatal(message, attributes) {
1158
+ this.emit({
1159
+ severityNumber: SEVERITY_NUMBERS.FATAL,
1160
+ severityText: "FATAL",
1161
+ body: message,
1162
+ attributes
1163
+ });
1164
+ }
1165
+ async forceFlush() {
1166
+ const promises = this.processors.map((p) => p.forceFlush());
1167
+ await Promise.allSettled(promises);
1168
+ }
1169
+ /**
1170
+ * Create a child logger that inherits attributes from this logger
1171
+ * Child attributes are merged with parent attributes (child takes precedence)
1172
+ */
1173
+ child(attributes) {
1174
+ const mergedAttributes = {
1175
+ ...this.inheritedAttributes,
1176
+ ...attributes
1177
+ };
1178
+ return new WorkerLogger(this.name, this.processors, this.resource, this.version, mergedAttributes);
1179
+ }
1180
+ }
1181
+
1182
+ let globalLoggerProvider;
1183
+ function setGlobalLoggerProvider(provider) {
1184
+ globalLoggerProvider = provider;
1185
+ }
1186
+ function getGlobalLoggerProvider() {
1187
+ return globalLoggerProvider || new NoopLoggerProvider();
1188
+ }
1189
+ class WorkerLoggerProvider {
1190
+ loggers = /* @__PURE__ */ new Map();
1191
+ processors;
1192
+ resource;
1193
+ constructor(processors, resource) {
1194
+ this.processors = processors;
1195
+ this.resource = resource;
1196
+ }
1197
+ getLogger(name, version, options) {
1198
+ const key = `${name}@${version || ""}:${options?.schemaUrl || ""}`;
1199
+ if (!this.loggers.has(key)) {
1200
+ this.loggers.set(key, new WorkerLogger(name, this.processors, this.resource, version));
1201
+ }
1202
+ return this.loggers.get(key);
1203
+ }
1204
+ register() {
1205
+ setGlobalLoggerProvider(this);
1206
+ }
1207
+ async shutdown() {
1208
+ await Promise.allSettled(this.processors.map((p) => p.shutdown()));
1209
+ }
1210
+ }
1211
+ class NoopLogger {
1212
+ emit() {
1213
+ }
1214
+ trace() {
1215
+ }
1216
+ debug() {
1217
+ }
1218
+ info() {
1219
+ }
1220
+ warn() {
1221
+ }
1222
+ error() {
1223
+ }
1224
+ fatal() {
1225
+ }
1226
+ async forceFlush() {
1227
+ }
1228
+ child() {
1229
+ return this;
1230
+ }
1231
+ }
1232
+ class NoopLoggerProvider {
1233
+ logger = new NoopLogger();
1234
+ getLogger() {
1235
+ return this.logger;
1236
+ }
1237
+ register() {
1238
+ }
1239
+ async shutdown() {
1240
+ }
1241
+ }
1242
+ function getLogger(name, version, options) {
1243
+ return getGlobalLoggerProvider().getLogger(name, version, options);
1244
+ }
1245
+
1246
+ const provider = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1247
+ __proto__: null,
1248
+ WorkerLoggerProvider,
1249
+ getGlobalLoggerProvider,
1250
+ getLogger,
1251
+ setGlobalLoggerProvider
1252
+ }, Symbol.toStringTag, { value: 'Module' }));
1253
+
1254
+ function isValidAttributeValue(value) {
1255
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1256
+ }
1257
+ function gatherUserAgentAttributes(request) {
1258
+ const attrs = {};
1259
+ if (!request.cf) {
1260
+ return attrs;
1261
+ }
1262
+ const cfData = request.cf;
1263
+ if (cfData["browser"]) {
1264
+ const browser = cfData["browser"];
1265
+ if (isValidAttributeValue(browser["name"])) attrs[ATTR_USER_AGENT_BROWSER_NAME] = browser["name"];
1266
+ if (isValidAttributeValue(browser["version"])) attrs[ATTR_USER_AGENT_BROWSER_VERSION] = browser["version"];
1267
+ if (isValidAttributeValue(browser["major"])) attrs[ATTR_USER_AGENT_BROWSER_MAJOR_VERSION] = browser["major"];
1268
+ }
1269
+ if (cfData["os"]) {
1270
+ const os = cfData["os"];
1271
+ if (isValidAttributeValue(os["name"])) attrs[ATTR_USER_AGENT_OS_NAME] = os["name"];
1272
+ if (isValidAttributeValue(os["version"])) attrs[ATTR_USER_AGENT_OS_VERSION] = os["version"];
1273
+ }
1274
+ if (cfData["engine"]) {
1275
+ const engine = cfData["engine"];
1276
+ if (isValidAttributeValue(engine["name"])) attrs[ATTR_USER_AGENT_ENGINE_NAME] = engine["name"];
1277
+ if (isValidAttributeValue(engine["version"])) attrs[ATTR_USER_AGENT_ENGINE_VERSION] = engine["version"];
1278
+ }
1279
+ if (cfData["device"]) {
1280
+ const device = cfData["device"];
1281
+ if (isValidAttributeValue(device["type"])) attrs[ATTR_USER_AGENT_DEVICE_TYPE] = device["type"];
1282
+ if (isValidAttributeValue(device["vendor"])) attrs[ATTR_USER_AGENT_DEVICE_VENDOR] = device["vendor"];
1283
+ if (isValidAttributeValue(device["model"])) attrs[ATTR_USER_AGENT_DEVICE_MODEL] = device["model"];
1284
+ }
1285
+ return attrs;
1286
+ }
1287
+
1288
+ function gatherRootSpanAttributes(request, handlerType, executionModel = "stateless") {
1289
+ const attrs = {
1290
+ [ATTR_CLOUDFLARE_HANDLER_TYPE]: handlerType,
1291
+ [ATTR_CLOUDFLARE_EXECUTION_MODEL]: executionModel
1292
+ };
1293
+ const rayId = request.headers?.get("cf-ray");
1294
+ if (rayId) {
1295
+ attrs[ATTR_CLOUDFLARE_RAY_ID] = rayId;
1296
+ }
1297
+ if (request.cf?.colo) {
1298
+ attrs[ATTR_CLOUDFLARE_COLO] = request.cf.colo;
1299
+ }
1300
+ return attrs;
1301
+ }
1302
+
1303
+ const netKeysFromCF = /* @__PURE__ */ new Set(["colo", "country", "request_priority", "tls_cipher", "tls_version", "asn", "tcp_rtt"]);
1304
+ const camelToSnakeCase = (s) => {
1305
+ return s.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
1306
+ };
1307
+ const gatherOutgoingCfAttributes = (cf) => {
1308
+ const attrs = {};
1309
+ Object.keys(cf).forEach((key) => {
1310
+ const value = cf[key];
1311
+ const destKey = camelToSnakeCase(key);
1312
+ if (!netKeysFromCF.has(destKey)) {
1313
+ if (typeof value === "string" || typeof value === "number") {
1314
+ attrs[`cf.${destKey}`] = value;
1315
+ } else {
1316
+ attrs[`cf.${destKey}`] = JSON.stringify(value);
1317
+ }
1318
+ }
1319
+ });
1320
+ return attrs;
1321
+ };
1322
+ function gatherRequestAttributes(request) {
1323
+ const attrs = {};
1324
+ const headers = request.headers;
1325
+ attrs["http.request.method"] = request.method.toUpperCase();
1326
+ attrs["network.protocol.name"] = "http";
1327
+ if (request.cf?.httpProtocol) {
1328
+ attrs["network.protocol.version"] = request.cf.httpProtocol;
1329
+ }
1330
+ const contentLength = headers.get("content-length");
1331
+ if (contentLength) {
1332
+ attrs["http.request.body.size"] = parseInt(contentLength, 10);
1333
+ attrs[ATTR_HTTP_REQUEST_HEADER_CONTENT_LENGTH] = contentLength;
1334
+ }
1335
+ const userAgent = headers.get("user-agent");
1336
+ if (userAgent) attrs["user_agent.original"] = userAgent;
1337
+ const contentType = headers.get("content-type");
1338
+ if (contentType) {
1339
+ attrs["http.mime_type"] = contentType;
1340
+ attrs[ATTR_HTTP_REQUEST_HEADER_CONTENT_TYPE] = contentType;
1341
+ }
1342
+ const accept = headers.get("accept");
1343
+ if (accept) attrs[ATTR_HTTP_REQUEST_HEADER_ACCEPT] = accept;
1344
+ const acceptEncoding = headers.get("accept-encoding");
1345
+ if (acceptEncoding) {
1346
+ attrs["http.accepts"] = acceptEncoding;
1347
+ attrs[ATTR_HTTP_REQUEST_HEADER_ACCEPT_ENCODING] = acceptEncoding;
1348
+ }
1349
+ const acceptLanguage = headers.get("accept-language");
1350
+ if (acceptLanguage) attrs[ATTR_HTTP_REQUEST_HEADER_ACCEPT_LANGUAGE] = acceptLanguage;
1351
+ const u = new URL(request.url);
1352
+ attrs["url.full"] = `${u.protocol}//${u.host}${u.pathname}${u.search}`;
1353
+ attrs["server.address"] = u.host;
1354
+ attrs["url.scheme"] = u.protocol.replace(":", "");
1355
+ attrs["url.path"] = u.pathname;
1356
+ if (u.search) attrs["url.query"] = u.search;
1357
+ if (u.port) {
1358
+ attrs["server.port"] = parseInt(u.port, 10);
1359
+ } else {
1360
+ attrs["server.port"] = u.protocol === "https:" ? 443 : 80;
1361
+ }
1362
+ return attrs;
1363
+ }
1364
+ function gatherResponseAttributes(response) {
1365
+ const attrs = {};
1366
+ attrs["http.response.status_code"] = response.status;
1367
+ if (response.headers.get("content-length") == null) {
1368
+ attrs["http.response.body.size"] = response.headers.get("content-length");
1369
+ }
1370
+ attrs["http.mime_type"] = response.headers.get("content-type");
1371
+ return attrs;
1372
+ }
1373
+ function gatherIncomingCfAttributes(request) {
1374
+ const attrs = {};
1375
+ if (!request.cf) {
1376
+ return attrs;
1377
+ }
1378
+ if (request.cf.colo) attrs["net.colo"] = request.cf.colo;
1379
+ if (request.cf.country) attrs["net.country"] = request.cf.country;
1380
+ if (request.cf.requestPriority) attrs["net.request_priority"] = request.cf.requestPriority;
1381
+ if (request.cf.tlsCipher) attrs["net.tls_cipher"] = request.cf.tlsCipher;
1382
+ if (request.cf.tlsVersion) attrs["net.tls_version"] = request.cf.tlsVersion;
1383
+ if (request.cf.asn) attrs[ATTR_CLOUDFLARE_ASN] = request.cf.asn;
1384
+ if (request.cf.clientTcpRtt) attrs["net.tcp_rtt"] = request.cf.clientTcpRtt;
1385
+ if (request.cf.timezone) attrs[ATTR_GEO_TIMEZONE] = request.cf.timezone;
1386
+ if (request.cf.continent) attrs[ATTR_GEO_CONTINENT_CODE] = request.cf.continent;
1387
+ if (request.cf.country) attrs[ATTR_GEO_COUNTRY_CODE] = request.cf.country;
1388
+ if (request.cf.city) attrs[ATTR_GEO_LOCALITY_NAME] = request.cf.city;
1389
+ if (request.cf.region) attrs[ATTR_GEO_LOCALITY_REGION] = request.cf.region;
1390
+ if (request.cf.verifiedBotCategory) attrs[ATTR_CLOUDFLARE_VERIFIED_BOT_CATEGORY] = request.cf.verifiedBotCategory;
1391
+ return attrs;
1392
+ }
1393
+ function getParentContextFromHeaders(headers) {
1394
+ return propagation.extract(context.active(), headers, {
1395
+ get(headers2, key) {
1396
+ return headers2.get(key) || void 0;
1397
+ },
1398
+ keys(headers2) {
1399
+ return [...headers2.keys()];
1400
+ }
1401
+ });
1402
+ }
1403
+ function getParentContextFromRequest(request) {
1404
+ const workerConfig = getActiveConfig();
1405
+ if (workerConfig === void 0) {
1406
+ return context.active();
1407
+ }
1408
+ const acceptTraceContext = typeof workerConfig.handlers.fetch.acceptTraceContext === "function" ? workerConfig.handlers.fetch.acceptTraceContext(request) : workerConfig.handlers.fetch.acceptTraceContext ?? true;
1409
+ return acceptTraceContext ? getParentContextFromHeaders(request.headers) : context.active();
1410
+ }
1411
+ function updateSpanNameOnRoute(span, request) {
1412
+ const readable = span;
1413
+ if (readable.attributes["http.route"]) {
1414
+ const method = request.method.toUpperCase();
1415
+ span.updateName(`${method} ${readable.attributes["http.route"]}`);
1416
+ }
1417
+ }
1418
+ const fetchInstrumentation = {
1419
+ getInitialSpanInfo: (request) => {
1420
+ const spanContext = getParentContextFromRequest(request);
1421
+ const attributes = {
1422
+ ["faas.trigger"]: "http",
1423
+ ["faas.invocation_id"]: request.headers.get("cf-ray") ?? void 0
1424
+ };
1425
+ Object.assign(attributes, gatherRequestAttributes(request));
1426
+ Object.assign(attributes, gatherIncomingCfAttributes(request));
1427
+ Object.assign(attributes, gatherRootSpanAttributes(request, "fetch"));
1428
+ Object.assign(attributes, gatherUserAgentAttributes(request));
1429
+ const method = request.method.toUpperCase();
1430
+ return {
1431
+ name: `fetchHandler ${method}`,
1432
+ options: {
1433
+ attributes,
1434
+ kind: SpanKind.SERVER
1435
+ },
1436
+ context: spanContext
1437
+ };
1438
+ },
1439
+ getAttributesFromResult: (response) => {
1440
+ return gatherResponseAttributes(response);
1441
+ },
1442
+ executionSucces: updateSpanNameOnRoute,
1443
+ executionFailed: updateSpanNameOnRoute
1444
+ };
1445
+ function instrumentClientFetch(fetchFn, configFn, attrs) {
1446
+ const handler = {
1447
+ apply: (target, thisArg, argArray) => {
1448
+ const request = new Request(argArray[0], argArray[1]);
1449
+ if (!request.url.startsWith("http")) {
1450
+ return Reflect.apply(target, thisArg, argArray);
1451
+ }
1452
+ const workerConfig = getActiveConfig();
1453
+ if (!workerConfig) {
1454
+ return Reflect.apply(target, thisArg, [request]);
1455
+ }
1456
+ const config = configFn(workerConfig);
1457
+ const tracer = trace.getTracer("fetcher");
1458
+ const options = { kind: SpanKind.CLIENT, attributes: attrs };
1459
+ const host = new URL(request.url).host;
1460
+ const method = request.method.toUpperCase();
1461
+ const spanName = typeof attrs?.["name"] === "string" ? attrs?.["name"] : `fetch ${method} ${host}`;
1462
+ const promise = tracer.startActiveSpan(spanName, options, async (span) => {
1463
+ try {
1464
+ const includeTraceContext = typeof config.includeTraceContext === "function" ? config.includeTraceContext(request) : config.includeTraceContext;
1465
+ if (includeTraceContext ?? true) {
1466
+ propagation.inject(context.active(), request.headers, {
1467
+ set: (h, k, v) => h.set(k, typeof v === "string" ? v : String(v))
1468
+ });
1469
+ }
1470
+ span.setAttributes(gatherRequestAttributes(request));
1471
+ if (request.cf) span.setAttributes(gatherOutgoingCfAttributes(request.cf));
1472
+ const response = await Reflect.apply(target, thisArg, [request]);
1473
+ span.setAttributes(gatherResponseAttributes(response));
1474
+ return response;
1475
+ } catch (error) {
1476
+ span.recordException(error);
1477
+ span.setStatus({ code: SpanStatusCode.ERROR });
1478
+ throw error;
1479
+ } finally {
1480
+ span.end();
1481
+ }
1482
+ });
1483
+ return promise;
1484
+ }
1485
+ };
1486
+ return wrap(fetchFn, handler, true);
1487
+ }
1488
+ function instrumentGlobalFetch() {
1489
+ globalThis.fetch = instrumentClientFetch(globalThis.fetch, (config) => config.fetch);
1490
+ }
1491
+
1492
+ const tracer = trace.getTracer("cache instrumentation");
1493
+ function sanitiseURL(url) {
1494
+ const u = new URL(url);
1495
+ return `${u.protocol}//${u.host}${u.pathname}${u.search}`;
1496
+ }
1497
+ function instrumentFunction(fn, cacheName, op) {
1498
+ const handler = {
1499
+ async apply(target, thisArg, argArray) {
1500
+ const attributes = {
1501
+ "cache.name": cacheName,
1502
+ "http.url": argArray[0].url ? sanitiseURL(argArray[0].url) : void 0,
1503
+ "cache.operation": op
1504
+ };
1505
+ const options = { kind: SpanKind.CLIENT, attributes };
1506
+ return tracer.startActiveSpan(`Cache ${cacheName} ${op}`, options, async (span) => {
1507
+ const result = await Reflect.apply(target, thisArg, argArray);
1508
+ if (op === "match") {
1509
+ span.setAttribute("cache.hit", !!result);
1510
+ }
1511
+ span.end();
1512
+ return result;
1513
+ });
1514
+ }
1515
+ };
1516
+ return wrap(fn, handler);
1517
+ }
1518
+ function instrumentCache(cache, cacheName) {
1519
+ const handler = {
1520
+ get(target, prop) {
1521
+ if (prop === "delete" || prop === "match" || prop === "put") {
1522
+ const fn = Reflect.get(target, prop).bind(target);
1523
+ return instrumentFunction(fn, cacheName, prop);
1524
+ } else {
1525
+ return Reflect.get(target, prop);
1526
+ }
1527
+ }
1528
+ };
1529
+ return wrap(cache, handler);
1530
+ }
1531
+ function instrumentOpen(openFn) {
1532
+ const handler = {
1533
+ async apply(target, thisArg, argArray) {
1534
+ const cacheName = argArray[0];
1535
+ const cache = await Reflect.apply(target, thisArg, argArray);
1536
+ return instrumentCache(cache, cacheName);
1537
+ }
1538
+ };
1539
+ return wrap(openFn, handler);
1540
+ }
1541
+ function _instrumentGlobalCache() {
1542
+ const handler = {
1543
+ get(target, prop) {
1544
+ if (prop === "default") {
1545
+ const cache = target.default;
1546
+ return instrumentCache(cache, "default");
1547
+ } else if (prop === "open") {
1548
+ const openFn = Reflect.get(target, prop).bind(target);
1549
+ return instrumentOpen(openFn);
1550
+ } else {
1551
+ return Reflect.get(target, prop);
1552
+ }
1553
+ }
1554
+ };
1555
+ globalThis.caches = wrap(caches, handler);
1556
+ }
1557
+ function instrumentGlobalCache() {
1558
+ return _instrumentGlobalCache();
1559
+ }
1560
+
1561
+ class MessageStatusCount {
1562
+ succeeded = 0;
1563
+ failed = 0;
1564
+ implicitly_acked = 0;
1565
+ implicitly_retried = 0;
1566
+ total;
1567
+ constructor(total) {
1568
+ this.total = total;
1569
+ }
1570
+ ack() {
1571
+ this.succeeded = this.succeeded + 1;
1572
+ }
1573
+ ackRemaining() {
1574
+ this.implicitly_acked = this.total - this.succeeded - this.failed;
1575
+ this.succeeded = this.total - this.failed;
1576
+ }
1577
+ retry() {
1578
+ this.failed = this.failed + 1;
1579
+ }
1580
+ retryRemaining() {
1581
+ this.implicitly_retried = this.total - this.succeeded - this.failed;
1582
+ this.failed = this.total - this.succeeded;
1583
+ }
1584
+ toAttributes() {
1585
+ return {
1586
+ "queue.messages_count": this.total,
1587
+ "queue.messages_success": this.succeeded,
1588
+ "queue.messages_failed": this.failed,
1589
+ "queue.batch_success": this.succeeded === this.total,
1590
+ "queue.implicitly_acked": this.implicitly_acked,
1591
+ "queue.implicitly_retried": this.implicitly_retried
1592
+ };
1593
+ }
1594
+ }
1595
+ const addEvent = (name, msg) => {
1596
+ const attrs = {};
1597
+ if (msg) {
1598
+ attrs["queue.message_id"] = msg.id;
1599
+ attrs["queue.message_timestamp"] = msg.timestamp.toISOString();
1600
+ }
1601
+ trace.getActiveSpan()?.addEvent(name, attrs);
1602
+ };
1603
+ const proxyQueueMessage = (msg, count) => {
1604
+ const msgHandler = {
1605
+ get: (target, prop) => {
1606
+ if (prop === "ack") {
1607
+ const ackFn = Reflect.get(target, prop);
1608
+ return new Proxy(ackFn, {
1609
+ apply: (fnTarget) => {
1610
+ addEvent("messageAck", msg);
1611
+ count.ack();
1612
+ Reflect.apply(fnTarget, msg, []);
1613
+ }
1614
+ });
1615
+ } else if (prop === "retry") {
1616
+ const retryFn = Reflect.get(target, prop);
1617
+ return new Proxy(retryFn, {
1618
+ apply: (fnTarget) => {
1619
+ addEvent("messageRetry", msg);
1620
+ count.retry();
1621
+ const result = Reflect.apply(fnTarget, msg, []);
1622
+ return result;
1623
+ }
1624
+ });
1625
+ } else {
1626
+ return Reflect.get(target, prop, msg);
1627
+ }
1628
+ }
1629
+ };
1630
+ return wrap(msg, msgHandler);
1631
+ };
1632
+ const proxyMessageBatch = (batch, count) => {
1633
+ const batchHandler = {
1634
+ get: (target, prop) => {
1635
+ if (prop === "messages") {
1636
+ const messages = Reflect.get(target, prop);
1637
+ const messagesHandler = {
1638
+ get: (target2, prop2) => {
1639
+ if (typeof prop2 === "string" && !isNaN(parseInt(prop2))) {
1640
+ const message = Reflect.get(target2, prop2);
1641
+ return proxyQueueMessage(message, count);
1642
+ } else {
1643
+ return Reflect.get(target2, prop2);
1644
+ }
1645
+ }
1646
+ };
1647
+ return wrap(messages, messagesHandler);
1648
+ } else if (prop === "ackAll") {
1649
+ const ackFn = Reflect.get(target, prop);
1650
+ return new Proxy(ackFn, {
1651
+ apply: (fnTarget) => {
1652
+ addEvent("ackAll");
1653
+ count.ackRemaining();
1654
+ Reflect.apply(fnTarget, batch, []);
1655
+ }
1656
+ });
1657
+ } else if (prop === "retryAll") {
1658
+ const retryFn = Reflect.get(target, prop);
1659
+ return new Proxy(retryFn, {
1660
+ apply: (fnTarget) => {
1661
+ addEvent("retryAll");
1662
+ count.retryRemaining();
1663
+ Reflect.apply(fnTarget, batch, []);
1664
+ }
1665
+ });
1666
+ }
1667
+ return Reflect.get(target, prop);
1668
+ }
1669
+ };
1670
+ return wrap(batch, batchHandler);
1671
+ };
1672
+ class QueueInstrumentation {
1673
+ count;
1674
+ getInitialSpanInfo(batch) {
1675
+ return {
1676
+ name: `queueHandler ${batch.queue}`,
1677
+ options: {
1678
+ attributes: {
1679
+ [ATTR_FAAS_TRIGGER]: FAAS_TRIGGER_VALUE_PUBSUB,
1680
+ [ATTR_CLOUDFLARE_QUEUE_NAME]: batch.queue,
1681
+ [ATTR_CLOUDFLARE_QUEUE_BATCH_SIZE]: batch.messages.length
1682
+ },
1683
+ kind: SpanKind.CONSUMER
1684
+ }
1685
+ };
1686
+ }
1687
+ instrumentTrigger(batch) {
1688
+ this.count = new MessageStatusCount(batch.messages.length);
1689
+ return proxyMessageBatch(batch, this.count);
1690
+ }
1691
+ executionSucces(span) {
1692
+ if (this.count) {
1693
+ this.count.ackRemaining();
1694
+ span.setAttributes(this.count.toAttributes());
1695
+ }
1696
+ }
1697
+ executionFailed(span) {
1698
+ if (this.count) {
1699
+ this.count.retryRemaining();
1700
+ span.setAttributes(this.count.toAttributes());
1701
+ }
1702
+ }
1703
+ }
1704
+ function instrumentQueueSend(fn, name) {
1705
+ const tracer = trace.getTracer("queueSender");
1706
+ const handler = {
1707
+ apply: (target, thisArg, argArray) => {
1708
+ return tracer.startActiveSpan(`Queues ${name} send`, async (span) => {
1709
+ span.setAttribute("queue.operation", "send");
1710
+ await Reflect.apply(target, unwrap(thisArg), argArray);
1711
+ span.end();
1712
+ });
1713
+ }
1714
+ };
1715
+ return wrap(fn, handler);
1716
+ }
1717
+ function instrumentQueueSendBatch(fn, name) {
1718
+ const tracer = trace.getTracer("queueSender");
1719
+ const handler = {
1720
+ apply: (target, thisArg, argArray) => {
1721
+ return tracer.startActiveSpan(`Queues ${name} sendBatch`, async (span) => {
1722
+ span.setAttribute("queue.operation", "sendBatch");
1723
+ await Reflect.apply(target, unwrap(thisArg), argArray);
1724
+ span.end();
1725
+ });
1726
+ }
1727
+ };
1728
+ return wrap(fn, handler);
1729
+ }
1730
+ function instrumentQueueSender(queue, name) {
1731
+ const queueHandler = {
1732
+ get: (target, prop) => {
1733
+ if (prop === "send") {
1734
+ const sendFn = Reflect.get(target, prop);
1735
+ return instrumentQueueSend(sendFn, name);
1736
+ } else if (prop === "sendBatch") {
1737
+ const sendFn = Reflect.get(target, prop);
1738
+ return instrumentQueueSendBatch(sendFn, name);
1739
+ } else {
1740
+ return Reflect.get(target, prop);
1741
+ }
1742
+ }
1743
+ };
1744
+ return wrap(queue, queueHandler);
1745
+ }
1746
+
1747
+ const dbSystem$4 = "Cloudflare KV";
1748
+ const KVAttributes = {
1749
+ delete(_argArray) {
1750
+ return {};
1751
+ },
1752
+ get(argArray) {
1753
+ const attrs = {};
1754
+ const opts = argArray[1];
1755
+ if (typeof opts === "string") {
1756
+ attrs[ATTR_CLOUDFLARE_KV_QUERY_TYPE] = opts;
1757
+ } else if (typeof opts === "object") {
1758
+ if (opts.type) attrs[ATTR_CLOUDFLARE_KV_QUERY_TYPE] = opts.type;
1759
+ if (opts.cacheTtl) attrs[ATTR_CLOUDFLARE_KV_QUERY_CACHE_TTL] = opts.cacheTtl;
1760
+ }
1761
+ return attrs;
1762
+ },
1763
+ getWithMetadata(argArray, result) {
1764
+ const attrs = {};
1765
+ const opts = argArray[1];
1766
+ if (typeof opts === "string") {
1767
+ attrs[ATTR_CLOUDFLARE_KV_QUERY_TYPE] = opts;
1768
+ } else if (typeof opts === "object") {
1769
+ if (opts.type) attrs[ATTR_CLOUDFLARE_KV_QUERY_TYPE] = opts.type;
1770
+ if (opts.cacheTtl) attrs[ATTR_CLOUDFLARE_KV_QUERY_CACHE_TTL] = opts.cacheTtl;
1771
+ }
1772
+ const kvResult = result;
1773
+ if (kvResult.metadata !== null && kvResult.metadata !== void 0) {
1774
+ attrs[ATTR_CLOUDFLARE_KV_RESPONSE_METADATA] = JSON.stringify(kvResult.metadata);
1775
+ }
1776
+ if (kvResult.cacheStatus) {
1777
+ attrs[ATTR_CLOUDFLARE_KV_RESPONSE_CACHE_STATUS] = kvResult.cacheStatus;
1778
+ }
1779
+ return attrs;
1780
+ },
1781
+ list(argArray, result) {
1782
+ const attrs = {};
1783
+ const opts = argArray[0] || {};
1784
+ if (opts.cursor) attrs[ATTR_CLOUDFLARE_KV_QUERY_CURSOR] = opts.cursor;
1785
+ if (opts.limit) attrs[ATTR_CLOUDFLARE_KV_QUERY_LIMIT] = opts.limit;
1786
+ if (opts.prefix) attrs[ATTR_CLOUDFLARE_KV_QUERY_PREFIX] = opts.prefix;
1787
+ const kvResult = result;
1788
+ attrs[ATTR_CLOUDFLARE_KV_RESPONSE_LIST_COMPLETE] = kvResult.list_complete;
1789
+ if (!kvResult.list_complete && kvResult.cursor) {
1790
+ attrs[ATTR_CLOUDFLARE_KV_RESPONSE_CURSOR] = kvResult.cursor;
1791
+ }
1792
+ if (kvResult.cacheStatus) {
1793
+ attrs[ATTR_CLOUDFLARE_KV_RESPONSE_CACHE_STATUS] = kvResult.cacheStatus;
1794
+ }
1795
+ return attrs;
1796
+ },
1797
+ put(argArray) {
1798
+ const attrs = {};
1799
+ const value = argArray[1];
1800
+ if (value !== void 0) {
1801
+ attrs[ATTR_CLOUDFLARE_KV_QUERY_VALUE_TYPE] = typeof value;
1802
+ }
1803
+ if (argArray.length > 2 && argArray[2]) {
1804
+ const options = argArray[2];
1805
+ if (options.expiration) attrs[ATTR_CLOUDFLARE_KV_QUERY_EXPIRATION] = options.expiration;
1806
+ if (options.expirationTtl) attrs[ATTR_CLOUDFLARE_KV_QUERY_EXPIRATION_TTL] = options.expirationTtl;
1807
+ if (options.metadata !== void 0) {
1808
+ attrs[ATTR_CLOUDFLARE_KV_QUERY_METADATA] = JSON.stringify(options.metadata);
1809
+ }
1810
+ }
1811
+ return attrs;
1812
+ }
1813
+ };
1814
+ function instrumentKVFn(fn, name, operation) {
1815
+ const tracer = trace.getTracer("KV");
1816
+ const fnHandler = {
1817
+ apply: (target, thisArg, argArray) => {
1818
+ const attributes = {
1819
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "KV",
1820
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
1821
+ [SemanticAttributes.DB_NAME]: name,
1822
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$4,
1823
+ [ATTR_DB_OPERATION_NAME]: operation
1824
+ };
1825
+ const options = {
1826
+ kind: SpanKind.CLIENT,
1827
+ attributes
1828
+ };
1829
+ return tracer.startActiveSpan(`KV ${name} ${operation}`, options, async (span) => {
1830
+ const result = await Reflect.apply(target, thisArg, argArray);
1831
+ const extraAttrsFn = KVAttributes[operation];
1832
+ const extraAttrs = extraAttrsFn ? extraAttrsFn(argArray, result) : {};
1833
+ span.setAttributes(extraAttrs);
1834
+ if (operation === "list") ; else if (Array.isArray(argArray[0])) {
1835
+ const keys = argArray[0];
1836
+ if (keys.length > 0 && keys[0]) {
1837
+ span.setAttribute(ATTR_CLOUDFLARE_KV_QUERY_KEYS, keys[0]);
1838
+ span.setAttribute(ATTR_CLOUDFLARE_KV_QUERY_KEYS_COUNT, keys.length);
1839
+ }
1840
+ } else if (argArray[0] && typeof argArray[0] === "string") {
1841
+ span.setAttribute(ATTR_CLOUDFLARE_KV_QUERY_KEYS, argArray[0]);
1842
+ span.setAttribute(ATTR_CLOUDFLARE_KV_QUERY_KEYS_COUNT, 1);
1843
+ }
1844
+ span.end();
1845
+ return result;
1846
+ });
1847
+ }
1848
+ };
1849
+ return wrap(fn, fnHandler);
1850
+ }
1851
+ function instrumentKV(kv, name) {
1852
+ const kvHandler = {
1853
+ get: (target, prop, receiver) => {
1854
+ const operation = String(prop);
1855
+ const fn = Reflect.get(target, prop, receiver);
1856
+ return instrumentKVFn(fn, name, operation);
1857
+ }
1858
+ };
1859
+ return wrap(kv, kvHandler);
1860
+ }
1861
+
1862
+ function instrumentServiceBinding(fetcher, envName) {
1863
+ const fetcherHandler = {
1864
+ get(target, prop) {
1865
+ if (prop === "fetch") {
1866
+ const fetcher2 = Reflect.get(target, prop);
1867
+ const attrs = {
1868
+ name: `Service Binding ${envName}`
1869
+ };
1870
+ return instrumentClientFetch(fetcher2, () => ({ includeTraceContext: true }), attrs);
1871
+ } else {
1872
+ return passthroughGet(target, prop);
1873
+ }
1874
+ }
1875
+ };
1876
+ return wrap(fetcher, fetcherHandler);
1877
+ }
1878
+
1879
+ const dbSystem$3 = "Cloudflare D1";
1880
+ function metaAttributes(meta) {
1881
+ return {
1882
+ [ATTR_CLOUDFLARE_D1_RESPONSE_ROWS_READ]: meta.rows_read,
1883
+ [ATTR_CLOUDFLARE_D1_RESPONSE_ROWS_WRITTEN]: meta.rows_written,
1884
+ [ATTR_CLOUDFLARE_D1_RESPONSE_SQL_DURATION_MS]: meta.duration,
1885
+ [ATTR_CLOUDFLARE_D1_RESPONSE_SIZE_AFTER]: meta.size_after,
1886
+ [ATTR_CLOUDFLARE_D1_RESPONSE_LAST_ROW_ID]: meta.last_row_id,
1887
+ [ATTR_CLOUDFLARE_D1_RESPONSE_CHANGED_DB]: meta.changed_db,
1888
+ [ATTR_CLOUDFLARE_D1_RESPONSE_CHANGES]: meta.changes
1889
+ };
1890
+ }
1891
+ function spanOptions(dbName, operation, sql) {
1892
+ const attributes = {
1893
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "D1",
1894
+ [SemanticAttributes.DB_NAME]: dbName,
1895
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$3,
1896
+ [ATTR_DB_OPERATION_NAME]: operation
1897
+ };
1898
+ if (sql) {
1899
+ attributes[ATTR_DB_QUERY_TEXT] = sql;
1900
+ }
1901
+ return {
1902
+ kind: SpanKind.CLIENT,
1903
+ attributes
1904
+ };
1905
+ }
1906
+ function instrumentD1StatementFn(fn, dbName, operation, sql) {
1907
+ const tracer = trace.getTracer("D1");
1908
+ const fnHandler = {
1909
+ apply: (target, thisArg, argArray) => {
1910
+ if (operation === "bind") {
1911
+ const newStmt = Reflect.apply(target, thisArg, argArray);
1912
+ return instrumentD1PreparedStatement(newStmt, dbName, sql);
1913
+ }
1914
+ const options = spanOptions(dbName, operation, sql);
1915
+ return tracer.startActiveSpan(`${dbName} ${operation}`, options, async (span) => {
1916
+ try {
1917
+ const result = await Reflect.apply(target, thisArg, argArray);
1918
+ if (operation === "all" || operation === "run") {
1919
+ span.setAttributes(metaAttributes(result.meta));
1920
+ }
1921
+ span.setStatus({ code: SpanStatusCode.OK });
1922
+ return result;
1923
+ } catch (error) {
1924
+ span.recordException(error);
1925
+ span.setStatus({ code: SpanStatusCode.ERROR });
1926
+ throw error;
1927
+ } finally {
1928
+ span.end();
1929
+ }
1930
+ });
1931
+ }
1932
+ };
1933
+ return wrap(fn, fnHandler);
1934
+ }
1935
+ function instrumentD1PreparedStatement(stmt, dbName, statement) {
1936
+ const statementHandler = {
1937
+ get: (target, prop, receiver) => {
1938
+ const operation = String(prop);
1939
+ const fn = Reflect.get(target, prop, receiver);
1940
+ if (typeof fn === "function") {
1941
+ return instrumentD1StatementFn(fn, dbName, operation, statement);
1942
+ }
1943
+ return fn;
1944
+ }
1945
+ };
1946
+ return wrap(stmt, statementHandler);
1947
+ }
1948
+ function instrumentD1Fn(fn, dbName, operation) {
1949
+ const tracer = trace.getTracer("D1");
1950
+ const fnHandler = {
1951
+ apply: (target, thisArg, argArray) => {
1952
+ if (operation === "prepare") {
1953
+ const sql = argArray[0];
1954
+ const stmt = Reflect.apply(target, thisArg, argArray);
1955
+ return instrumentD1PreparedStatement(stmt, dbName, sql);
1956
+ } else if (operation === "exec") {
1957
+ const sql = argArray[0];
1958
+ const options = spanOptions(dbName, operation, sql);
1959
+ return tracer.startActiveSpan(`${dbName} ${operation}`, options, async (span) => {
1960
+ try {
1961
+ const result = await Reflect.apply(target, thisArg, argArray);
1962
+ span.setStatus({ code: SpanStatusCode.OK });
1963
+ return result;
1964
+ } catch (error) {
1965
+ span.recordException(error);
1966
+ span.setStatus({ code: SpanStatusCode.ERROR });
1967
+ throw error;
1968
+ } finally {
1969
+ span.end();
1970
+ }
1971
+ });
1972
+ } else if (operation === "batch") {
1973
+ const statements = argArray[0];
1974
+ return tracer.startActiveSpan(`${dbName} ${operation}`, async (span) => {
1975
+ span.setAttribute(ATTR_DB_OPERATION_BATCH_SIZE, statements.length);
1976
+ const subSpans = statements.map(
1977
+ (s) => tracer.startSpan(`${dbName} ${operation} > query`, spanOptions(dbName, operation, s.statement))
1978
+ );
1979
+ try {
1980
+ const result = await Reflect.apply(target, thisArg, argArray);
1981
+ result.forEach((r, i) => subSpans[i]?.setAttributes(metaAttributes(r.meta)));
1982
+ span.setStatus({ code: SpanStatusCode.OK });
1983
+ return result;
1984
+ } catch (error) {
1985
+ span.recordException(error);
1986
+ span.setStatus({ code: SpanStatusCode.ERROR });
1987
+ throw error;
1988
+ } finally {
1989
+ subSpans.forEach((s) => s.end());
1990
+ span.end();
1991
+ }
1992
+ });
1993
+ } else {
1994
+ return Reflect.apply(target, thisArg, argArray);
1995
+ }
1996
+ }
1997
+ };
1998
+ return wrap(fn, fnHandler);
1999
+ }
2000
+ function instrumentD1(database, dbName) {
2001
+ const dbHandler = {
2002
+ get: (target, prop, receiver) => {
2003
+ const operation = String(prop);
2004
+ const fn = Reflect.get(target, prop, receiver);
2005
+ if (typeof fn === "function") {
2006
+ return instrumentD1Fn(fn, dbName, operation);
2007
+ }
2008
+ return fn;
2009
+ }
2010
+ };
2011
+ return wrap(database, dbHandler);
2012
+ }
2013
+
2014
+ const dbSystem$2 = "Cloudflare Analytics Engine";
2015
+ const AEAttributes = {
2016
+ writeDataPoint(argArray) {
2017
+ const attrs = {};
2018
+ const opts = argArray[0];
2019
+ if (typeof opts === "object") {
2020
+ attrs["db.cf.ae.indexes"] = opts.indexes.length;
2021
+ attrs["db.cf.ae.index"] = opts.indexes[0].toString();
2022
+ attrs["db.cf.ae.doubles"] = opts.doubles.length;
2023
+ attrs["db.cf.ae.blobs"] = opts.blobs.length;
2024
+ }
2025
+ return attrs;
2026
+ }
2027
+ };
2028
+ function instrumentAEFn(fn, name, operation) {
2029
+ const tracer = trace.getTracer("AnalyticsEngine");
2030
+ const fnHandler = {
2031
+ apply: (target, thisArg, argArray) => {
2032
+ const attributes = {
2033
+ binding_type: "AnalyticsEngine",
2034
+ [SemanticAttributes.DB_NAME]: name,
2035
+ [SemanticAttributes.DB_SYSTEM]: dbSystem$2,
2036
+ [SemanticAttributes.DB_OPERATION]: operation
2037
+ };
2038
+ const options = {
2039
+ kind: SpanKind.CLIENT,
2040
+ attributes
2041
+ };
2042
+ return tracer.startActiveSpan(`Analytics Engine ${name} ${operation}`, options, async (span) => {
2043
+ const result = await Reflect.apply(target, thisArg, argArray);
2044
+ const extraAttrsFn = AEAttributes[operation];
2045
+ const extraAttrs = extraAttrsFn ? extraAttrsFn(argArray, result) : {};
2046
+ span.setAttributes(extraAttrs);
2047
+ span.setAttribute(SemanticAttributes.DB_STATEMENT, `${operation} ${argArray[0]}`);
2048
+ span.end();
2049
+ return result;
2050
+ });
2051
+ }
2052
+ };
2053
+ return wrap(fn, fnHandler);
2054
+ }
2055
+ function instrumentAnalyticsEngineDataset(dataset, name) {
2056
+ const datasetHandler = {
2057
+ get: (target, prop, receiver) => {
2058
+ const operation = String(prop);
2059
+ const fn = Reflect.get(target, prop, receiver);
2060
+ return instrumentAEFn(fn, name, operation);
2061
+ }
2062
+ };
2063
+ return wrap(dataset, datasetHandler);
2064
+ }
2065
+
2066
+ const dbSystem$1 = "Cloudflare R2";
2067
+ function addObjectMetadata(attrs, obj) {
2068
+ if (!obj) return;
2069
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_SIZE] = obj.size;
2070
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_ETAG] = obj.etag;
2071
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_VERSION] = obj.version;
2072
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_UPLOADED] = obj.uploaded.toISOString();
2073
+ if (obj.httpMetadata) {
2074
+ if (obj.httpMetadata.contentType) {
2075
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CONTENT_TYPE] = obj.httpMetadata.contentType;
2076
+ }
2077
+ if (obj.httpMetadata.contentLanguage) {
2078
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CONTENT_LANGUAGE] = obj.httpMetadata.contentLanguage;
2079
+ }
2080
+ if (obj.httpMetadata.contentDisposition) {
2081
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CONTENT_DISPOSITION] = obj.httpMetadata.contentDisposition;
2082
+ }
2083
+ if (obj.httpMetadata.contentEncoding) {
2084
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CONTENT_ENCODING] = obj.httpMetadata.contentEncoding;
2085
+ }
2086
+ if (obj.httpMetadata.cacheControl) {
2087
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CACHE_CONTROL] = obj.httpMetadata.cacheControl;
2088
+ }
2089
+ if (obj.httpMetadata.cacheExpiry) {
2090
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_HTTP_METADATA_CACHE_EXPIRY] = obj.httpMetadata.cacheExpiry.toISOString();
2091
+ }
2092
+ }
2093
+ if (obj.customMetadata && Object.keys(obj.customMetadata).length > 0) {
2094
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_CUSTOM_METADATA_KEYS] = Object.keys(obj.customMetadata).join(",");
2095
+ }
2096
+ if (obj.range) {
2097
+ if ("offset" in obj.range && "length" in obj.range) {
2098
+ const offset = obj.range.offset ?? 0;
2099
+ const length = obj.range.length ?? 0;
2100
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_RANGE] = `${offset}-${offset + length - 1}`;
2101
+ } else if ("suffix" in obj.range) {
2102
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_RANGE] = `suffix-${obj.range.suffix}`;
2103
+ }
2104
+ }
2105
+ if (obj.storageClass) {
2106
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_STORAGE_CLASS] = obj.storageClass;
2107
+ }
2108
+ if (obj.checksums) {
2109
+ if (obj.checksums.md5) {
2110
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_MD5] = Array.from(new Uint8Array(obj.checksums.md5)).map((b) => b.toString(16).padStart(2, "0")).join("");
2111
+ }
2112
+ if (obj.checksums.sha1) {
2113
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_SHA1] = Array.from(new Uint8Array(obj.checksums.sha1)).map((b) => b.toString(16).padStart(2, "0")).join("");
2114
+ }
2115
+ if (obj.checksums.sha256) {
2116
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_SHA256] = Array.from(new Uint8Array(obj.checksums.sha256)).map((b) => b.toString(16).padStart(2, "0")).join("");
2117
+ }
2118
+ if (obj.checksums.sha384) {
2119
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_SHA384] = Array.from(new Uint8Array(obj.checksums.sha384)).map((b) => b.toString(16).padStart(2, "0")).join("");
2120
+ }
2121
+ if (obj.checksums.sha512) {
2122
+ attrs[ATTR_CLOUDFLARE_R2_RESPONSE_CHECKSUMS_SHA512] = Array.from(new Uint8Array(obj.checksums.sha512)).map((b) => b.toString(16).padStart(2, "0")).join("");
2123
+ }
2124
+ }
2125
+ }
2126
+ function instrumentHead(fn, name) {
2127
+ const tracer = trace.getTracer("r2");
2128
+ const handler = {
2129
+ apply: (target, thisArg, argArray) => {
2130
+ const key = argArray[0];
2131
+ const attributes = {
2132
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "R2",
2133
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2134
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$1,
2135
+ [ATTR_DB_OPERATION_NAME]: "head",
2136
+ [ATTR_DB_QUERY_TEXT]: key,
2137
+ [ATTR_CLOUDFLARE_R2_QUERY_KEY]: key
2138
+ };
2139
+ const options = {
2140
+ kind: SpanKind.CLIENT,
2141
+ attributes
2142
+ };
2143
+ return tracer.startActiveSpan(`R2 ${name} head`, options, async (span) => {
2144
+ const result = await Reflect.apply(target, thisArg, argArray);
2145
+ addObjectMetadata(attributes, result);
2146
+ span.setAttributes(attributes);
2147
+ span.end();
2148
+ return result;
2149
+ });
2150
+ }
2151
+ };
2152
+ return wrap(fn, handler);
2153
+ }
2154
+ function instrumentGet(fn, name) {
2155
+ const tracer = trace.getTracer("r2");
2156
+ const handler = {
2157
+ apply: (target, thisArg, argArray) => {
2158
+ const key = argArray[0];
2159
+ const getOptions = argArray[1];
2160
+ const attributes = {
2161
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "R2",
2162
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2163
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$1,
2164
+ [ATTR_DB_OPERATION_NAME]: "get",
2165
+ [ATTR_DB_QUERY_TEXT]: key,
2166
+ [ATTR_CLOUDFLARE_R2_QUERY_KEY]: key
2167
+ };
2168
+ if (getOptions) {
2169
+ if (getOptions.range) {
2170
+ if ("offset" in getOptions.range) {
2171
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_OFFSET] = getOptions.range.offset;
2172
+ if ("length" in getOptions.range) {
2173
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_LENGTH] = getOptions.range.length;
2174
+ }
2175
+ } else if ("suffix" in getOptions.range) {
2176
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_SUFFIX] = getOptions.range.suffix;
2177
+ }
2178
+ }
2179
+ if (getOptions.onlyIf) {
2180
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_ONLY_IF] = JSON.stringify(getOptions.onlyIf);
2181
+ }
2182
+ }
2183
+ const options = {
2184
+ kind: SpanKind.CLIENT,
2185
+ attributes
2186
+ };
2187
+ return tracer.startActiveSpan(`R2 ${name} get`, options, async (span) => {
2188
+ const result = await Reflect.apply(target, thisArg, argArray);
2189
+ addObjectMetadata(attributes, result);
2190
+ span.setAttributes(attributes);
2191
+ span.end();
2192
+ return result;
2193
+ });
2194
+ }
2195
+ };
2196
+ return wrap(fn, handler);
2197
+ }
2198
+ function instrumentPut(fn, name) {
2199
+ const tracer = trace.getTracer("r2");
2200
+ const handler = {
2201
+ apply: (target, thisArg, argArray) => {
2202
+ const key = argArray[0];
2203
+ const putOptions = argArray[2];
2204
+ const attributes = {
2205
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "R2",
2206
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2207
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$1,
2208
+ [ATTR_DB_OPERATION_NAME]: "put",
2209
+ [ATTR_DB_QUERY_TEXT]: key,
2210
+ [ATTR_CLOUDFLARE_R2_QUERY_KEY]: key
2211
+ };
2212
+ if (putOptions) {
2213
+ if (putOptions.httpMetadata) {
2214
+ attributes[ATTR_CLOUDFLARE_R2_PUT_HTTP_METADATA] = true;
2215
+ }
2216
+ if (putOptions.customMetadata) {
2217
+ attributes[ATTR_CLOUDFLARE_R2_PUT_CUSTOM_METADATA] = Object.keys(putOptions.customMetadata).join(",");
2218
+ }
2219
+ if (putOptions.md5) {
2220
+ attributes[ATTR_CLOUDFLARE_R2_PUT_MD5] = true;
2221
+ }
2222
+ if (putOptions.sha1) {
2223
+ attributes[ATTR_CLOUDFLARE_R2_PUT_SHA1] = true;
2224
+ }
2225
+ if (putOptions.sha256) {
2226
+ attributes[ATTR_CLOUDFLARE_R2_PUT_SHA256] = true;
2227
+ }
2228
+ if (putOptions.sha384) {
2229
+ attributes[ATTR_CLOUDFLARE_R2_PUT_SHA384] = true;
2230
+ }
2231
+ if (putOptions.sha512) {
2232
+ attributes[ATTR_CLOUDFLARE_R2_PUT_SHA512] = true;
2233
+ }
2234
+ if (putOptions.storageClass) {
2235
+ attributes[ATTR_CLOUDFLARE_R2_PUT_STORAGE_CLASS] = putOptions.storageClass;
2236
+ }
2237
+ }
2238
+ const options = {
2239
+ kind: SpanKind.CLIENT,
2240
+ attributes
2241
+ };
2242
+ return tracer.startActiveSpan(`R2 ${name} put`, options, async (span) => {
2243
+ const result = await Reflect.apply(target, thisArg, argArray);
2244
+ addObjectMetadata(attributes, result);
2245
+ span.setAttributes(attributes);
2246
+ span.end();
2247
+ return result;
2248
+ });
2249
+ }
2250
+ };
2251
+ return wrap(fn, handler);
2252
+ }
2253
+ function instrumentDelete(fn, name) {
2254
+ const tracer = trace.getTracer("r2");
2255
+ const handler = {
2256
+ apply: (target, thisArg, argArray) => {
2257
+ const keys = argArray[0];
2258
+ const isArray = Array.isArray(keys);
2259
+ const attributes = {
2260
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "R2",
2261
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2262
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$1,
2263
+ [ATTR_DB_OPERATION_NAME]: "delete"
2264
+ };
2265
+ if (isArray) {
2266
+ if (keys.length > 0) {
2267
+ attributes[ATTR_DB_QUERY_TEXT] = keys[0];
2268
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_KEY] = keys[0];
2269
+ }
2270
+ } else {
2271
+ attributes[ATTR_DB_QUERY_TEXT] = keys;
2272
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_KEY] = keys;
2273
+ }
2274
+ const options = {
2275
+ kind: SpanKind.CLIENT,
2276
+ attributes
2277
+ };
2278
+ return tracer.startActiveSpan(`R2 ${name} delete`, options, async (span) => {
2279
+ await Reflect.apply(target, thisArg, argArray);
2280
+ span.end();
2281
+ });
2282
+ }
2283
+ };
2284
+ return wrap(fn, handler);
2285
+ }
2286
+ function instrumentList(fn, name) {
2287
+ const tracer = trace.getTracer("r2");
2288
+ const handler = {
2289
+ apply: (target, thisArg, argArray) => {
2290
+ const listOptions = argArray[0];
2291
+ const attributes = {
2292
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "R2",
2293
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2294
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$1,
2295
+ [ATTR_DB_OPERATION_NAME]: "list"
2296
+ };
2297
+ if (listOptions) {
2298
+ if (listOptions.prefix) {
2299
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_PREFIX] = listOptions.prefix;
2300
+ }
2301
+ if (listOptions.limit) {
2302
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_LIMIT] = listOptions.limit;
2303
+ }
2304
+ if (listOptions.delimiter) {
2305
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_DELIMITER] = listOptions.delimiter;
2306
+ }
2307
+ if (listOptions.startAfter) {
2308
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_START_AFTER] = listOptions.startAfter;
2309
+ }
2310
+ if (listOptions.include) {
2311
+ attributes[ATTR_CLOUDFLARE_R2_QUERY_INCLUDE] = listOptions.include.join(",");
2312
+ }
2313
+ if (listOptions.cursor) {
2314
+ attributes[ATTR_CLOUDFLARE_R2_LIST_CURSOR] = listOptions.cursor;
2315
+ }
2316
+ }
2317
+ const options = {
2318
+ kind: SpanKind.CLIENT,
2319
+ attributes
2320
+ };
2321
+ return tracer.startActiveSpan(`R2 ${name} list`, options, async (span) => {
2322
+ const result = await Reflect.apply(target, thisArg, argArray);
2323
+ attributes[ATTR_CLOUDFLARE_R2_LIST_TRUNCATED] = result.truncated;
2324
+ attributes[ATTR_CLOUDFLARE_R2_LIST_OBJECTS_COUNT] = result.objects.length;
2325
+ if (result.delimitedPrefixes) {
2326
+ attributes[ATTR_CLOUDFLARE_R2_LIST_DELIMITED_PREFIXES_COUNT] = result.delimitedPrefixes.length;
2327
+ }
2328
+ if (result.truncated && "cursor" in result && result.cursor) {
2329
+ attributes[ATTR_CLOUDFLARE_R2_LIST_CURSOR] = result.cursor;
2330
+ }
2331
+ span.setAttributes(attributes);
2332
+ span.end();
2333
+ return result;
2334
+ });
2335
+ }
2336
+ };
2337
+ return wrap(fn, handler);
2338
+ }
2339
+ function instrumentCreateMultipartUpload(fn, name) {
2340
+ const tracer = trace.getTracer("r2");
2341
+ const handler = {
2342
+ apply: (target, thisArg, argArray) => {
2343
+ const key = argArray[0];
2344
+ const attributes = {
2345
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "R2",
2346
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2347
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$1,
2348
+ [ATTR_DB_OPERATION_NAME]: "createMultipartUpload",
2349
+ [ATTR_DB_QUERY_TEXT]: key,
2350
+ [ATTR_CLOUDFLARE_R2_QUERY_KEY]: key
2351
+ };
2352
+ const options = {
2353
+ kind: SpanKind.CLIENT,
2354
+ attributes
2355
+ };
2356
+ return tracer.startActiveSpan(`R2 ${name} createMultipartUpload`, options, async (span) => {
2357
+ const result = await Reflect.apply(target, thisArg, argArray);
2358
+ attributes[ATTR_CLOUDFLARE_R2_MULTIPART_UPLOAD_ID] = result.uploadId;
2359
+ span.setAttributes(attributes);
2360
+ span.end();
2361
+ return result;
2362
+ });
2363
+ }
2364
+ };
2365
+ return wrap(fn, handler);
2366
+ }
2367
+ function instrumentResumeMultipartUpload(fn, name) {
2368
+ const tracer = trace.getTracer("r2");
2369
+ const handler = {
2370
+ apply: (target, thisArg, argArray) => {
2371
+ const key = argArray[0];
2372
+ const uploadId = argArray[1];
2373
+ const attributes = {
2374
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "R2",
2375
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2376
+ [ATTR_DB_SYSTEM_NAME]: dbSystem$1,
2377
+ [ATTR_DB_OPERATION_NAME]: "resumeMultipartUpload",
2378
+ [ATTR_DB_QUERY_TEXT]: key,
2379
+ [ATTR_CLOUDFLARE_R2_QUERY_KEY]: key,
2380
+ [ATTR_CLOUDFLARE_R2_MULTIPART_UPLOAD_ID]: uploadId
2381
+ };
2382
+ const options = {
2383
+ kind: SpanKind.CLIENT,
2384
+ attributes
2385
+ };
2386
+ return tracer.startActiveSpan(`R2 ${name} resumeMultipartUpload`, options, async (span) => {
2387
+ const result = await Reflect.apply(target, thisArg, argArray);
2388
+ span.end();
2389
+ return result;
2390
+ });
2391
+ }
2392
+ };
2393
+ return wrap(fn, handler);
2394
+ }
2395
+ function instrumentR2Bucket(bucket, name) {
2396
+ const bucketHandler = {
2397
+ get: (target, prop, receiver) => {
2398
+ const operation = String(prop);
2399
+ const fn = Reflect.get(target, prop, receiver);
2400
+ if (typeof fn !== "function") {
2401
+ return fn;
2402
+ }
2403
+ switch (operation) {
2404
+ case "head":
2405
+ return instrumentHead(fn, name);
2406
+ case "get":
2407
+ return instrumentGet(fn, name);
2408
+ case "put":
2409
+ return instrumentPut(fn, name);
2410
+ case "delete":
2411
+ return instrumentDelete(fn, name);
2412
+ case "list":
2413
+ return instrumentList(fn, name);
2414
+ case "createMultipartUpload":
2415
+ return instrumentCreateMultipartUpload(fn, name);
2416
+ case "resumeMultipartUpload":
2417
+ return instrumentResumeMultipartUpload(fn, name);
2418
+ default:
2419
+ return fn;
2420
+ }
2421
+ }
2422
+ };
2423
+ return wrap(bucket, bucketHandler);
2424
+ }
2425
+
2426
+ function instrumentImagesGet(fn, name) {
2427
+ const tracer = trace.getTracer("images");
2428
+ const handler = {
2429
+ apply: (target, thisArg, argArray) => {
2430
+ const key = argArray[0];
2431
+ const attributes = {
2432
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "Images",
2433
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2434
+ [ATTR_CLOUDFLARE_IMAGES_KEY]: key
2435
+ };
2436
+ const options = {
2437
+ kind: SpanKind.CLIENT,
2438
+ attributes
2439
+ };
2440
+ return tracer.startActiveSpan(`Images ${name} get`, options, async (span) => {
2441
+ const result = await Reflect.apply(target, thisArg, argArray);
2442
+ if (result && typeof result === "object") {
2443
+ if (result.id) {
2444
+ attributes[ATTR_CLOUDFLARE_IMAGES_RESPONSE_ID] = result.id;
2445
+ }
2446
+ if (result.filename) {
2447
+ attributes[ATTR_CLOUDFLARE_IMAGES_RESPONSE_FILENAME] = result.filename;
2448
+ }
2449
+ if (result.uploaded) {
2450
+ attributes[ATTR_CLOUDFLARE_IMAGES_UPLOADED] = result.uploaded;
2451
+ }
2452
+ if (result.metadata && typeof result.metadata === "object") {
2453
+ attributes[ATTR_CLOUDFLARE_IMAGES_METADATA_KEYS] = Object.keys(result.metadata).join(",");
2454
+ }
2455
+ if (result.variants && Array.isArray(result.variants)) {
2456
+ attributes[ATTR_CLOUDFLARE_IMAGES_VARIANTS_COUNT] = result.variants.length;
2457
+ }
2458
+ if (typeof result.requireSignedURLs === "boolean") {
2459
+ attributes[ATTR_CLOUDFLARE_IMAGES_REQUIRE_SIGNED_URLS] = result.requireSignedURLs;
2460
+ }
2461
+ }
2462
+ span.setAttributes(attributes);
2463
+ span.end();
2464
+ return result;
2465
+ });
2466
+ }
2467
+ };
2468
+ return wrap(fn, handler);
2469
+ }
2470
+ function instrumentImagesList(fn, name) {
2471
+ const tracer = trace.getTracer("images");
2472
+ const handler = {
2473
+ apply: (target, thisArg, argArray) => {
2474
+ const attributes = {
2475
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "Images",
2476
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name
2477
+ };
2478
+ const options = {
2479
+ kind: SpanKind.CLIENT,
2480
+ attributes
2481
+ };
2482
+ return tracer.startActiveSpan(`Images ${name} list`, options, async (span) => {
2483
+ const result = await Reflect.apply(target, thisArg, argArray);
2484
+ if (result && typeof result === "object" && Array.isArray(result.images)) {
2485
+ span.setAttribute("cloudflare.images.list.count", result.images.length);
2486
+ }
2487
+ span.end();
2488
+ return result;
2489
+ });
2490
+ }
2491
+ };
2492
+ return wrap(fn, handler);
2493
+ }
2494
+ function instrumentImagesDelete(fn, name) {
2495
+ const tracer = trace.getTracer("images");
2496
+ const handler = {
2497
+ apply: (target, thisArg, argArray) => {
2498
+ const key = argArray[0];
2499
+ const attributes = {
2500
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "Images",
2501
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2502
+ [ATTR_CLOUDFLARE_IMAGES_KEY]: key
2503
+ };
2504
+ const options = {
2505
+ kind: SpanKind.CLIENT,
2506
+ attributes
2507
+ };
2508
+ return tracer.startActiveSpan(`Images ${name} delete`, options, async (span) => {
2509
+ await Reflect.apply(target, thisArg, argArray);
2510
+ span.end();
2511
+ });
2512
+ }
2513
+ };
2514
+ return wrap(fn, handler);
2515
+ }
2516
+ function instrumentImagesBinding(images, name) {
2517
+ const imagesHandler = {
2518
+ get: (target, prop, receiver) => {
2519
+ const fn = Reflect.get(target, prop, receiver);
2520
+ if (typeof fn !== "function") {
2521
+ return fn;
2522
+ }
2523
+ switch (String(prop)) {
2524
+ case "get":
2525
+ return instrumentImagesGet(fn, name);
2526
+ case "list":
2527
+ return instrumentImagesList(fn, name);
2528
+ case "delete":
2529
+ return instrumentImagesDelete(fn, name);
2530
+ default:
2531
+ return fn;
2532
+ }
2533
+ }
2534
+ };
2535
+ return wrap(images, imagesHandler);
2536
+ }
2537
+
2538
+ function instrumentRateLimitLimit(fn, name) {
2539
+ const tracer = trace.getTracer("rate_limit");
2540
+ const handler = {
2541
+ apply: (target, thisArg, argArray) => {
2542
+ const options = argArray[0];
2543
+ const attributes = {
2544
+ [ATTR_CLOUDFLARE_BINDING_TYPE]: "RateLimit",
2545
+ [ATTR_CLOUDFLARE_BINDING_NAME]: name,
2546
+ [ATTR_CLOUDFLARE_RATE_LIMIT_KEY]: options.key
2547
+ };
2548
+ const spanOptions = {
2549
+ kind: SpanKind.CLIENT,
2550
+ attributes
2551
+ };
2552
+ return tracer.startActiveSpan(`RateLimit ${name} limit`, spanOptions, async (span) => {
2553
+ const result = await Reflect.apply(target, thisArg, argArray);
2554
+ if (result && typeof result === "object") {
2555
+ attributes[ATTR_CLOUDFLARE_RATE_LIMIT_SUCCESS] = result.success;
2556
+ attributes[ATTR_CLOUDFLARE_RATE_LIMIT_ALLOWED] = result.success;
2557
+ }
2558
+ span.setAttributes(attributes);
2559
+ span.end();
2560
+ return result;
2561
+ });
2562
+ }
2563
+ };
2564
+ return wrap(fn, handler);
2565
+ }
2566
+ function instrumentRateLimitBinding(rateLimit, name) {
2567
+ const rateLimitHandler = {
2568
+ get: (target, prop, receiver) => {
2569
+ const fn = Reflect.get(target, prop, receiver);
2570
+ if (typeof fn !== "function") {
2571
+ return fn;
2572
+ }
2573
+ switch (String(prop)) {
2574
+ case "limit":
2575
+ return instrumentRateLimitLimit(fn, name);
2576
+ default:
2577
+ return fn;
2578
+ }
2579
+ }
2580
+ };
2581
+ return wrap(rateLimit, rateLimitHandler);
2582
+ }
2583
+
2584
+ const isJSRPC = (item) => {
2585
+ return !!item?.["__some_property_that_will_never_exist" + Math.random()];
2586
+ };
2587
+ const isKVNamespace = (item) => {
2588
+ return !isJSRPC(item) && !!item?.getWithMetadata;
2589
+ };
2590
+ const isQueue = (item) => {
2591
+ return !isJSRPC(item) && !!item?.sendBatch;
2592
+ };
2593
+ const isDurableObject = (item) => {
2594
+ return !isJSRPC(item) && !!item?.idFromName;
2595
+ };
2596
+ const isVersionMetadata = (item) => {
2597
+ return !isJSRPC(item) && typeof item?.id === "string" && typeof item?.tag === "string";
2598
+ };
2599
+ const isAnalyticsEngineDataset = (item) => {
2600
+ return !isJSRPC(item) && !!item?.writeDataPoint;
2601
+ };
2602
+ const isD1Database = (item) => {
2603
+ return !!item?.exec && !!item?.prepare;
2604
+ };
2605
+ const isR2Bucket = (item) => {
2606
+ return !isJSRPC(item) && !!item?.head && !!item?.list;
2607
+ };
2608
+ const isImagesBinding = (item) => {
2609
+ const obj = item;
2610
+ return !isJSRPC(item) && typeof obj?.get === "function" && typeof obj?.list === "function" && typeof obj?.delete === "function" && // Distinguish from other bindings with similar methods
2611
+ !isR2Bucket(item) && !isKVNamespace(item);
2612
+ };
2613
+ const isRateLimitBinding = (item) => {
2614
+ const obj = item;
2615
+ return !isJSRPC(item) && typeof obj?.limit === "function" && !isDurableObject(item);
2616
+ };
2617
+ const instrumentEnv = (env) => {
2618
+ const envHandler = {
2619
+ get: (target, prop, receiver) => {
2620
+ const item = Reflect.get(target, prop, receiver);
2621
+ if (!isProxyable(item)) {
2622
+ return item;
2623
+ }
2624
+ if (isJSRPC(item)) {
2625
+ return instrumentServiceBinding(item, String(prop));
2626
+ } else if (isKVNamespace(item)) {
2627
+ return instrumentKV(item, String(prop));
2628
+ } else if (isQueue(item)) {
2629
+ return instrumentQueueSender(item, String(prop));
2630
+ } else if (isDurableObject(item)) {
2631
+ return instrumentDOBinding(item, String(prop));
2632
+ } else if (isVersionMetadata(item)) {
2633
+ return item;
2634
+ } else if (isAnalyticsEngineDataset(item)) {
2635
+ return instrumentAnalyticsEngineDataset(item, String(prop));
2636
+ } else if (isD1Database(item)) {
2637
+ return instrumentD1(item, String(prop));
2638
+ } else if (isR2Bucket(item)) {
2639
+ return instrumentR2Bucket(item, String(prop));
2640
+ } else if (isImagesBinding(item)) {
2641
+ return instrumentImagesBinding(item, String(prop));
2642
+ } else if (isRateLimitBinding(item)) {
2643
+ return instrumentRateLimitBinding(item, String(prop));
2644
+ } else {
2645
+ return item;
2646
+ }
2647
+ }
2648
+ };
2649
+ return wrap(env, envHandler);
2650
+ };
2651
+
2652
+ const dbSystem = "Cloudflare DO";
2653
+ function isDurableObjectCommonOptions(options) {
2654
+ return typeof options === "object" && ("allowConcurrency" in options || "allowUnconfirmed" in options || "noCache" in options);
2655
+ }
2656
+ function applyOptionsAttributes(attrs, options) {
2657
+ if ("allowConcurrency" in options) {
2658
+ attrs[ATTR_CLOUDFLARE_DO_ALLOW_CONCURRENCY] = options.allowConcurrency;
2659
+ }
2660
+ if ("allowUnconfirmed" in options) {
2661
+ attrs[ATTR_CLOUDFLARE_DO_ALLOW_UNCONFIRMED] = options.allowUnconfirmed;
2662
+ }
2663
+ if ("noCache" in options) {
2664
+ attrs[ATTR_CLOUDFLARE_DO_NO_CACHE] = options.noCache;
2665
+ }
2666
+ }
2667
+ const StorageAttributes = {
2668
+ delete(argArray, result) {
2669
+ const args = argArray;
2670
+ let attrs = {};
2671
+ if (Array.isArray(args[0])) {
2672
+ const keys = args[0];
2673
+ attrs = {
2674
+ [ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS]: keys[0],
2675
+ [ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS_COUNT]: keys.length,
2676
+ [ATTR_CLOUDFLARE_DO_KV_RESPONSE_DELETED_COUNT]: result
2677
+ };
2678
+ } else {
2679
+ attrs = {
2680
+ [ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS]: args[0]
2681
+ };
2682
+ }
2683
+ if (args[1]) {
2684
+ applyOptionsAttributes(attrs, args[1]);
2685
+ }
2686
+ return attrs;
2687
+ },
2688
+ deleteAll(argArray) {
2689
+ const args = argArray;
2690
+ let attrs = {};
2691
+ if (args[0]) {
2692
+ applyOptionsAttributes(attrs, args[0]);
2693
+ }
2694
+ return attrs;
2695
+ },
2696
+ get(argArray) {
2697
+ const args = argArray;
2698
+ let attrs = {};
2699
+ if (Array.isArray(args[0])) {
2700
+ const keys = args[0];
2701
+ attrs = {
2702
+ [ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS]: keys[0],
2703
+ [ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS_COUNT]: keys.length
2704
+ };
2705
+ } else {
2706
+ attrs = {
2707
+ [ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS]: args[0]
2708
+ };
2709
+ }
2710
+ if (args[1]) {
2711
+ applyOptionsAttributes(attrs, args[1]);
2712
+ }
2713
+ return attrs;
2714
+ },
2715
+ list(argArray) {
2716
+ const args = argArray;
2717
+ const attrs = {};
2718
+ if (args[0]) {
2719
+ const options = args[0];
2720
+ applyOptionsAttributes(attrs, options);
2721
+ if ("start" in options) {
2722
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_START] = options.start;
2723
+ }
2724
+ if ("startAfter" in options) {
2725
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_START_AFTER] = options.startAfter;
2726
+ }
2727
+ if ("end" in options) {
2728
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_END] = options.end;
2729
+ }
2730
+ if ("prefix" in options) {
2731
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_PREFIX] = options.prefix;
2732
+ }
2733
+ if ("reverse" in options) {
2734
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_REVERSE] = options.reverse;
2735
+ }
2736
+ if ("limit" in options) {
2737
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_LIMIT] = options.limit;
2738
+ }
2739
+ }
2740
+ return attrs;
2741
+ },
2742
+ put(argArray) {
2743
+ const args = argArray;
2744
+ const attrs = {};
2745
+ if (typeof args[0] === "string") {
2746
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS] = args[0];
2747
+ if (args[2]) {
2748
+ applyOptionsAttributes(attrs, args[2]);
2749
+ }
2750
+ } else {
2751
+ const keys = Object.keys(args[0]);
2752
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS] = keys[0];
2753
+ attrs[ATTR_CLOUDFLARE_DO_KV_QUERY_KEYS_COUNT] = keys.length;
2754
+ if (isDurableObjectCommonOptions(args[1])) {
2755
+ applyOptionsAttributes(attrs, args[1]);
2756
+ }
2757
+ }
2758
+ return attrs;
2759
+ },
2760
+ getAlarm(argArray) {
2761
+ const args = argArray;
2762
+ const attrs = {};
2763
+ if (args[0]) {
2764
+ applyOptionsAttributes(attrs, args[0]);
2765
+ }
2766
+ return attrs;
2767
+ },
2768
+ setAlarm(argArray) {
2769
+ const args = argArray;
2770
+ const attrs = {};
2771
+ if (args[0] instanceof Date) {
2772
+ attrs["db.cf.do.alarm_time"] = args[0].getTime();
2773
+ } else {
2774
+ attrs["db.cf.do.alarm_time"] = args[0];
2775
+ }
2776
+ if (args[1]) {
2777
+ applyOptionsAttributes(attrs, args[1]);
2778
+ }
2779
+ return attrs;
2780
+ },
2781
+ deleteAlarm(argArray) {
2782
+ const args = argArray;
2783
+ const attrs = {};
2784
+ if (args[0]) {
2785
+ applyOptionsAttributes(attrs, args[0]);
2786
+ }
2787
+ return attrs;
2788
+ }
2789
+ };
2790
+ function instrumentStorageFn(fn, operation) {
2791
+ const tracer = trace.getTracer("do_storage");
2792
+ const fnHandler = {
2793
+ apply: (target, thisArg, argArray) => {
2794
+ const attributes = {
2795
+ [ATTR_DB_SYSTEM_NAME]: dbSystem,
2796
+ [ATTR_DB_OPERATION_NAME]: operation
2797
+ };
2798
+ const options = {
2799
+ kind: SpanKind.CLIENT,
2800
+ attributes
2801
+ };
2802
+ return tracer.startActiveSpan(`Durable Object Storage ${operation}`, options, async (span) => {
2803
+ const result = await Reflect.apply(target, thisArg, argArray);
2804
+ const extraAttrsFn = StorageAttributes[operation];
2805
+ const extraAttrs = extraAttrsFn ? extraAttrsFn(argArray, result) : {};
2806
+ span.setAttributes(extraAttrs);
2807
+ span.end();
2808
+ return result;
2809
+ });
2810
+ }
2811
+ };
2812
+ return wrap(fn, fnHandler);
2813
+ }
2814
+ function instrumentStorage(storage) {
2815
+ const storageHandler = {
2816
+ get: (target, prop, receiver) => {
2817
+ const operation = String(prop);
2818
+ const fn = Reflect.get(target, prop, receiver);
2819
+ if (prop === "sql" && typeof fn === "object" && fn !== null) {
2820
+ return instrumentSQLStorage(fn);
2821
+ }
2822
+ return instrumentStorageFn(fn, operation);
2823
+ }
2824
+ };
2825
+ return wrap(storage, storageHandler);
2826
+ }
2827
+ function instrumentSQLStorageExec(fn, operation) {
2828
+ const tracer = trace.getTracer("do_sql_storage");
2829
+ const fnHandler = {
2830
+ apply: (target, thisArg, argArray) => {
2831
+ const query = argArray[0];
2832
+ const bindings = argArray[1];
2833
+ const attributes = {
2834
+ [ATTR_DB_SYSTEM_NAME]: dbSystem,
2835
+ [ATTR_DB_OPERATION_NAME]: operation,
2836
+ [ATTR_DB_QUERY_TEXT]: query
2837
+ };
2838
+ if (bindings && bindings.length > 0) {
2839
+ attributes[ATTR_CLOUDFLARE_DO_SQL_QUERY_BINDINGS] = bindings.length;
2840
+ }
2841
+ const options = {
2842
+ kind: SpanKind.CLIENT,
2843
+ attributes
2844
+ };
2845
+ return tracer.startActiveSpan(`Durable Object SQL ${operation}`, options, async (span) => {
2846
+ const result = await Reflect.apply(target, thisArg, argArray);
2847
+ if (result && typeof result === "object") {
2848
+ if ("rowsRead" in result) {
2849
+ span.setAttribute(ATTR_CLOUDFLARE_DO_SQL_RESPONSE_ROWS_READ, result.rowsRead);
2850
+ }
2851
+ if ("rowsWritten" in result) {
2852
+ span.setAttribute(ATTR_CLOUDFLARE_DO_SQL_RESPONSE_ROWS_WRITTEN, result.rowsWritten);
2853
+ }
2854
+ }
2855
+ span.end();
2856
+ return result;
2857
+ });
2858
+ }
2859
+ };
2860
+ return wrap(fn, fnHandler);
2861
+ }
2862
+ function instrumentSQLStorageExecBatch(fn, operation) {
2863
+ const tracer = trace.getTracer("do_sql_storage");
2864
+ const fnHandler = {
2865
+ apply: (target, thisArg, argArray) => {
2866
+ const statements = argArray[0];
2867
+ const attributes = {
2868
+ [ATTR_DB_SYSTEM_NAME]: dbSystem,
2869
+ [ATTR_DB_OPERATION_NAME]: operation,
2870
+ [ATTR_DB_OPERATION_BATCH_SIZE]: statements.length
2871
+ };
2872
+ if (statements.length > 0 && statements[0]) {
2873
+ attributes[ATTR_DB_QUERY_TEXT] = statements[0].query;
2874
+ }
2875
+ const options = {
2876
+ kind: SpanKind.CLIENT,
2877
+ attributes
2878
+ };
2879
+ return tracer.startActiveSpan(`Durable Object SQL ${operation}`, options, async (span) => {
2880
+ const results = await Reflect.apply(target, thisArg, argArray);
2881
+ let totalRowsRead = 0;
2882
+ let totalRowsWritten = 0;
2883
+ for (const result of results) {
2884
+ if (result && typeof result === "object") {
2885
+ if ("rowsRead" in result) {
2886
+ totalRowsRead += result.rowsRead;
2887
+ }
2888
+ if ("rowsWritten" in result) {
2889
+ totalRowsWritten += result.rowsWritten;
2890
+ }
2891
+ }
2892
+ }
2893
+ span.setAttribute(ATTR_CLOUDFLARE_DO_SQL_RESPONSE_ROWS_READ, totalRowsRead);
2894
+ span.setAttribute(ATTR_CLOUDFLARE_DO_SQL_RESPONSE_ROWS_WRITTEN, totalRowsWritten);
2895
+ span.end();
2896
+ return results;
2897
+ });
2898
+ }
2899
+ };
2900
+ return wrap(fn, fnHandler);
2901
+ }
2902
+ function instrumentSQLStorage(sql) {
2903
+ const sqlHandler = {
2904
+ get: (target, prop, receiver) => {
2905
+ const fn = Reflect.get(target, prop, receiver);
2906
+ if (typeof fn !== "function") {
2907
+ return fn;
2908
+ }
2909
+ switch (prop) {
2910
+ case "exec":
2911
+ return instrumentSQLStorageExec(fn, "exec");
2912
+ case "execBatch":
2913
+ return instrumentSQLStorageExecBatch(fn, "execBatch");
2914
+ default:
2915
+ return fn;
2916
+ }
2917
+ }
2918
+ };
2919
+ return wrap(sql, sqlHandler);
2920
+ }
2921
+
2922
+ function instrumentBindingStub(stub, nsName) {
2923
+ const stubHandler = {
2924
+ get(target, prop, receiver) {
2925
+ if (prop === "fetch") {
2926
+ const fetcher = Reflect.get(target, prop);
2927
+ const attrs = {
2928
+ name: `Durable Object ${nsName}`,
2929
+ "do.namespace": nsName,
2930
+ "do.id": target.id.toString(),
2931
+ "do.id.name": target.id.name
2932
+ };
2933
+ return instrumentClientFetch(fetcher, () => ({ includeTraceContext: true }), attrs);
2934
+ } else {
2935
+ return passthroughGet(target, prop, receiver);
2936
+ }
2937
+ }
2938
+ };
2939
+ return wrap(stub, stubHandler);
2940
+ }
2941
+ function instrumentBindingGet(getFn, nsName) {
2942
+ const getHandler = {
2943
+ apply(target, thisArg, argArray) {
2944
+ const stub = Reflect.apply(target, thisArg, argArray);
2945
+ return instrumentBindingStub(stub, nsName);
2946
+ }
2947
+ };
2948
+ return wrap(getFn, getHandler);
2949
+ }
2950
+ function instrumentDOBinding(ns, nsName) {
2951
+ const nsHandler = {
2952
+ get(target, prop, receiver) {
2953
+ if (prop === "get") {
2954
+ const fn = Reflect.get(ns, prop, receiver);
2955
+ return instrumentBindingGet(fn, nsName);
2956
+ } else {
2957
+ return passthroughGet(target, prop, receiver);
2958
+ }
2959
+ }
2960
+ };
2961
+ return wrap(ns, nsHandler);
2962
+ }
2963
+ function instrumentState(state) {
2964
+ const stateHandler = {
2965
+ get(target, prop, receiver) {
2966
+ const result = Reflect.get(target, prop, unwrap(receiver));
2967
+ if (prop === "storage") {
2968
+ return instrumentStorage(result);
2969
+ } else if (typeof result === "function") {
2970
+ return result.bind(target);
2971
+ } else {
2972
+ return result;
2973
+ }
2974
+ }
2975
+ };
2976
+ return wrap(state, stateHandler);
2977
+ }
2978
+ let cold_start$1 = true;
2979
+ function executeDOFetch(fetchFn, request, id) {
2980
+ const spanContext = getParentContextFromHeaders(request.headers);
2981
+ const tracer = trace.getTracer("DO fetchHandler");
2982
+ const attributes = {
2983
+ [SemanticAttributes.FAAS_TRIGGER]: "http",
2984
+ [SemanticAttributes.FAAS_COLDSTART]: cold_start$1
2985
+ };
2986
+ cold_start$1 = false;
2987
+ Object.assign(attributes, gatherRequestAttributes(request));
2988
+ Object.assign(attributes, gatherIncomingCfAttributes(request));
2989
+ const options = {
2990
+ attributes,
2991
+ kind: SpanKind.SERVER
2992
+ };
2993
+ const name = id.name || "";
2994
+ const promise = tracer.startActiveSpan(`Durable Object Fetch ${name}`, options, spanContext, async (span) => {
2995
+ try {
2996
+ const response = await fetchFn(request);
2997
+ if (response.ok) {
2998
+ span.setStatus({ code: SpanStatusCode.OK });
2999
+ }
3000
+ span.setAttributes(gatherResponseAttributes(response));
3001
+ span.end();
3002
+ return response;
3003
+ } catch (error) {
3004
+ span.recordException(error);
3005
+ span.setStatus({ code: SpanStatusCode.ERROR });
3006
+ span.end();
3007
+ throw error;
3008
+ }
3009
+ });
3010
+ return promise;
3011
+ }
3012
+ function executeDOAlarm(alarmFn, id) {
3013
+ const tracer = trace.getTracer("DO alarmHandler");
3014
+ const name = id.name || "";
3015
+ const promise = tracer.startActiveSpan(`Durable Object Alarm ${name}`, async (span) => {
3016
+ span.setAttribute(SemanticAttributes.FAAS_COLDSTART, cold_start$1);
3017
+ cold_start$1 = false;
3018
+ span.setAttribute("do.id", id.toString());
3019
+ if (id.name) span.setAttribute("do.name", id.name);
3020
+ try {
3021
+ await alarmFn();
3022
+ span.end();
3023
+ } catch (error) {
3024
+ span.recordException(error);
3025
+ span.setStatus({ code: SpanStatusCode.ERROR });
3026
+ span.end();
3027
+ throw error;
3028
+ }
3029
+ });
3030
+ return promise;
3031
+ }
3032
+ function instrumentFetchFn(fetchFn, initialiser, env, id) {
3033
+ const fetchHandler = {
3034
+ async apply(target, thisArg, argArray) {
3035
+ const request = argArray[0];
3036
+ const config = initialiser(env, request);
3037
+ const context$1 = setConfig(config);
3038
+ try {
3039
+ const bound = target.bind(unwrap(thisArg));
3040
+ return await context.with(context$1, executeDOFetch, void 0, bound, request, id);
3041
+ } catch (error) {
3042
+ throw error;
3043
+ }
3044
+ }
3045
+ };
3046
+ return wrap(fetchFn, fetchHandler);
3047
+ }
3048
+ function instrumentAlarmFn(alarmFn, initialiser, env, id) {
3049
+ if (!alarmFn) return void 0;
3050
+ const alarmHandler = {
3051
+ async apply(target, thisArg) {
3052
+ const config = initialiser(env, "do-alarm");
3053
+ const context$1 = setConfig(config);
3054
+ try {
3055
+ const bound = target.bind(unwrap(thisArg));
3056
+ return await context.with(context$1, executeDOAlarm, void 0, bound, id);
3057
+ } catch (error) {
3058
+ throw error;
3059
+ }
3060
+ }
3061
+ };
3062
+ return wrap(alarmFn, alarmHandler);
3063
+ }
3064
+ function instrumentAnyFn(fn, initialiser, env, _id) {
3065
+ if (!fn) return void 0;
3066
+ const fnHandler = {
3067
+ async apply(target, thisArg, argArray) {
3068
+ thisArg = unwrap(thisArg);
3069
+ const config = initialiser(env, "do-alarm");
3070
+ const context$1 = setConfig(config);
3071
+ try {
3072
+ const bound = target.bind(unwrap(thisArg));
3073
+ return await context.with(context$1, () => bound.apply(thisArg, argArray), void 0);
3074
+ } catch (error) {
3075
+ throw error;
3076
+ }
3077
+ }
3078
+ };
3079
+ return wrap(fn, fnHandler);
3080
+ }
3081
+ function instrumentDurableObject(doObj, initialiser, env, state, classStyle) {
3082
+ const objHandler = {
3083
+ get(target, prop) {
3084
+ if (classStyle && prop === "ctx") {
3085
+ return state;
3086
+ } else if (classStyle && prop === "env") {
3087
+ return env;
3088
+ } else if (prop === "fetch") {
3089
+ const fetchFn = Reflect.get(target, prop);
3090
+ return instrumentFetchFn(fetchFn, initialiser, env, state.id);
3091
+ } else if (prop === "alarm") {
3092
+ const alarmFn = Reflect.get(target, prop);
3093
+ return instrumentAlarmFn(alarmFn, initialiser, env, state.id);
3094
+ } else {
3095
+ const result = Reflect.get(target, prop);
3096
+ if (typeof result === "function") {
3097
+ result.bind(doObj);
3098
+ return instrumentAnyFn(result, initialiser, env, state.id);
3099
+ }
3100
+ return result;
3101
+ }
3102
+ }
3103
+ };
3104
+ return wrap(doObj, objHandler);
3105
+ }
3106
+ function instrumentDOClass(doClass, initialiser) {
3107
+ const classHandler = {
3108
+ construct(target, [orig_state, orig_env]) {
3109
+ const trigger = {
3110
+ id: orig_state.id.toString(),
3111
+ name: orig_state.id.name
3112
+ };
3113
+ const constructorConfig = initialiser(orig_env, trigger);
3114
+ const context$1 = setConfig(constructorConfig);
3115
+ const state = instrumentState(orig_state);
3116
+ const env = instrumentEnv(orig_env);
3117
+ const classStyle = doClass.prototype instanceof DurableObject;
3118
+ const createDO = () => {
3119
+ if (classStyle) {
3120
+ return new target(orig_state, orig_env);
3121
+ } else {
3122
+ return new target(state, env);
3123
+ }
3124
+ };
3125
+ const doObj = context.with(context$1, createDO);
3126
+ return instrumentDurableObject(doObj, initialiser, env, state, classStyle);
3127
+ }
3128
+ };
3129
+ return wrap(doClass, classHandler);
3130
+ }
3131
+
3132
+ const scheduledInstrumentation = {
3133
+ getInitialSpanInfo: function(controller) {
3134
+ const scheduledTimeISO = new Date(controller.scheduledTime).toISOString();
3135
+ return {
3136
+ name: `scheduledHandler ${controller.cron}`,
3137
+ options: {
3138
+ attributes: {
3139
+ [ATTR_FAAS_TRIGGER]: FAAS_TRIGGER_VALUE_TIMER,
3140
+ [ATTR_FAAS_CRON]: controller.cron,
3141
+ [ATTR_FAAS_TIME]: scheduledTimeISO,
3142
+ [ATTR_CLOUDFLARE_SCHEDULED_TIME]: scheduledTimeISO
3143
+ },
3144
+ kind: SpanKind.INTERNAL
3145
+ }
3146
+ };
3147
+ }
3148
+ };
3149
+
3150
+ function versionAttributes(env) {
3151
+ const attributes = {};
3152
+ if (typeof env === "object" && env !== null) {
3153
+ for (const [binding, data] of Object.entries(env)) {
3154
+ if (isVersionMetadata(data)) {
3155
+ attributes["cf.workers_version_metadata.binding"] = binding;
3156
+ attributes["cf.workers_version_metadata.id"] = data.id;
3157
+ attributes["cf.workers_version_metadata.tag"] = data.tag;
3158
+ break;
3159
+ }
3160
+ }
3161
+ }
3162
+ return attributes;
3163
+ }
3164
+
3165
+ class PromiseTracker {
3166
+ _outstandingPromises = [];
3167
+ get outstandingPromiseCount() {
3168
+ return this._outstandingPromises.length;
3169
+ }
3170
+ track(promise) {
3171
+ this._outstandingPromises.push(promise);
3172
+ }
3173
+ async wait() {
3174
+ await allSettledMutable(this._outstandingPromises);
3175
+ }
3176
+ }
3177
+ function createWaitUntil(fn, context, tracker) {
3178
+ const handler = {
3179
+ apply(target, _thisArg, argArray) {
3180
+ tracker.track(argArray[0]);
3181
+ return Reflect.apply(target, context, argArray);
3182
+ }
3183
+ };
3184
+ return wrap(fn, handler);
3185
+ }
3186
+ function proxyExecutionContext(context) {
3187
+ const tracker = new PromiseTracker();
3188
+ const ctx = new Proxy(context, {
3189
+ get(target, prop) {
3190
+ if (prop === "waitUntil") {
3191
+ const fn = Reflect.get(target, prop);
3192
+ return createWaitUntil(fn, context, tracker);
3193
+ } else {
3194
+ return passthroughGet(target, prop);
3195
+ }
3196
+ }
3197
+ });
3198
+ return { ctx, tracker };
3199
+ }
3200
+ async function allSettledMutable(promises) {
3201
+ let values;
3202
+ do {
3203
+ values = await Promise.allSettled(promises);
3204
+ } while (values.length !== promises.length);
3205
+ return values;
3206
+ }
3207
+
3208
+ function headerAttributes(message) {
3209
+ return Object.fromEntries([...message.headers].map(([key, value]) => [`email.header.${key}`, value]));
3210
+ }
3211
+ const emailInstrumentation = {
3212
+ getInitialSpanInfo: (message) => {
3213
+ const attributes = {
3214
+ [ATTR_FAAS_TRIGGER]: "other",
3215
+ [ATTR_RPC_MESSAGE_ID]: message.headers.get("Message-Id") ?? void 0,
3216
+ [ATTR_MESSAGING_DESTINATION_NAME]: message.to,
3217
+ [ATTR_CLOUDFLARE_EMAIL_FROM]: message.from,
3218
+ [ATTR_CLOUDFLARE_EMAIL_TO]: message.to,
3219
+ [ATTR_CLOUDFLARE_EMAIL_SIZE]: message.rawSize
3220
+ };
3221
+ Object.assign(attributes, headerAttributes(message));
3222
+ const options = {
3223
+ attributes,
3224
+ kind: SpanKind.CONSUMER
3225
+ };
3226
+ return {
3227
+ name: `emailHandler ${message.to}`,
3228
+ options
3229
+ };
3230
+ }
3231
+ };
3232
+
3233
+ function isRequest(trigger) {
3234
+ return trigger instanceof Request;
3235
+ }
3236
+ function isMessageBatch(trigger) {
3237
+ return !!trigger.ackAll;
3238
+ }
3239
+ function isAlarm(trigger) {
3240
+ return trigger === "do-alarm";
3241
+ }
3242
+ function findVersionMeta() {
3243
+ return Object.values(env).find((binding) => {
3244
+ return Object.getPrototypeOf(binding).constructor.name === "Object" && binding.id !== void 0 && binding.tag !== void 0;
3245
+ });
3246
+ }
3247
+ const createResource = (serviceConfig, versionMeta) => {
3248
+ console.log({ versionMeta });
3249
+ const workerResourceAttrs = {
3250
+ "cloud.provider": "cloudflare",
3251
+ "cloud.platform": "cloudflare.workers",
3252
+ "cloud.region": "earth",
3253
+ "faas.max_memory": 134217728,
3254
+ "telemetry.sdk.language": "js",
3255
+ "telemetry.sdk.name": "@inference-net/otel-cf-workers",
3256
+ "telemetry.sdk.version": PACKAGE_VERSION,
3257
+ "cf.worker.version.id": versionMeta?.id,
3258
+ "cf.worker.version.tag": versionMeta?.tag,
3259
+ "cf.worker.version.timestamp": versionMeta?.timestamp
3260
+ };
3261
+ const serviceResource = resourceFromAttributes({
3262
+ "service.name": serviceConfig.name,
3263
+ "service.namespace": serviceConfig.namespace,
3264
+ "service.version": serviceConfig.version
3265
+ });
3266
+ const resource = resourceFromAttributes(workerResourceAttrs);
3267
+ return resource.merge(serviceResource);
3268
+ };
3269
+ let initialised = false;
3270
+ function init(config, serviceConfig, propagator) {
3271
+ if (!initialised) {
3272
+ const resource = createResource(serviceConfig, findVersionMeta());
3273
+ if (config.trace) {
3274
+ if (config.trace.instrumentation.instrumentGlobalCache) {
3275
+ instrumentGlobalCache();
3276
+ }
3277
+ if (config.trace.instrumentation.instrumentGlobalFetch) {
3278
+ instrumentGlobalFetch();
3279
+ }
3280
+ const traceProvider = new WorkerTracerProvider(config.trace.spanProcessors, resource);
3281
+ traceProvider.register();
3282
+ }
3283
+ if (config.logs && config.logs.processors.length > 0) {
3284
+ const logsProvider = new WorkerLoggerProvider(config.logs.processors, resource);
3285
+ logsProvider.register();
3286
+ if (config.logs.instrumentation.instrumentConsole) {
3287
+ import('./console-Cy5QdByD.js').then(({ instrumentConsole }) => {
3288
+ instrumentConsole();
3289
+ });
3290
+ }
3291
+ }
3292
+ propagation.setGlobalPropagator(propagator);
3293
+ initialised = true;
3294
+ }
3295
+ }
3296
+ function createInitialiser(config) {
3297
+ if (typeof config === "function") {
3298
+ return (env2, trigger) => {
3299
+ const userConfig = config(env2, trigger);
3300
+ const conf = parseConfig(userConfig);
3301
+ const propagator = userConfig.propagator || new W3CTraceContextPropagator();
3302
+ init(conf, userConfig.service, propagator);
3303
+ return conf;
3304
+ };
3305
+ } else {
3306
+ return () => {
3307
+ const conf = parseConfig(config);
3308
+ const propagator = config.propagator || new W3CTraceContextPropagator();
3309
+ init(conf, config.service, propagator);
3310
+ return conf;
3311
+ };
3312
+ }
3313
+ }
3314
+ async function exportTelemetry(traceId, tracker) {
3315
+ const tracer = trace.getTracer("export");
3316
+ const { getLogger } = await Promise.resolve().then(() => provider);
3317
+ const logger = getLogger("export");
3318
+ if (tracer instanceof WorkerTracer) {
3319
+ await scheduler.wait(1);
3320
+ await tracker?.wait();
3321
+ await tracer.forceFlush(traceId);
3322
+ }
3323
+ if (logger && typeof logger.forceFlush === "function") {
3324
+ await logger.forceFlush();
3325
+ }
3326
+ }
3327
+ const exportSpans = exportTelemetry;
3328
+ let cold_start = true;
3329
+ function createHandlerFlowFn(instrumentation) {
3330
+ return (handlerFn, args) => {
3331
+ const [trigger, env2, context$1] = args;
3332
+ const proxiedEnv = instrumentEnv(env2);
3333
+ const { ctx: proxiedCtx, tracker } = proxyExecutionContext(context$1);
3334
+ const instrumentedTrigger = instrumentation.instrumentTrigger ? instrumentation.instrumentTrigger(trigger) : trigger;
3335
+ const tracer = trace.getTracer("handler");
3336
+ const { name, options, context: spanContext } = instrumentation.getInitialSpanInfo(trigger);
3337
+ const attrs = options.attributes || {};
3338
+ attrs["faas.coldstart"] = cold_start;
3339
+ options.attributes = attrs;
3340
+ Object.assign(attrs, versionAttributes(env2));
3341
+ cold_start = false;
3342
+ const parentContext = spanContext || context.active();
3343
+ const result = tracer.startActiveSpan(name, options, parentContext, async (span) => {
3344
+ try {
3345
+ const result2 = await handlerFn(instrumentedTrigger, proxiedEnv, proxiedCtx);
3346
+ if (instrumentation.getAttributesFromResult) {
3347
+ const attributes = instrumentation.getAttributesFromResult(result2);
3348
+ span.setAttributes(attributes);
3349
+ }
3350
+ if (instrumentation.executionSucces) {
3351
+ instrumentation.executionSucces(span, trigger, result2);
3352
+ }
3353
+ return result2;
3354
+ } catch (error) {
3355
+ span.recordException(error);
3356
+ span.setStatus({ code: SpanStatusCode.ERROR });
3357
+ if (instrumentation.executionFailed) {
3358
+ instrumentation.executionFailed(span, trigger, error);
3359
+ }
3360
+ throw error;
3361
+ } finally {
3362
+ span.end();
3363
+ context$1.waitUntil(exportTelemetry(span.spanContext().traceId, tracker));
3364
+ }
3365
+ });
3366
+ return result;
3367
+ };
3368
+ }
3369
+ function createHandlerProxy(handler, handlerFn, initialiser, instrumentation) {
3370
+ return (trigger, env2, ctx) => {
3371
+ const config = initialiser(env2, trigger);
3372
+ const context$1 = setConfig(config);
3373
+ const flowFn = createHandlerFlowFn(instrumentation);
3374
+ return context.with(context$1, flowFn, handler, handlerFn, [trigger, env2, ctx]);
3375
+ };
3376
+ }
3377
+ function instrument(handler, config) {
3378
+ const initialiser = createInitialiser(config);
3379
+ if (handler.fetch) {
3380
+ const fetcher = unwrap(handler.fetch);
3381
+ handler.fetch = createHandlerProxy(handler, fetcher, initialiser, fetchInstrumentation);
3382
+ }
3383
+ if (handler.scheduled) {
3384
+ const scheduler2 = unwrap(handler.scheduled);
3385
+ handler.scheduled = createHandlerProxy(handler, scheduler2, initialiser, scheduledInstrumentation);
3386
+ }
3387
+ if (handler.queue) {
3388
+ const queuer = unwrap(handler.queue);
3389
+ handler.queue = createHandlerProxy(handler, queuer, initialiser, new QueueInstrumentation());
3390
+ }
3391
+ if (handler.email) {
3392
+ const emailer = unwrap(handler.email);
3393
+ handler.email = createHandlerProxy(handler, emailer, initialiser, emailInstrumentation);
3394
+ }
3395
+ return handler;
3396
+ }
3397
+ function instrumentDO(doClass, config) {
3398
+ const initialiser = createInitialiser(config);
3399
+ return instrumentDOClass(doClass, initialiser);
3400
+ }
3401
+ const __unwrappedFetch = unwrap(fetch);
3402
+
3403
+ class MultiSpanExporter {
3404
+ exporters;
3405
+ constructor(exporters) {
3406
+ this.exporters = exporters;
3407
+ }
3408
+ export(items, resultCallback) {
3409
+ for (const exporter of this.exporters) {
3410
+ exporter.export(items, resultCallback);
3411
+ }
3412
+ }
3413
+ async shutdown() {
3414
+ for (const exporter of this.exporters) {
3415
+ await exporter.shutdown();
3416
+ }
3417
+ }
3418
+ }
3419
+ class MultiSpanExporterAsync {
3420
+ exporters;
3421
+ constructor(exporters) {
3422
+ this.exporters = exporters;
3423
+ }
3424
+ export(items, resultCallback) {
3425
+ const promises = this.exporters.map(
3426
+ (exporter) => new Promise((resolve) => {
3427
+ exporter.export(items, resolve);
3428
+ })
3429
+ );
3430
+ Promise.all(promises).then((results) => {
3431
+ const failed = results.filter((result) => result.code === ExportResultCode.FAILED);
3432
+ if (failed.length > 0) {
3433
+ resultCallback({ code: ExportResultCode.FAILED, error: failed[0].error });
3434
+ } else {
3435
+ resultCallback({ code: ExportResultCode.SUCCESS });
3436
+ }
3437
+ });
3438
+ }
3439
+ async shutdown() {
3440
+ await Promise.all(this.exporters.map((exporter) => exporter.shutdown()));
3441
+ }
3442
+ }
3443
+
3444
+ class OTLPTransport {
3445
+ name = "otlp";
3446
+ headers;
3447
+ url;
3448
+ constructor(config) {
3449
+ this.url = config.url;
3450
+ this.headers = Object.assign({}, DEFAULT_OTLP_HEADERS, config.headers);
3451
+ }
3452
+ export(logs, callback) {
3453
+ this._export(logs).then(() => {
3454
+ callback({ code: ExportResultCode.SUCCESS });
3455
+ }).catch((error) => {
3456
+ callback({ code: ExportResultCode.FAILED, error });
3457
+ });
3458
+ }
3459
+ async _export(logs) {
3460
+ try {
3461
+ await this.send(logs);
3462
+ } catch (e) {
3463
+ throw e;
3464
+ }
3465
+ }
3466
+ async send(logs) {
3467
+ const otlpLogs = this.transformToOTLP(logs);
3468
+ const body = JSON.stringify(otlpLogs);
3469
+ const params = {
3470
+ method: "POST",
3471
+ headers: this.headers,
3472
+ body
3473
+ };
3474
+ const response = await unwrap(fetch)(this.url, params);
3475
+ if (!response.ok) {
3476
+ throw new OTLPExporterError(`Exporter received a statusCode: ${response.status}`);
3477
+ }
3478
+ }
3479
+ transformToOTLP(logs) {
3480
+ const resourceLogsMap = /* @__PURE__ */ new Map();
3481
+ for (const log of logs) {
3482
+ const resourceKey = JSON.stringify(log.resource.attributes);
3483
+ const scopeKey = JSON.stringify(log.instrumentationScope);
3484
+ if (!resourceLogsMap.has(resourceKey)) {
3485
+ resourceLogsMap.set(resourceKey, /* @__PURE__ */ new Map());
3486
+ }
3487
+ const scopeLogsMap = resourceLogsMap.get(resourceKey);
3488
+ if (!scopeLogsMap.has(scopeKey)) {
3489
+ scopeLogsMap.set(scopeKey, []);
3490
+ }
3491
+ scopeLogsMap.get(scopeKey).push(log);
3492
+ }
3493
+ const resourceLogs = [];
3494
+ for (const [resourceKey, scopeLogsMap] of resourceLogsMap) {
3495
+ const resource = logs.find((l) => JSON.stringify(l.resource.attributes) === resourceKey).resource;
3496
+ const scopeLogs = [];
3497
+ for (const [_scopeKey, scopeRecords] of scopeLogsMap) {
3498
+ const scope = scopeRecords[0].instrumentationScope;
3499
+ scopeLogs.push({
3500
+ scope: {
3501
+ name: scope.name,
3502
+ version: scope.version
3503
+ },
3504
+ logRecords: scopeRecords.map((log) => this.transformLogRecord(log))
3505
+ });
3506
+ }
3507
+ resourceLogs.push({
3508
+ resource: {
3509
+ attributes: this.transformAttributes(resource.attributes)
3510
+ },
3511
+ scopeLogs
3512
+ });
3513
+ }
3514
+ return { resourceLogs };
3515
+ }
3516
+ transformLogRecord(log) {
3517
+ const record = {
3518
+ timeUnixNano: this.hrTimeToString(log.timeUnixNano),
3519
+ observedTimeUnixNano: this.hrTimeToString(log.observedTimeUnixNano),
3520
+ severityNumber: log.severityNumber,
3521
+ severityText: log.severityText,
3522
+ body: this.transformBody(log.body),
3523
+ attributes: this.transformAttributes(log.attributes),
3524
+ droppedAttributesCount: log.droppedAttributesCount || 0
3525
+ };
3526
+ if (log.traceId) {
3527
+ record.traceId = log.traceId;
3528
+ }
3529
+ if (log.spanId) {
3530
+ record.spanId = log.spanId;
3531
+ }
3532
+ if (log.traceFlags !== void 0) {
3533
+ record.flags = log.traceFlags;
3534
+ }
3535
+ return record;
3536
+ }
3537
+ transformBody(body) {
3538
+ if (body === void 0 || body === null) {
3539
+ return void 0;
3540
+ }
3541
+ if (typeof body === "string") {
3542
+ return { stringValue: body };
3543
+ }
3544
+ return { stringValue: JSON.stringify(body) };
3545
+ }
3546
+ transformAttributes(attrs) {
3547
+ return Object.entries(attrs).map(([key, value]) => ({
3548
+ key,
3549
+ value: this.transformAttributeValue(value)
3550
+ }));
3551
+ }
3552
+ transformAttributeValue(value) {
3553
+ if (typeof value === "string") {
3554
+ return { stringValue: value };
3555
+ } else if (typeof value === "number") {
3556
+ if (Number.isInteger(value)) {
3557
+ return { intValue: value.toString() };
3558
+ }
3559
+ return { doubleValue: value };
3560
+ } else if (typeof value === "boolean") {
3561
+ return { boolValue: value };
3562
+ } else if (Array.isArray(value)) {
3563
+ return {
3564
+ arrayValue: {
3565
+ values: value.map((v) => this.transformAttributeValue(v))
3566
+ }
3567
+ };
3568
+ }
3569
+ return { stringValue: String(value) };
3570
+ }
3571
+ hrTimeToString(hrTime) {
3572
+ const nanos = BigInt(hrTime[0]) * BigInt(1e9) + BigInt(hrTime[1]);
3573
+ return nanos.toString();
3574
+ }
3575
+ async shutdown() {
3576
+ }
3577
+ }
3578
+ class ConsoleTransport {
3579
+ name = "console";
3580
+ options;
3581
+ constructor(options = {}) {
3582
+ this.options = {
3583
+ pretty: options.pretty ?? true,
3584
+ colors: options.colors ?? false,
3585
+ includeTimestamp: options.includeTimestamp ?? true
3586
+ };
3587
+ }
3588
+ export(logs, callback) {
3589
+ try {
3590
+ for (const log of logs) {
3591
+ this.printLog(log);
3592
+ }
3593
+ callback({ code: ExportResultCode.SUCCESS });
3594
+ } catch (error) {
3595
+ callback({ code: ExportResultCode.FAILED, error });
3596
+ }
3597
+ }
3598
+ printLog(log) {
3599
+ if (this.options.pretty) {
3600
+ this.prettyPrint(log);
3601
+ } else {
3602
+ console.log(JSON.stringify(this.serializeLog(log)));
3603
+ }
3604
+ }
3605
+ prettyPrint(log) {
3606
+ const parts = [];
3607
+ if (this.options.includeTimestamp) {
3608
+ const timestamp = new Date(log.timeUnixNano[0] * 1e3).toISOString();
3609
+ parts.push(`[${timestamp}]`);
3610
+ }
3611
+ const severity = log.severityText || this.getSeverityText(log.severityNumber);
3612
+ parts.push(severity.padEnd(5));
3613
+ if (log.traceId) {
3614
+ parts.push(`[trace: ${log.traceId.substring(0, 16)}...]`);
3615
+ }
3616
+ const body = typeof log.body === "string" ? log.body : JSON.stringify(log.body);
3617
+ parts.push(body);
3618
+ const message = parts.join(" ");
3619
+ switch (severity) {
3620
+ case "TRACE":
3621
+ case "DEBUG":
3622
+ console.debug(message, log.attributes);
3623
+ break;
3624
+ case "INFO":
3625
+ console.info(message, log.attributes);
3626
+ break;
3627
+ case "WARN":
3628
+ console.warn(message, log.attributes);
3629
+ break;
3630
+ case "ERROR":
3631
+ case "FATAL":
3632
+ console.error(message, log.attributes);
3633
+ break;
3634
+ default:
3635
+ console.log(message, log.attributes);
3636
+ }
3637
+ }
3638
+ serializeLog(log) {
3639
+ return {
3640
+ timestamp: new Date(log.timeUnixNano[0] * 1e3).toISOString(),
3641
+ severity: log.severityText || this.getSeverityText(log.severityNumber),
3642
+ body: log.body,
3643
+ attributes: log.attributes,
3644
+ traceId: log.traceId,
3645
+ spanId: log.spanId,
3646
+ resource: log.resource.attributes,
3647
+ scope: log.instrumentationScope
3648
+ };
3649
+ }
3650
+ getSeverityText(severityNumber) {
3651
+ if (!severityNumber) return "INFO";
3652
+ if (severityNumber <= 4) return "TRACE";
3653
+ if (severityNumber <= 8) return "DEBUG";
3654
+ if (severityNumber <= 12) return "INFO";
3655
+ if (severityNumber <= 16) return "WARN";
3656
+ if (severityNumber <= 20) return "ERROR";
3657
+ return "FATAL";
3658
+ }
3659
+ async shutdown() {
3660
+ }
3661
+ }
3662
+
3663
+ export { BatchSizeLogRecordProcessor, BatchTraceSpanProcessor, ConsoleTransport, ImmediateLogRecordProcessor, MultiSpanExporter, MultiSpanExporterAsync, MultiTransportLogRecordProcessor, OTLPExporter, OTLPTransport, SEVERITY_NUMBERS, SpanImpl, WorkerLogger, WorkerLoggerProvider, __unwrappedFetch, createLogProcessor, createSampler, exportSpans, exportTelemetry, getGlobalLoggerProvider, getLogger, instrument, instrumentDO, isAlarm, isHeadSampled, isMessageBatch, isRequest, isRootErrorSpan, multiTailSampler, setGlobalLoggerProvider, withNextSpan };
3664
+ //# sourceMappingURL=index.js.map