autotel-cloudflare
Version:
The #1 OpenTelemetry package for Cloudflare Workers - complete bindings coverage, native CF OTel integration, advanced sampling
249 lines (235 loc) • 7.59 kB
TypeScript
import { ConfigurationOption } from 'autotel-edge';
/**
* Type definitions for @cloudflare/actors integration
*/
/**
* 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: unknown) => T;
/**
* Actor class instrumentation for @cloudflare/actors
*
* Wraps Actor lifecycle methods with OpenTelemetry tracing:
* - onInit: Traced as 'actor.lifecycle': 'init'
* - onRequest: Traced with full HTTP semantics
* - onAlarm: Traced as 'actor.lifecycle': 'alarm'
* - onPersist: Traced as 'actor.lifecycle': 'persist'
* - WebSocket methods: Traced with socket semantics
*/
/**
* 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: unknown, trigger?: unknown) => ActorConfig)): C;
/**
* Traced handler wrapper for @cloudflare/actors
*
* Wraps the Actors handler() to provide:
* - Root span for the entire request lifecycle
* - Actor name extraction and correlation
* - Request routing tracing
*/
/**
* 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>;
/**
* Actor storage instrumentation
*
* Traces operations on actor.storage including SQL queries
*/
/**
* Instrument Actor storage for tracing
*
* Captures:
* - SQL query operations
* - Key-value operations (if available)
*/
declare function instrumentActorStorage(storage: unknown, actorInstance: ActorLike, actorClass: object): unknown;
/**
* Actor alarms instrumentation
*
* Traces operations on actor.alarms
*/
/**
* 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;
/**
* Actor sockets instrumentation
*
* Traces operations on actor.sockets
*/
/**
* 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;
export { type ActorConfig, type ActorInstrumentationOptions, type ActorLifecycle, instrumentActor, instrumentActorAlarms, instrumentActorSockets, instrumentActorStorage, tracedHandler, wrapHandler };