UNPKG

autotel

Version:
201 lines (197 loc) 7.29 kB
import { SpanStatusCode, TimeInput, Link, BaggageEntry } from '@opentelemetry/api'; /** * Trace context types and utilities */ /** * Base trace context containing trace identifiers */ interface TraceContextBase { traceId: string; spanId: string; correlationId: string; } /** * Attribute value types following OpenTelemetry specification. * Supports primitive values and arrays of homogeneous primitives. */ type AttributeValue = string | number | boolean | string[] | number[] | boolean[]; /** * Span methods available on trace context */ interface SpanMethods { /** Set a single attribute on the span */ setAttribute(key: string, value: AttributeValue): void; /** Set multiple attributes on the span */ setAttributes(attrs: Record<string, AttributeValue>): void; /** Set the status of the span */ setStatus(status: { code: SpanStatusCode; message?: string; }): void; /** Record an exception on the span */ recordException(exception: Error, time?: TimeInput): void; /** Add an event to the span (for logging milestones/checkpoints) */ addEvent(name: string, attributesOrStartTime?: Record<string, AttributeValue> | TimeInput, startTime?: TimeInput): void; /** Add a link to another span */ addLink(link: Link): void; /** Add multiple links to other spans */ addLinks(links: Link[]): void; /** Update the span name dynamically */ updateName(name: string): void; /** Check if the span is recording */ isRecording(): boolean; } /** * Baggage methods available on trace context * * @template TBaggage - Optional type for typed baggage (defaults to undefined for untyped) */ interface BaggageMethods<TBaggage extends Record<string, unknown> | undefined = undefined> { /** * Get a baggage entry by key * @param key - Baggage key * @returns Baggage entry value or undefined */ getBaggage(key: string): string | undefined; /** * Set a baggage entry * * Note: OpenTelemetry contexts are immutable. For proper scoping across async * boundaries, use withBaggage() instead. This method updates baggage in the * current context which may not propagate to all child operations. * * @param key - Baggage key * @param value - Baggage value * @returns The baggage value that was set (for chaining) * * @example Using withBaggage() (recommended) * ```typescript * await withBaggage({ baggage: { 'key': 'value' }, fn: async () => { * // Baggage is available here and in child spans * }); * ``` */ setBaggage(key: string, value: string): string; /** * Delete a baggage entry * * Note: OpenTelemetry contexts are immutable. For proper scoping across async * boundaries, use withBaggage() with only the entries you want instead. * * @param key - Baggage key */ deleteBaggage(key: string): void; /** * Get all baggage entries * @returns Map of all baggage entries */ getAllBaggage(): Map<string, BaggageEntry>; /** * Get typed baggage (only available when TBaggage is defined) * This is used internally by defineBaggageSchema() * * @internal */ getTypedBaggage?: TBaggage extends Record<string, unknown> ? <T extends TBaggage>(namespace?: string) => Partial<T> | undefined : never; /** * Set typed baggage (only available when TBaggage is defined) * This is used internally by defineBaggageSchema() * * @internal */ setTypedBaggage?: TBaggage extends Record<string, unknown> ? <T extends TBaggage>(namespace: string | undefined, value: Partial<T>) => void : never; } /** * Complete trace context that merges base context, span methods, and baggage methods * * This is the ctx parameter passed to factory functions in trace(). * It provides access to trace IDs, span manipulation methods, and baggage operations. * * @template TBaggage - Optional type for typed baggage support * * @example Untyped (default) * ```typescript * export const handler = trace((ctx) => async () => { * ctx.getBaggage('key'); // returns string | undefined * }); * ``` * * @example Typed baggage * ```typescript * type TenantBaggage = { tenantId: string; region?: string }; * * export const handler = trace<TenantBaggage>((ctx) => async () => { * // Use typed schema helper for type-safe access * const schema = defineBaggageSchema<TenantBaggage>('tenant'); * const tenant = schema.get(ctx); // Partial<TenantBaggage> | undefined * }); * ``` */ type TraceContext<TBaggage extends Record<string, unknown> | undefined = undefined> = TraceContextBase & SpanMethods & BaggageMethods<TBaggage>; /** * Define a typed baggage schema for type-safe baggage operations * * This helper provides a type-safe API for working with baggage entries. * The namespace parameter is optional and prefixes all keys to avoid collisions. * * @template T - The baggage schema type (all fields are treated as optional) * @param namespace - Optional namespace to prefix baggage keys * * @example Basic usage * ```typescript * type TenantBaggage = { tenantId: string; region?: string }; * const tenantBaggage = defineBaggageSchema<TenantBaggage>('tenant'); * * export const handler = trace<TenantBaggage>((ctx) => async () => { * // Get typed baggage * const tenant = tenantBaggage.get(ctx); * if (tenant?.tenantId) { * console.log('Tenant:', tenant.tenantId); * } * * // Set typed baggage * tenantBaggage.set(ctx, { tenantId: 't1', region: 'us-east-1' }); * }); * ``` * * @example With withBaggage helper * ```typescript * const tenantBaggage = defineBaggageSchema<TenantBaggage>('tenant'); * * export const handler = trace<TenantBaggage>((ctx) => async () => { * return await tenantBaggage.with(ctx, { tenantId: 't1' }, async () => { * // Baggage is available here and in child spans * const tenant = tenantBaggage.get(ctx); * }); * }); * ``` */ declare function defineBaggageSchema<T extends Record<string, unknown>>(namespace?: string): { /** * Get typed baggage from context * @param ctx - Trace context * @returns Partial baggage object or undefined if no baggage is set */ get: (ctx: TraceContext<T>) => Partial<T> | undefined; /** * Set typed baggage in context * * Note: For proper scoping across async boundaries, use the `with` method instead * * @param ctx - Trace context * @param value - Partial baggage object to set */ set: (ctx: TraceContext<T>, value: Partial<T>) => void; /** * Run a function with typed baggage properly scoped * * This is the recommended way to set baggage as it ensures proper * scoping across async boundaries. * * @param ctx - Trace context (can be omitted, will use active context) * @param value - Partial baggage object to set * @param fn - Function to execute with the baggage */ with: <R>(ctxOrValue: TraceContext<T> | Partial<T>, valueOrFn: Partial<T> | (() => R | Promise<R>), maybeFn?: () => R | Promise<R>) => R | Promise<R>; }; export { type AttributeValue as A, type TraceContext as T, defineBaggageSchema as d };