UNPKG

autotel-cloudflare

Version:

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

333 lines (331 loc) 11 kB
import { wrap } from './chunk-O4IYKWPJ.js'; import { context, trace, propagation, SpanKind, SpanStatusCode } from '@opentelemetry/api'; import { createInitialiser, setConfig } from 'autotel-edge'; var coldStarts = /* @__PURE__ */ new WeakMap(); function isColdStart(doClass) { if (!coldStarts.has(doClass)) { coldStarts.set(doClass, true); return true; } return false; } function instrumentDOFetch(fetchFn, id, doClass) { return async function instrumentedFetch(request) { const tracer = trace.getTracer("autotel-edge"); const parentContext = propagation.extract( context.active(), request.headers ); const url = new URL(request.url); const spanName = `DO ${id.name || id.toString()}: ${request.method} ${url.pathname}`; return tracer.startActiveSpan( spanName, { kind: SpanKind.SERVER, attributes: { "http.request.method": request.method, "url.full": request.url, "do.id": id.toString(), "do.id.name": id.name || "", "faas.trigger": "http", "faas.coldstart": isColdStart(doClass) } }, parentContext, async (span) => { try { const response = await fetchFn.call(this, 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 instrumentDOAlarm(alarmFn, id, doClass) { return async function instrumentedAlarm() { const tracer = trace.getTracer("autotel-edge"); const spanName = `DO ${id.name || id.toString()}: alarm`; return tracer.startActiveSpan( spanName, { kind: SpanKind.INTERNAL, attributes: { "do.id": id.toString(), "do.id.name": id.name || "", "faas.trigger": "timer", "faas.coldstart": isColdStart(doClass) } }, async (span) => { try { await alarmFn.call(this); 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 instrumentDOInstance(doInstance, state, _env, doClass) { const instanceHandler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "fetch" && typeof value === "function") { return instrumentDOFetch(value.bind(target), state.id, doClass); } if (prop === "alarm" && typeof value === "function") { return instrumentDOAlarm(value.bind(target), state.id, doClass); } if (typeof value === "function") { return value.bind(target); } return value; } }; return wrap(doInstance, instanceHandler); } function instrumentDO(doClass, config) { const initialiser = createInitialiser(config); const classHandler = { construct(target, [state, env]) { const trigger = { id: state.id.toString(), name: state.id.name }; const doConfig = initialiser(env, trigger); const context$1 = setConfig(doConfig); const doInstance = context.with(context$1, () => { return new target(state, env); }); return instrumentDOInstance(doInstance, state, env, doClass); } }; return wrap(doClass, classHandler); } var coldStarts2 = /* @__PURE__ */ new WeakMap(); function isColdStart2(workflowClass) { if (!coldStarts2.has(workflowClass)) { coldStarts2.set(workflowClass, true); return true; } return false; } function instrumentWorkflowStep(step, workflowName) { const stepHandler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "do" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, thisArg, args) => { const [stepName] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `Workflow ${workflowName}: ${stepName}`, { kind: SpanKind.INTERNAL, attributes: { "workflow.step.name": stepName, "workflow.name": workflowName } }, async (span) => { try { const result = await Reflect.apply(fnTarget, thisArg, 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 === "sleep" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, thisArg, args) => { const [sleepName, duration] = args; const tracer = trace.getTracer("autotel-edge"); return tracer.startActiveSpan( `Workflow ${workflowName}: sleep ${sleepName}`, { kind: SpanKind.INTERNAL, attributes: { "workflow.sleep.name": sleepName, "workflow.sleep.duration": String(duration), "workflow.name": workflowName } }, async (span) => { try { const result = await Reflect.apply(fnTarget, thisArg, 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 === "sleepUntil" && typeof value === "function") { return new Proxy(value, { apply: (fnTarget, thisArg, args) => { const [sleepName, timestamp] = args; const tracer = trace.getTracer("autotel-edge"); const wakeAt = timestamp instanceof Date ? timestamp.toISOString() : new Date(timestamp).toISOString(); return tracer.startActiveSpan( `Workflow ${workflowName}: sleepUntil ${sleepName}`, { kind: SpanKind.INTERNAL, attributes: { "workflow.sleep.name": sleepName, "workflow.sleep.until": wakeAt, "workflow.name": workflowName } }, async (span) => { try { const result = await Reflect.apply(fnTarget, thisArg, 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 (typeof value === "function") { return value.bind(target); } return value; } }; return wrap(step, stepHandler); } function instrumentWorkflowRun(runFn, workflowName, workflowClass) { return async function instrumentedRun(event, step) { const tracer = trace.getTracer("autotel-edge"); const instrumentedStep = instrumentWorkflowStep(step, workflowName); const spanName = `Workflow ${workflowName}: run`; return tracer.startActiveSpan( spanName, { kind: SpanKind.INTERNAL, attributes: { "workflow.name": workflowName, "workflow.instance_id": event.instanceId, "faas.trigger": "workflow", "faas.coldstart": isColdStart2(workflowClass) } }, async (span) => { try { const result = await runFn.call(this, event, instrumentedStep); 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(); } } ); }; } function instrumentWorkflowInstance(workflowInstance, workflowName, workflowClass) { const instanceHandler = { get(target, prop) { const value = Reflect.get(target, prop); if (prop === "run" && typeof value === "function") { return instrumentWorkflowRun( value.bind(target), workflowName, workflowClass ); } if (typeof value === "function") { return value.bind(target); } return value; } }; return wrap(workflowInstance, instanceHandler); } function instrumentWorkflow(workflowClass, workflowName, config) { const initialiser = createInitialiser(config); const classHandler = { construct(target, args) { const env = args[args.length - 1] || {}; const trigger = { type: "workflow", name: workflowName }; const workflowConfig = initialiser(env, trigger); const context$1 = setConfig(workflowConfig); const workflowInstance = context.with(context$1, () => { return new target(...args); }); return instrumentWorkflowInstance( workflowInstance, workflowName, workflowClass ); } }; return wrap(workflowClass, classHandler); } export { instrumentDO, instrumentWorkflow }; //# sourceMappingURL=chunk-MIDMNKDC.js.map //# sourceMappingURL=chunk-MIDMNKDC.js.map