UNPKG

autotel

Version:
235 lines (231 loc) 6.96 kB
import { AttributeValue, SpanContext } from '@opentelemetry/api'; import { ConsumerContext, ProducerContext } from './messaging.cjs'; import './trace-context-t5X1AP-e.cjs'; /** * Pre-built adapter configurations for common messaging systems. * * These adapters provide ready-to-use hook configurations for systems * not explicitly supported by the core messaging module. Use them with * traceProducer/traceConsumer to get system-specific attributes. * * @example NATS consumer * ```typescript * import { traceConsumer } from 'autotel/messaging'; * import { natsAdapter } from 'autotel/messaging/adapters'; * * const processMessage = traceConsumer({ * system: 'nats', * destination: 'orders', * ...natsAdapter.consumer, * })(ctx => async (msg) => { * // msg.subject, msg.info.stream are now captured as span attributes * await handleOrder(msg.data); * }); * ``` * * @example Datadog context propagation * ```typescript * import { traceConsumer } from 'autotel/messaging'; * import { datadogContextExtractor } from 'autotel/messaging/adapters'; * * const processMessage = traceConsumer({ * system: 'kafka', * destination: 'events', * customContextExtractor: datadogContextExtractor, * })(ctx => async (msg) => { * // Parent span from Datadog trace headers is linked * }); * ``` * * @module */ /** * Producer adapter configuration */ interface ProducerAdapter { /** * Hook to add system-specific attributes to producer spans */ customAttributes?: (ctx: ProducerContext, args: unknown[]) => Record<string, AttributeValue>; /** * Hook to inject custom headers beyond W3C traceparent */ customHeaders?: (ctx: ProducerContext) => Record<string, string>; } /** * Consumer adapter configuration */ interface ConsumerAdapter { /** * Extract headers from the message for trace context propagation */ headersFrom?: (msg: unknown) => Record<string, string> | undefined; /** * Hook to add system-specific attributes to consumer spans */ customAttributes?: (ctx: ConsumerContext, msg: unknown) => Record<string, AttributeValue>; /** * Hook to extract parent span context from non-W3C header formats */ customContextExtractor?: (headers: Record<string, string>) => SpanContext | null; } /** * Combined producer and consumer adapter */ interface MessagingAdapter { producer?: ProducerAdapter; consumer?: ConsumerAdapter; } /** * NATS JetStream adapter * * Captures NATS-specific attributes following NATS observability conventions. * * @example Producer * ```typescript * const publishOrder = traceProducer({ * system: 'nats', * destination: 'orders.created', * ...natsAdapter.producer, * })(ctx => async (subject, payload, opts) => { * const headers = ctx.getTraceHeaders(); * await nc.publish(subject, payload, { headers }); * }); * ``` * * @example Consumer * ```typescript * const processOrder = traceConsumer({ * system: 'nats', * destination: 'orders.created', * consumerGroup: 'order-processor', * ...natsAdapter.consumer, * })(ctx => async (msg: JsMsg) => { * await handleOrder(msg.data); * msg.ack(); * }); * ``` */ declare const natsAdapter: MessagingAdapter; /** * Temporal adapter * * Captures Temporal-specific attributes for workflow activities. * Use this when instrumenting Temporal activity handlers. * * @example Activity handler * ```typescript * const processOrder = traceConsumer({ * system: 'temporal', * destination: 'order-activities', * ...temporalAdapter.consumer, * })(ctx => async (info: ActivityInfo, input: OrderInput) => { * // Temporal attributes are captured automatically * return processOrderLogic(input); * }); * ``` * * @example Workflow signal/query * ```typescript * const sendSignal = traceProducer({ * system: 'temporal', * destination: 'order-signals', * ...temporalAdapter.producer, * })(ctx => async (workflowId, signalName, payload) => { * await client.workflow.signal(workflowId, signalName, payload); * }); * ``` */ declare const temporalAdapter: MessagingAdapter; /** * Cloudflare Queues adapter * * Captures Cloudflare Queue-specific attributes. * * @example Queue consumer * ```typescript * export default { * async queue(batch: MessageBatch, env: Env) { * for (const msg of batch.messages) { * await processMessage(msg); * } * }, * }; * * const processMessage = traceConsumer({ * system: 'cloudflare_queues', * destination: 'my-queue', * ...cloudflareQueuesAdapter.consumer, * })(ctx => async (msg: Message) => { * await handleMessage(msg.body); * msg.ack(); * }); * ``` */ declare const cloudflareQueuesAdapter: MessagingAdapter; /** * Datadog trace context extractor * * Extracts parent span context from Datadog-format trace headers. * Converts Datadog's decimal IDs to OpenTelemetry's hex format. * * Note: Datadog sends trace/span IDs as decimal strings, not hex. * This extractor converts decimal -> hex before formatting for OTel. * * @example * ```typescript * const processMessage = traceConsumer({ * system: 'kafka', * destination: 'events', * customContextExtractor: datadogContextExtractor, * })(ctx => async (msg) => { * // Links to parent Datadog span automatically * }); * ``` */ declare function datadogContextExtractor(headers: Record<string, string>): SpanContext | null; /** * B3 (Zipkin) trace context extractor * * Extracts parent span context from B3 format headers. * Supports both single-header (b3) and multi-header formats. * * @see https://github.com/openzipkin/b3-propagation * * @example Single-header format * ```typescript * // Header: b3: 80f198ee56343ba864fe8b2a57d3eff7-e457b5a2e4d86bd1-1 * const processMessage = traceConsumer({ * system: 'rabbitmq', * destination: 'events', * customContextExtractor: b3ContextExtractor, * })(ctx => async (msg) => { * // Links to parent Zipkin span * }); * ``` * * @example Multi-header format * ```typescript * // Headers: X-B3-TraceId, X-B3-SpanId, X-B3-Sampled * ``` */ declare function b3ContextExtractor(headers: Record<string, string>): SpanContext | null; /** * AWS X-Ray trace context extractor * * Extracts parent span context from AWS X-Ray trace header. * Format: Root=1-{timestamp}-{random};Parent={parent-id};Sampled={0|1} * * @example * ```typescript * const processMessage = traceConsumer({ * system: 'sqs', * destination: 'my-queue', * customContextExtractor: xrayContextExtractor, * })(ctx => async (msg) => { * // Links to parent X-Ray trace * }); * ``` */ declare function xrayContextExtractor(headers: Record<string, string>): SpanContext | null; export { type ConsumerAdapter, type MessagingAdapter, type ProducerAdapter, b3ContextExtractor, cloudflareQueuesAdapter, datadogContextExtractor, natsAdapter, temporalAdapter, xrayContextExtractor };