UNPKG

autotel-cloudflare

Version:

The #1 OpenTelemetry package for Cloudflare Workers - complete bindings coverage, native CF OTel integration, advanced sampling

1,084 lines (1,081 loc) 39.9 kB
import { wrap, isWrapped, setAttr } from './chunk-O4IYKWPJ.js'; import { trace, SpanKind, SpanStatusCode } from '@opentelemetry/api'; import { getActiveConfig } from 'autotel-edge'; function instrumentAI(ai, bindingName) { const name = bindingName || "ai"; const handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "run" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [model] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `AI ${name}: run ${model}`, { kind: SpanKind.CLIENT, attributes: { "gen_ai.system": "cloudflare-workers-ai", "gen_ai.operation.name": "run", "gen_ai.request.model": model } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); if (result?.usage?.prompt_tokens !== void 0) { setAttr(span, "gen_ai.usage.input_tokens", Number(result.usage.prompt_tokens)); } if (result?.usage?.completion_tokens !== void 0) { setAttr(span, "gen_ai.usage.output_tokens", Number(result.usage.completion_tokens)); } span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(ai, handler); } var TRACED_METHODS = ["query", "insert", "upsert", "deleteByIds", "getByIds", "describe"]; function instrumentVectorize(vectorize, indexName) { const name = indexName || "vectorize"; const handler = { get(target, prop) { const value = Reflect.get(target, prop); if (typeof prop === "string" && TRACED_METHODS.includes(prop) && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const operation = prop; const tracer = trace.getTracer("autotel-edge"); const attributes = { "db.system": "cloudflare-vectorize", "db.operation": operation, "db.collection.name": name }; if (operation === "query") { const queryInput = args[0]; if (queryInput?.topK !== void 0) { attributes["db.vectorize.top_k"] = queryInput.topK; } } if ((operation === "insert" || operation === "upsert") && Array.isArray(args[0])) { attributes["db.vectorize.vectors_count"] = args[0].length; } return tracer.startActiveSpan( `Vectorize ${name}: ${operation}`, { kind: SpanKind.CLIENT, attributes }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); if (operation === "query" && result?.matches) { setAttr(span, "db.vectorize.matches_count", result.matches.length); } span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(vectorize, handler); } function instrumentHyperdrive(hyperdrive, bindingName) { const name = bindingName || "hyperdrive"; const handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "connect" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const tracer = trace.getTracer("autotel-edge"); const attributes = { "db.system": "cloudflare-hyperdrive", "db.operation": "connect" }; try { setAttr({ setAttribute: (k, v) => { if (v !== void 0 && v !== null) attributes[k] = v; } }, "server.address", target.host); setAttr({ setAttribute: (k, v) => { if (v !== void 0 && v !== null) attributes[k] = v; } }, "server.port", target.port); setAttr({ setAttribute: (k, v) => { if (v !== void 0 && v !== null) attributes[k] = v; } }, "db.user", target.user); } catch { } return tracer.startActiveSpan( `Hyperdrive ${name}: connect`, { kind: SpanKind.CLIENT, attributes }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(hyperdrive, handler); } function instrumentQueueProducer(queue, queueName) { const name = queueName || "queue"; const handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "send" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `Queue ${name}: send`, { kind: SpanKind.PRODUCER, attributes: { "messaging.system": "cloudflare-queues", "messaging.operation.type": "publish", "messaging.operation": "send", "messaging.destination.name": name } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); setAttr(span, "messaging.message.id", result?.messageId); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } if (prop === "sendBatch" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [messages] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `Queue ${name}: sendBatch`, { kind: SpanKind.PRODUCER, attributes: { "messaging.system": "cloudflare-queues", "messaging.operation.type": "publish", "messaging.operation": "sendBatch", "messaging.destination.name": name, "messaging.batch.message_count": Array.isArray(messages) ? messages.length : 0 } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(queue, handler); } function instrumentAnalyticsEngine(ae, datasetName) { const name = datasetName || "analytics-engine"; const handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "writeDataPoint" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [dataPoint] = args; const tracer = trace.getTracer("autotel-edge"); const attributes = { "analytics.system": "cloudflare-analytics-engine", "analytics.operation": "writeDataPoint" }; if (dataPoint) { if (dataPoint.indexes) { attributes["analytics.indexes_count"] = Array.isArray(dataPoint.indexes) ? dataPoint.indexes.length : 1; } if (dataPoint.doubles) { attributes["analytics.doubles_count"] = dataPoint.doubles.length; } if (dataPoint.blobs) { attributes["analytics.blobs_count"] = dataPoint.blobs.length; } } return tracer.startActiveSpan( `AnalyticsEngine ${name}: writeDataPoint`, { kind: SpanKind.CLIENT, attributes }, (span) => { try { Reflect.apply(fnTarget, target, args); span.setStatus({ code: SpanStatusCode.OK }); } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(ae, handler); } var pipelineMetaSymbol = /* @__PURE__ */ Symbol("images-pipeline-meta"); function proxyTransformer(transformer, meta, bindingName) { const handler = { get(target, prop) { const value = Reflect.get(target, prop); if ((prop === "transform" || prop === "draw") && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { meta.operationCount++; const result = Reflect.apply(fnTarget, target, args); if (result === target || result && typeof result === "object" && "output" in result) { return proxyTransformer(result, meta, bindingName); } return result; } }); } if (prop === "output" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const tracer = trace.getTracer("autotel-edge"); const [formatOrOptions] = args; const attributes = { "images.system": "cloudflare-images", "images.pipeline.operation_count": meta.operationCount }; if (typeof formatOrOptions === "string") { attributes["images.output.format"] = formatOrOptions; } else if (formatOrOptions && typeof formatOrOptions === "object") { const fmt = formatOrOptions.format; if (fmt) attributes["images.output.format"] = fmt; } return tracer.startActiveSpan( `Images ${bindingName}: output`, { kind: SpanKind.CLIENT, attributes }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; const proxy = new Proxy(transformer, handler); Object.defineProperty(proxy, pipelineMetaSymbol, { value: meta, writable: false, enumerable: false, configurable: false }); return proxy; } function instrumentImages(images, bindingName) { const name = bindingName || "images"; const handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "info" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `Images ${name}: info`, { kind: SpanKind.CLIENT, attributes: { "images.system": "cloudflare-images", "images.operation": "info" } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); setAttr(span, "images.width", result?.width); setAttr(span, "images.height", result?.height); setAttr(span, "images.format", result?.format); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } if (prop === "input" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const transformer = Reflect.apply(fnTarget, target, args); const meta = { operationCount: 0 }; return proxyTransformer(transformer, meta, name); } }); } return value; } }; return wrap(images, handler); } // src/bindings/bindings.ts function sanitizeStatement(query, mode) { if (mode === "off") return void 0; if (mode === "obfuscated") return query.replaceAll(/'[^']*'/g, "'?'").replaceAll(/\b\d+\b/g, "?"); return query; } function instrumentKV(kv, namespaceName) { const name = namespaceName || "kv"; const kvHandler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "get" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [key, options] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `KV ${name}: get`, { kind: SpanKind.CLIENT, attributes: { "db.system": "cloudflare-kv", "db.operation": "get", "db.namespace": name, "db.key": key, "db.cache_hit": options?.cacheTtl !== void 0 } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setAttribute("db.result.type", result === null ? "null" : typeof result); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } if (prop === "put" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [key] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `KV ${name}: put`, { kind: SpanKind.CLIENT, attributes: { "db.system": "cloudflare-kv", "db.operation": "put", "db.namespace": name, "db.key": key } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } if (prop === "delete" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [key] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `KV ${name}: delete`, { kind: SpanKind.CLIENT, attributes: { "db.system": "cloudflare-kv", "db.operation": "delete", "db.namespace": name, "db.key": key } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } if (prop === "list" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [options] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `KV ${name}: list`, { kind: SpanKind.CLIENT, attributes: { "db.system": "cloudflare-kv", "db.operation": "list", "db.namespace": name, "db.prefix": options?.prefix || void 0, "db.limit": options?.limit || void 0 } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setAttribute("db.result.keys_count", result.keys.length); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(kv, kvHandler); } function instrumentR2(r2, bucketName) { const name = bucketName || "r2"; const r2Handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "get" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [key] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `R2 ${name}: get`, { kind: SpanKind.CLIENT, attributes: { "db.system": "cloudflare-r2", "db.operation": "get", "db.bucket": name, "db.key": key } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); if (result) { span.setAttribute("db.result.size", result.size); span.setAttribute("db.result.etag", result.etag); span.setAttribute("db.result.content_type", result.httpMetadata?.contentType); } else { span.setAttribute("db.result.exists", false); } span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } if (prop === "put" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [key] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `R2 ${name}: put`, { kind: SpanKind.CLIENT, attributes: { "db.system": "cloudflare-r2", "db.operation": "put", "db.bucket": name, "db.key": key } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setAttribute("db.result.etag", result.etag); span.setAttribute("db.result.uploaded", result.uploaded); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } if (prop === "delete" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const keys = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `R2 ${name}: delete`, { kind: SpanKind.CLIENT, attributes: { "db.system": "cloudflare-r2", "db.operation": "delete", "db.bucket": name, "db.keys_count": keys.length } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } if (prop === "list" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [options] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `R2 ${name}: list`, { kind: SpanKind.CLIENT, attributes: { "db.system": "cloudflare-r2", "db.operation": "list", "db.bucket": name, "db.prefix": options?.prefix || void 0, "db.limit": options?.limit || void 0 } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setAttribute("db.result.objects_count", result.objects.length); span.setAttribute("db.result.truncated", result.truncated); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(r2, r2Handler); } function instrumentD1(d1, databaseName) { const name = databaseName || "d1"; const d1Handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "prepare" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [query] = args; const tracer = trace.getTracer("autotel-edge"); const prepared = Reflect.apply(fnTarget, target, args); const preparedHandler = { get(target2, prop2) { const value2 = Reflect.get(target2, prop2); if (prop2 === "first" || prop2 === "run" || prop2 === "all" || prop2 === "raw") { return new Proxy(value2, { apply: (fnTarget2, _thisArg2, args2) => { const activeConfig = getActiveConfig(); const captureMode = activeConfig?.dataSafety?.captureDbStatement ?? "full"; const statement = sanitizeStatement(query, captureMode); const attributes = { "db.system": "cloudflare-d1", "db.operation": prop2, "db.name": name }; if (statement !== void 0) { attributes["db.statement"] = statement; } return tracer.startActiveSpan( `D1 ${name}: ${prop2}`, { kind: SpanKind.CLIENT, attributes }, async (span) => { try { const result = await Reflect.apply(fnTarget2, target2, args2); if (prop2 === "all" && Array.isArray(result)) { span.setAttribute("db.result.rows_count", result.length); } else if (prop2 === "first" && result) { span.setAttribute("db.result.exists", true); } span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value2; } }; return wrap(prepared, preparedHandler); } }); } if (prop === "exec" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [query] = args; const tracer = trace.getTracer("autotel-edge"); const activeConfig = getActiveConfig(); const captureMode = activeConfig?.dataSafety?.captureDbStatement ?? "full"; const statement = sanitizeStatement(query, captureMode); const attributes = { "db.system": "cloudflare-d1", "db.operation": "exec", "db.name": name }; if (statement !== void 0) { attributes["db.statement"] = statement; } return tracer.startActiveSpan( `D1 ${name}: exec`, { kind: SpanKind.CLIENT, attributes }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); span.setAttribute("db.result.count", result.count); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(d1, d1Handler); } function instrumentServiceBinding(fetcher, serviceName) { const name = serviceName || "service"; const fetcherHandler = { get(target, prop) { if (prop === "fetch" && typeof target.fetch === "function") { const tracedFetch = (...args) => { const [input, init] = args; const request = new Request(input, init); const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `Service ${name}: ${request.method}`, { kind: SpanKind.CLIENT, attributes: { "rpc.system": "cloudflare-service-binding", "rpc.service": name, "http.request.method": request.method, "url.full": request.url } }, async (span) => { try { const response = await target.fetch(input, init); span.setAttribute("http.response.status_code", response.status); span.setStatus({ code: SpanStatusCode.OK }); return response; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); }; return tracedFetch; } const value = Reflect.get(target, prop); if (typeof value === "function") { return value.bind(target); } return value; } }; return wrap(fetcher, fetcherHandler); } var hasMethod = (obj, m) => typeof obj?.[m] === "function"; var hasExactMethods = (obj, methods) => methods.every((m) => hasMethod(obj, m)); var envCache = /* @__PURE__ */ new WeakMap(); function instrumentBindings(env) { const cached = envCache.get(env); if (cached) return cached; const instrumented = {}; for (const [key, value] of Object.entries(env)) { if (!value || typeof value !== "object") { instrumented[key] = value; continue; } if (isWrapped(value)) { instrumented[key] = value; continue; } if (hasExactMethods(value, ["get", "put", "delete", "list", "head"])) { instrumented[key] = instrumentR2(value, key); continue; } if (hasExactMethods(value, ["get", "put", "delete", "list"]) && !("head" in value)) { instrumented[key] = instrumentKV(value, key); continue; } if (hasExactMethods(value, ["prepare", "exec"])) { instrumented[key] = instrumentD1(value, key); continue; } if (hasExactMethods(value, ["query", "insert", "upsert", "describe"])) { instrumented[key] = instrumentVectorize(value, key); continue; } if (hasMethod(value, "run") && ("gateway" in value || "models" in value)) { instrumented[key] = instrumentAI(value, key); continue; } if (hasMethod(value, "connect") && "connectionString" in value && "host" in value) { instrumented[key] = instrumentHyperdrive(value, key); continue; } if (hasExactMethods(value, ["send", "sendBatch"]) && !("get" in value)) { instrumented[key] = instrumentQueueProducer(value, key); continue; } if (hasMethod(value, "writeDataPoint")) { instrumented[key] = instrumentAnalyticsEngine(value, key); continue; } if (hasExactMethods(value, ["info", "input"])) { instrumented[key] = instrumentImages(value, key); continue; } if (hasMethod(value, "fetch")) { instrumented[key] = instrumentServiceBinding(value, key); continue; } instrumented[key] = value; } envCache.set(env, instrumented); return instrumented; } function instrumentRateLimiter(limiter, bindingName) { const name = bindingName || "rate-limiter"; const handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "limit" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [options] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `RateLimiter ${name}: limit`, { kind: SpanKind.CLIENT, attributes: { "rate_limiter.system": "cloudflare-rate-limiter", "rate_limiter.key": options?.key } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); setAttr(span, "rate_limiter.success", result?.success); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(limiter, handler); } function instrumentBrowserRendering(browser, bindingName) { const name = bindingName || "browser"; const handler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "fetch" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, _thisArg, args) => { const [input] = args; const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `BrowserRendering ${name}: fetch`, { kind: SpanKind.CLIENT, attributes: { "browser.system": "cloudflare-browser-rendering", "url.full": url } }, async (span) => { try { const result = await Reflect.apply(fnTarget, target, args); setAttr(span, "http.response.status_code", result?.status); span.setStatus({ code: SpanStatusCode.OK }); return result; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); throw error; } finally { span.end(); } } ); } }); } return value; } }; return wrap(browser, handler); } export { instrumentAI, instrumentAnalyticsEngine, instrumentBindings, instrumentBrowserRendering, instrumentD1, instrumentHyperdrive, instrumentImages, instrumentKV, instrumentQueueProducer, instrumentR2, instrumentRateLimiter, instrumentServiceBinding, instrumentVectorize }; //# sourceMappingURL=chunk-KAUHT25H.js.map //# sourceMappingURL=chunk-KAUHT25H.js.map