UNPKG

autotel-cloudflare

Version:

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

224 lines 7.57 kB
import { t as UnknownRecord } from "./values-CRvW9g6_.js"; import { ConfigurationOption } from "autotel-edge"; //#region src/actors/types.d.ts /** * Actor-specific instrumentation options */ interface ActorInstrumentationOptions { /** * Whether to instrument storage operations (sql queries, etc.) * @default true */ instrumentStorage?: boolean; /** * Whether to instrument alarm operations * @default true */ instrumentAlarms?: boolean; /** * Whether to instrument socket operations * @default true */ instrumentSockets?: boolean; /** * Whether to capture persist events as spans * @default true */ capturePersistEvents?: boolean; /** * Custom span name formatter for lifecycle methods */ spanNameFormatter?: (actorName: string, lifecycle: string) => string; } /** * Actor-specific configuration * Can be a static config object with actors options, or a function that returns config */ type ActorConfig = ConfigurationOption & { /** * Actor-specific instrumentation options */ actors?: ActorInstrumentationOptions; }; /** * Actor lifecycle events that can be traced */ type ActorLifecycle = 'init' | 'request' | 'alarm' | 'persist' | 'websocket.connect' | 'websocket.message' | 'websocket.disconnect' | 'websocket.upgrade' | 'destroy'; /** * Minimal interface matching @cloudflare/actors Actor class * We don't import the actual type to avoid coupling */ interface ActorLike { name?: string; identifier?: string; storage?: unknown; alarms?: unknown; sockets?: unknown; fetch?(request: Request): Promise<Response>; alarm?(alarmInfo?: unknown): Promise<void>; } /** * Constructor type for Actor classes */ type ActorConstructor<T extends ActorLike = ActorLike> = (new (state: DurableObjectState, env: Record<string, unknown>) => T) & { /** A class's own name, which the instrumentation puts on the span. */ readonly name?: string; }; //#endregion //#region src/actors/instrument-actor.d.ts /** * The Actor class being instrumented. Its own type belongs to the application, * so this names only what the wrappers read off it: the class name that goes on * the span, and the marker used to detect a cold start. */ /** What an Actor persists, and what a WebSocket carries: the app's own values. */ type ActorPayload = string | number | boolean | null | undefined | UnknownRecord | unknown[] | ArrayBuffer; /** The env a Durable Object is constructed with: whatever wrangler bound. */ type ActorEnv = UnknownRecord; /** * Instrument an Actor class for comprehensive OpenTelemetry tracing * * This wraps the Actor class to automatically trace all lifecycle methods: * - onInit: Actor initialization * - onRequest: HTTP request handling * - onAlarm: Alarm triggers * - onPersist: Property persistence events * - WebSocket methods: Connection, message, disconnect * * It also optionally instruments: * - actor.storage: SQL queries and storage operations * - actor.alarms: Alarm scheduling operations * - actor.sockets: WebSocket operations * * @example * ```typescript * import { Actor } from '@cloudflare/actors' * import { instrumentActor } from 'autotel-cloudflare/actors' * * class Counter extends Actor<Env> { * protected onInit() { * console.log('Counter initialized') * } * * protected onRequest(request: Request) { * return new Response('count: 42') * } * } * * // Wrap the class * export const InstrumentedCounter = instrumentActor(Counter, (env: Env) => ({ * service: { name: 'counter-actor' }, * exporter: { url: env.OTLP_ENDPOINT }, * actors: { * instrumentStorage: true, * capturePersistEvents: true * } * })) * ``` * * @param actorClass - The Actor class to instrument * @param config - Configuration (static object or function) * @returns Instrumented Actor class */ declare function instrumentActor<C extends ActorConstructor>(actorClass: C, config: ActorConfig | ((env: ActorEnv, trigger?: ActorPayload) => ActorConfig)): C; //#endregion //#region src/actors/traced-handler.d.ts /** * Worker handler type matching @cloudflare/actors output */ interface WorkerHandler<E = unknown> { fetch(request: Request, env: E, ctx: ExecutionContext): Promise<Response>; } /** * Create a traced handler that combines Actor instrumentation with request tracing * * This is an all-in-one wrapper that: * 1. Initializes telemetry for the Worker * 2. Creates a root span for each incoming request * 3. Extracts the Actor name using `nameFromRequest` * 4. Instruments the Actor class with lifecycle tracing * 5. Routes the request to the instrumented Actor * * @example * ```typescript * import { Actor } from '@cloudflare/actors' * import { tracedHandler } from 'autotel-cloudflare/actors' * * class MyActor extends Actor<Env> { * protected onRequest(request: Request) { * return new Response('Hello!') * } * } * * // Export the Actor class and use tracedHandler * export { MyActor } * export default tracedHandler(MyActor, (env) => ({ * service: { name: 'my-actor-service' }, * exporter: { url: env.OTLP_ENDPOINT } * })) * ``` * * @param actorClass - The Actor class to handle requests * @param config - Configuration (static object or function) * @returns A Worker handler with full tracing */ declare function tracedHandler<E, A extends ActorLike>(actorClass: ActorConstructor<A> & { nameFromRequest?(request: Request): Promise<string | undefined>; configuration?(request: Request): { locationHint?: DurableObjectLocationHint; }; }, config: ActorConfig | ((env: E, trigger?: unknown) => ActorConfig)): WorkerHandler<E>; /** * Alternative: Create a handler wrapper that uses the existing @cloudflare/actors handler * * This is useful if you want to use the original handler() but add tracing around it. * * @example * ```typescript * import { Actor, handler } from '@cloudflare/actors' * import { wrapHandler } from 'autotel-cloudflare/actors' * * class MyActor extends Actor<Env> {} * * export { MyActor } * export default wrapHandler(handler(MyActor), (env) => ({ * service: { name: 'my-service' } * })) * ``` */ declare function wrapHandler<E>(originalHandler: WorkerHandler<E>, config: ActorConfig | ((env: E, trigger?: unknown) => ActorConfig)): WorkerHandler<E>; //#endregion //#region src/actors/storage.d.ts /** * Instrument Actor storage for tracing * * Captures: * - SQL query operations * - Key-value operations (if available) */ declare function instrumentActorStorage(storage: unknown, actorInstance: ActorLike, actorClass: object): unknown; //#endregion //#region src/actors/alarms.d.ts /** * Instrument Actor alarms for tracing * * Captures: * - set: Schedule a single alarm * - setMultiple: Schedule multiple alarms * - cancel: Cancel an alarm * - cancelAll: Cancel all alarms */ declare function instrumentActorAlarms(alarms: unknown, actorInstance: ActorLike, actorClass: object): unknown; //#endregion //#region src/actors/sockets.d.ts /** * Instrument Actor sockets for tracing * * Captures: * - acceptWebSocket: Accept an incoming WebSocket connection * - broadcast: Send message to all connected sockets * - send: Send message to a specific socket */ declare function instrumentActorSockets(sockets: unknown, actorInstance: ActorLike, actorClass: object): unknown; //#endregion export { type ActorConfig, type ActorInstrumentationOptions, type ActorLifecycle, instrumentActor, instrumentActorAlarms, instrumentActorSockets, instrumentActorStorage, tracedHandler, wrapHandler };