UNPKG

autotel-cloudflare

Version:

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

1,030 lines (1,027 loc) 37.2 kB
import { wrap } from './chunk-O4IYKWPJ.js'; import { propagation, SpanKind, SpanStatusCode, context, trace } from '@opentelemetry/api'; import { createInitialiser, setConfig } from 'autotel-edge'; function getTracer() { return trace.getTracer("autotel-cloudflare-actors"); } function instrumentActorStorage(storage, actorInstance, actorClass) { if (!storage || typeof storage !== "object") { return storage; } const actorClassName = actorClass.name || "Actor"; const actorName = actorInstance.name || actorClassName; const storageHandler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "exec" && typeof value === "function") { return function instrumentedExec(query, ...params) { const tracer = getTracer(); const spanName = `Actor ${actorName}: storage.exec`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "db.system": "sqlite", "db.operation": "exec", "db.statement": query, "db.statement.params_count": params.length } }, (span) => { try { const result = value.call(target, query, ...params); 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 === "query" && typeof value === "function") { return function instrumentedQuery(query, ...params) { const tracer = getTracer(); const spanName = `Actor ${actorName}: storage.query`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "db.system": "sqlite", "db.operation": "query", "db.statement": query, "db.statement.params_count": params.length } }, (span) => { try { const result = value.call(target, query, ...params); 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 === "get" && typeof value === "function") { return async function instrumentedGet(key) { const tracer = getTracer(); const spanName = `Actor ${actorName}: storage.get`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "db.system": "durable_object_storage", "db.operation": "get", "db.key": key } }, async (span) => { try { const result = await value.call(target, key); span.setAttributes({ "db.result.found": result !== null && result !== void 0 }); 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 async function instrumentedPut(key, val) { const tracer = getTracer(); const spanName = `Actor ${actorName}: storage.put`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "db.system": "durable_object_storage", "db.operation": "put", "db.key": key, "db.value_type": typeof val } }, async (span) => { try { await value.call(target, key, val); 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(); } } ); }; } if (prop === "delete" && typeof value === "function") { return async function instrumentedDelete(key) { const tracer = getTracer(); const spanName = `Actor ${actorName}: storage.delete`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "db.system": "durable_object_storage", "db.operation": "delete", "db.key": key } }, async (span) => { try { const result = await value.call(target, key); span.setAttributes({ "db.result.deleted": 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 (typeof value === "function") { return value.bind(target); } return value; } }; return wrap(storage, storageHandler); } function getTracer2() { return trace.getTracer("autotel-cloudflare-actors"); } function instrumentActorAlarms(alarms, actorInstance, actorClass) { if (!alarms || typeof alarms !== "object") { return alarms; } const actorClassName = actorClass.name || "Actor"; const actorName = actorInstance.name || actorClassName; const alarmsHandler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "set" && typeof value === "function") { return async function instrumentedSet(...args) { const tracer = getTracer2(); const spanName = `Actor ${actorName}: alarms.set`; const alarmAttributes = { "actor.name": actorName, "actor.class": actorClassName, "alarm.operation": "set" }; if (args.length > 0) { const firstArg = args[0]; if (typeof firstArg === "number") { alarmAttributes["alarm.delay_ms"] = firstArg; } else if (firstArg instanceof Date) { alarmAttributes["alarm.scheduled_time"] = firstArg.toISOString(); } else if (typeof firstArg === "string") { alarmAttributes["alarm.cron"] = firstArg; } } return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: alarmAttributes }, async (span) => { try { const result = await value.apply(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 === "setMultiple" && typeof value === "function") { return async function instrumentedSetMultiple(alarmDefs) { const tracer = getTracer2(); const spanName = `Actor ${actorName}: alarms.setMultiple`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "alarm.operation": "setMultiple", "alarm.count": Array.isArray(alarmDefs) ? alarmDefs.length : 0 } }, async (span) => { try { const result = await value.call(target, alarmDefs); 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 === "cancel" && typeof value === "function") { return async function instrumentedCancel(alarmId) { const tracer = getTracer2(); const spanName = `Actor ${actorName}: alarms.cancel`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "alarm.operation": "cancel", "alarm.id": alarmId } }, async (span) => { try { const result = await value.call(target, alarmId); 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 === "cancelAll" && typeof value === "function") { return async function instrumentedCancelAll() { const tracer = getTracer2(); const spanName = `Actor ${actorName}: alarms.cancelAll`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "alarm.operation": "cancelAll" } }, async (span) => { try { const result = await value.call(target); 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 (typeof value === "function") { return value.bind(target); } return value; } }; return wrap(alarms, alarmsHandler); } function getTracer3() { return trace.getTracer("autotel-cloudflare-actors"); } function instrumentActorSockets(sockets, actorInstance, actorClass) { if (!sockets || typeof sockets !== "object") { return sockets; } const actorClassName = actorClass.name || "Actor"; const actorName = actorInstance.name || actorClassName; const socketsHandler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "acceptWebSocket" && typeof value === "function") { return function instrumentedAcceptWebSocket(request) { const tracer = getTracer3(); const spanName = `Actor ${actorName}: sockets.acceptWebSocket`; return tracer.startActiveSpan( spanName, { kind: SpanKind.SERVER, attributes: { "actor.name": actorName, "actor.class": actorClassName, "websocket.operation": "accept", "url.full": request.url } }, (span) => { try { const result = value.call(target, request); 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 === "broadcast" && typeof value === "function") { return function instrumentedBroadcast(message) { const tracer = getTracer3(); const spanName = `Actor ${actorName}: sockets.broadcast`; tracer.startActiveSpan( spanName, { kind: SpanKind.PRODUCER, attributes: { "actor.name": actorName, "actor.class": actorClassName, "websocket.operation": "broadcast", "websocket.message.type": typeof message, "websocket.message.size": typeof message === "string" ? message.length : message instanceof ArrayBuffer ? message.byteLength : 0 } }, (span) => { try { value.call(target, message); 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(); } } ); }; } if (prop === "send" && typeof value === "function") { return function instrumentedSend(ws, message) { const tracer = getTracer3(); const spanName = `Actor ${actorName}: sockets.send`; tracer.startActiveSpan( spanName, { kind: SpanKind.PRODUCER, attributes: { "actor.name": actorName, "actor.class": actorClassName, "websocket.operation": "send", "websocket.message.type": typeof message, "websocket.message.size": typeof message === "string" ? message.length : message instanceof ArrayBuffer ? message.byteLength : 0 } }, (span) => { try { value.call(target, ws, message); 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(); } } ); }; } if (prop === "getConnections" && typeof value === "function") { return function instrumentedGetConnections() { const tracer = getTracer3(); const spanName = `Actor ${actorName}: sockets.getConnections`; return tracer.startActiveSpan( spanName, { kind: SpanKind.CLIENT, attributes: { "actor.name": actorName, "actor.class": actorClassName, "websocket.operation": "getConnections" } }, (span) => { try { const result = value.call(target); if (Array.isArray(result)) { span.setAttribute("websocket.connections.count", result.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(); } } ); }; } if (typeof value === "function") { return value.bind(target); } return value; } }; return wrap(sockets, socketsHandler); } // src/actors/instrument-actor.ts var coldStarts = /* @__PURE__ */ new WeakMap(); function isColdStart(actorClass) { if (!coldStarts.has(actorClass)) { coldStarts.set(actorClass, true); return true; } return false; } function getTracer4() { return trace.getTracer("autotel-cloudflare-actors"); } function defaultSpanNameFormatter(actorName, actorClass, lifecycle) { const displayName = actorName || actorClass; return `Actor ${displayName}: ${lifecycle}`; } function createActorAttributes(actorInstance, actorClass, lifecycle) { return { "actor.name": actorInstance.name || "unknown", "actor.class": actorClass.name || "Actor", "actor.lifecycle": lifecycle, "actor.coldstart": isColdStart(actorClass), ...actorInstance.identifier && { "actor.identifier": actorInstance.identifier } }; } function instrumentOnInit(originalMethod, actorInstance, actorClass, options) { return async function instrumentedOnInit() { const tracer = getTracer4(); const actorClassName = actorClass.name || "Actor"; const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "init") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "init"); return tracer.startActiveSpan( spanName, { kind: SpanKind.INTERNAL, attributes: createActorAttributes(actorInstance, actorClass, "init") }, async (span) => { try { await originalMethod.call(actorInstance); 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(); } } ); }; } function instrumentOnRequest(originalMethod, actorInstance, actorClass, options) { return async function instrumentedOnRequest(request) { const tracer = getTracer4(); const parentContext = propagation.extract(context.active(), request.headers); const url = new URL(request.url); const actorClassName = actorClass.name || "Actor"; const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "request") : `Actor ${actorInstance.name || actorClassName}: ${request.method} ${url.pathname}`; return tracer.startActiveSpan( spanName, { kind: SpanKind.SERVER, attributes: { ...createActorAttributes(actorInstance, actorClass, "request"), "http.request.method": request.method, "url.full": request.url, "url.path": url.pathname, "url.query": url.search } }, parentContext, async (span) => { try { const response = await originalMethod.call(actorInstance, request); span.setAttributes({ "http.response.status_code": response.status }); if (response.ok) { span.setStatus({ code: SpanStatusCode.OK }); } else { span.setStatus({ code: SpanStatusCode.ERROR }); } 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(); } } ); }; } function instrumentOnAlarm(originalMethod, actorInstance, actorClass, options) { return async function instrumentedOnAlarm(alarmInfo) { const tracer = getTracer4(); const actorClassName = actorClass.name || "Actor"; const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "alarm") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "alarm"); return tracer.startActiveSpan( spanName, { kind: SpanKind.INTERNAL, attributes: { ...createActorAttributes(actorInstance, actorClass, "alarm"), "faas.trigger": "timer" } }, async (span) => { try { await originalMethod.call(actorInstance, alarmInfo); 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(); } } ); }; } function instrumentOnPersist(originalMethod, actorInstance, actorClass, options) { if (!options.capturePersistEvents) { return originalMethod; } return function instrumentedOnPersist(key, value) { const tracer = getTracer4(); const actorClassName = actorClass.name || "Actor"; const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "persist") : `Actor ${actorInstance.name || actorClassName}: persist ${key}`; tracer.startActiveSpan( spanName, { kind: SpanKind.INTERNAL, attributes: { ...createActorAttributes(actorInstance, actorClass, "persist"), "actor.persist.key": key, "actor.persist.value_type": typeof value } }, (span) => { try { originalMethod.call(actorInstance, key, value); 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(); } } ); }; } function instrumentWebSocketConnect(originalMethod, actorInstance, actorClass, options) { return function instrumentedWebSocketConnect(ws, request) { const tracer = getTracer4(); const actorClassName = actorClass.name || "Actor"; const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "websocket.connect") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "websocket.connect"); tracer.startActiveSpan( spanName, { kind: SpanKind.SERVER, attributes: { ...createActorAttributes(actorInstance, actorClass, "websocket.connect"), "url.full": request.url } }, (span) => { try { originalMethod.call(actorInstance, ws, request); 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(); } } ); }; } function instrumentWebSocketMessage(originalMethod, actorInstance, actorClass, options) { return function instrumentedWebSocketMessage(ws, message) { const tracer = getTracer4(); const actorClassName = actorClass.name || "Actor"; const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "websocket.message") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "websocket.message"); tracer.startActiveSpan( spanName, { kind: SpanKind.SERVER, attributes: { ...createActorAttributes(actorInstance, actorClass, "websocket.message"), "websocket.message.type": typeof message, "websocket.message.size": typeof message === "string" ? message.length : message instanceof ArrayBuffer ? message.byteLength : 0 } }, (span) => { try { originalMethod.call(actorInstance, ws, message); 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(); } } ); }; } function instrumentWebSocketDisconnect(originalMethod, actorInstance, actorClass, options) { return function instrumentedWebSocketDisconnect(ws) { const tracer = getTracer4(); const actorClassName = actorClass.name || "Actor"; const spanName = options.spanNameFormatter ? options.spanNameFormatter(actorInstance.name || "", "websocket.disconnect") : defaultSpanNameFormatter(actorInstance.name || "", actorClassName, "websocket.disconnect"); tracer.startActiveSpan( spanName, { kind: SpanKind.SERVER, attributes: createActorAttributes(actorInstance, actorClass, "websocket.disconnect") }, (span) => { try { originalMethod.call(actorInstance, ws); 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(); } } ); }; } function instrumentActorInstance(actorInstance, _state, _env, actorClass, options) { const instanceHandler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "onInit" && typeof value === "function") { return instrumentOnInit(value.bind(target), target, actorClass, options); } if (prop === "onRequest" && typeof value === "function") { return instrumentOnRequest(value.bind(target), target, actorClass, options); } if (prop === "onAlarm" && typeof value === "function") { return instrumentOnAlarm(value.bind(target), target, actorClass, options); } if (prop === "onPersist" && typeof value === "function") { return instrumentOnPersist(value.bind(target), target, actorClass, options); } if (prop === "onWebSocketConnect" && typeof value === "function") { return instrumentWebSocketConnect(value.bind(target), target, actorClass, options); } if (prop === "onWebSocketMessage" && typeof value === "function") { return instrumentWebSocketMessage(value.bind(target), target, actorClass, options); } if (prop === "onWebSocketDisconnect" && typeof value === "function") { return instrumentWebSocketDisconnect(value.bind(target), target, actorClass, options); } if (prop === "storage" && value && options.instrumentStorage !== false) { return instrumentActorStorage(value, target, actorClass); } if (prop === "alarms" && value && options.instrumentAlarms !== false) { return instrumentActorAlarms(value, target, actorClass); } if (prop === "sockets" && value && options.instrumentSockets !== false) { return instrumentActorSockets(value, target, actorClass); } if (typeof value === "function") { return value.bind(target); } return value; } }; return wrap(actorInstance, instanceHandler); } function instrumentActor(actorClass, config) { const initialiser = createInitialiser(config); const defaultOptions = { instrumentStorage: true, instrumentAlarms: true, instrumentSockets: true, capturePersistEvents: true }; const classHandler = { construct(target, [state, env]) { const resolvedConfig = typeof config === "function" ? config(env, { id: state.id.toString(), name: state.id.name }) : config; const actorOptions = resolvedConfig && typeof resolvedConfig === "object" && "actors" in resolvedConfig ? resolvedConfig.actors : void 0; const options = { ...defaultOptions, ...actorOptions }; const trigger = { id: state.id.toString(), name: state.id.name }; const telemetryConfig = initialiser(env, trigger); const context$1 = setConfig(telemetryConfig); const actorInstance = context.with(context$1, () => { return new target(state, env); }); return instrumentActorInstance(actorInstance, state, env, actorClass, options); } }; return wrap(actorClass, classHandler); } function getTracer5() { return trace.getTracer("autotel-cloudflare-actors"); } function tracedHandler(actorClass, config) { const initialiser = createInitialiser(config); return { async fetch(request, env, _ctx) { const telemetryConfig = initialiser(env, { type: "http" }); const configContext = setConfig(telemetryConfig); const parentContext = propagation.extract(configContext, request.headers); const tracer = getTracer5(); const url = new URL(request.url); const actorClassName = actorClass.name || "Actor"; let actorName; try { if (actorClass.nameFromRequest) { actorName = await actorClass.nameFromRequest(request); } } catch { actorName = void 0; } const spanName = `${actorClassName} handler: ${request.method} ${url.pathname}`; return tracer.startActiveSpan( spanName, { kind: SpanKind.SERVER, attributes: { "http.request.method": request.method, "url.full": request.url, "url.path": url.pathname, "url.query": url.search, "actor.class": actorClassName, ...actorName && { "actor.name": actorName }, "faas.trigger": "http" } }, parentContext, async (span) => { try { const envObj = env; const bindingName = Object.keys(envObj).find((key) => { const binding = env.__DURABLE_OBJECT_BINDINGS; return key === actorClassName || binding?.[key]?.class_name === actorClassName; }); if (!bindingName) { span.setStatus({ code: SpanStatusCode.ERROR, message: `No Durable Object binding found for ${actorClassName}` }); return Response.json( { error: "Configuration Error", message: `No Durable Object binding found for actor class ${actorClassName}` }, { status: 500, headers: { "Content-Type": "application/json" } } ); } const namespace = envObj[bindingName]; const idString = actorName || "default"; const locationHint = actorClass.configuration?.(request)?.locationHint; const stub = namespace.getByName(idString, { locationHint }); if ("setName" in stub && typeof stub.setName === "function") { stub.setName(idString); } const headers = new Headers(request.headers); propagation.inject(context.active(), headers); const tracedRequest = new Request(request.url, { method: request.method, headers, body: request.body, redirect: request.redirect }); const response = await stub.fetch(tracedRequest); span.setAttributes({ "http.response.status_code": response.status, "actor.name": idString }); if (response.ok) { span.setStatus({ code: SpanStatusCode.OK }); } else { span.setStatus({ code: SpanStatusCode.ERROR }); } return response; } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error instanceof Error ? error.message : String(error) }); return Response.json( { error: "Internal Server Error", message: error instanceof Error ? error.message : "Unknown error" }, { status: 500, headers: { "Content-Type": "application/json" } } ); } finally { span.end(); } } ); } }; } function wrapHandler(originalHandler, config) { const initialiser = createInitialiser(config); return { async fetch(request, env, ctx) { const telemetryConfig = initialiser(env, { type: "http" }); const configContext = setConfig(telemetryConfig); const parentContext = propagation.extract(configContext, request.headers); const tracer = getTracer5(); const url = new URL(request.url); return tracer.startActiveSpan( `Worker: ${request.method} ${url.pathname}`, { kind: SpanKind.SERVER, attributes: { "http.request.method": request.method, "url.full": request.url, "url.path": url.pathname, "url.query": url.search, "faas.trigger": "http" } }, parentContext, async (span) => { try { const headers = new Headers(request.headers); propagation.inject(context.active(), headers); const tracedRequest = new Request(request.url, { method: request.method, headers, body: request.body, redirect: request.redirect }); const response = await originalHandler.fetch(tracedRequest, env, ctx); span.setAttributes({ "http.response.status_code": response.status }); if (response.ok) { span.setStatus({ code: SpanStatusCode.OK }); } else { span.setStatus({ code: SpanStatusCode.ERROR }); } 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(); } } ); } }; } export { instrumentActor, instrumentActorAlarms, instrumentActorSockets, instrumentActorStorage, tracedHandler, wrapHandler }; //# sourceMappingURL=actors.js.map //# sourceMappingURL=actors.js.map