autotel-cloudflare
Version:
The #1 OpenTelemetry package for Cloudflare Workers - complete bindings coverage, native CF OTel integration, advanced sampling
224 lines • 7.57 kB
TypeScript
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 };