autotel 2.25.4 → 2.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -1
- package/dist/auto.cjs +2 -2
- package/dist/auto.js +1 -1
- package/dist/{chunk-OPTGXEVN.js → chunk-4PTCDOZY.js} +3 -3
- package/dist/{chunk-OPTGXEVN.js.map → chunk-4PTCDOZY.js.map} +1 -1
- package/dist/{chunk-MN6PZ4AN.cjs → chunk-CMADDTHY.cjs} +7 -7
- package/dist/{chunk-MN6PZ4AN.cjs.map → chunk-CMADDTHY.cjs.map} +1 -1
- package/dist/{chunk-CMUM4JQI.js → chunk-DGPUZ6TE.js} +3 -3
- package/dist/{chunk-CMUM4JQI.js.map → chunk-DGPUZ6TE.js.map} +1 -1
- package/dist/{chunk-MNBAXRVG.js → chunk-EXOXDI5A.js} +74 -4
- package/dist/chunk-EXOXDI5A.js.map +1 -0
- package/dist/{chunk-QDREXAD7.js → chunk-GTD3NXOS.js} +3 -3
- package/dist/{chunk-QDREXAD7.js.map → chunk-GTD3NXOS.js.map} +1 -1
- package/dist/{chunk-A5ZUL2RZ.cjs → chunk-II7GFVAF.cjs} +13 -13
- package/dist/{chunk-A5ZUL2RZ.cjs.map → chunk-II7GFVAF.cjs.map} +1 -1
- package/dist/{chunk-I6JPSD4R.cjs → chunk-N344PVE5.cjs} +5 -5
- package/dist/{chunk-I6JPSD4R.cjs.map → chunk-N344PVE5.cjs.map} +1 -1
- package/dist/{chunk-WYP6OOCT.js → chunk-RXFZKLRQ.js} +3 -3
- package/dist/{chunk-WYP6OOCT.js.map → chunk-RXFZKLRQ.js.map} +1 -1
- package/dist/{chunk-EEJGUBWV.cjs → chunk-TS7IHIRW.cjs} +5 -5
- package/dist/{chunk-EEJGUBWV.cjs.map → chunk-TS7IHIRW.cjs.map} +1 -1
- package/dist/{chunk-ITYASFHQ.cjs → chunk-UJJPTSEI.cjs} +74 -3
- package/dist/chunk-UJJPTSEI.cjs.map +1 -0
- package/dist/{chunk-XB2GITM5.js → chunk-WAB4CHBU.js} +3 -3
- package/dist/{chunk-XB2GITM5.js.map → chunk-WAB4CHBU.js.map} +1 -1
- package/dist/{chunk-QQLP4M6W.cjs → chunk-ZJ5GXCOT.cjs} +26 -26
- package/dist/{chunk-QQLP4M6W.cjs.map → chunk-ZJ5GXCOT.cjs.map} +1 -1
- package/dist/decorators.cjs +2 -2
- package/dist/decorators.js +2 -2
- package/dist/event.cjs +5 -5
- package/dist/event.js +2 -2
- package/dist/functional.cjs +9 -9
- package/dist/functional.js +2 -2
- package/dist/index.cjs +42 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -9
- package/dist/index.js.map +1 -1
- package/dist/{init-C_PiC_Su.d.ts → init-FiR_glVc.d.ts} +23 -0
- package/dist/{init-CIzpC5kZ.d.cts → init-QSj7X6zU.d.cts} +23 -0
- package/dist/instrumentation.cjs +8 -8
- package/dist/instrumentation.js +1 -1
- package/dist/messaging.cjs +6 -6
- package/dist/messaging.js +3 -3
- package/dist/semantic-helpers.cjs +7 -7
- package/dist/semantic-helpers.js +3 -3
- package/dist/test-span-collector.cjs.map +1 -1
- package/dist/test-span-collector.d.cts +5 -2
- package/dist/test-span-collector.d.ts +5 -2
- package/dist/test-span-collector.js.map +1 -1
- package/dist/webhook.cjs +3 -3
- package/dist/webhook.js +2 -2
- package/dist/workflow-distributed.cjs +4 -4
- package/dist/workflow-distributed.js +2 -2
- package/dist/workflow.cjs +7 -7
- package/dist/workflow.js +3 -3
- package/dist/yaml-config.d.cts +1 -1
- package/dist/yaml-config.d.ts +1 -1
- package/package.json +41 -41
- package/src/devtools.ts +60 -0
- package/src/hook.mjs +2 -2
- package/src/init.customization.test.ts +81 -0
- package/src/init.ts +71 -1
- package/src/shutdown.test.ts +35 -1
- package/src/shutdown.ts +3 -1
- package/src/test-span-collector.ts +5 -2
- package/dist/chunk-ITYASFHQ.cjs.map +0 -1
- package/dist/chunk-MNBAXRVG.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/messaging.ts"],"names":["trace","SpanKind","propagation","context","extractLinksFromBatch","createLinkFromHeaders"],"mappings":"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","file":"chunk-I6JPSD4R.cjs","sourcesContent":["/**\n * Messaging helpers for event-driven architectures\n *\n * Provides specialized tracing for message producers and consumers\n * with automatic context propagation, link extraction, and OTel\n * semantic convention compliance.\n *\n * @example Producer\n * ```typescript\n * import { traceProducer } from 'autotel/messaging';\n *\n * export const publishEvent = traceProducer({\n * system: 'kafka',\n * destination: 'user-events',\n * })(ctx => async (event: UserEvent) => {\n * const headers = ctx.getTraceHeaders();\n * await producer.send({\n * topic: 'user-events',\n * messages: [{ value: JSON.stringify(event), headers }]\n * });\n * });\n * ```\n *\n * @example Consumer\n * ```typescript\n * import { traceConsumer } from 'autotel/messaging';\n *\n * export const processEvents = traceConsumer({\n * system: 'kafka',\n * destination: 'user-events',\n * consumerGroup: 'event-processor',\n * batchMode: true,\n * })(ctx => async (messages: KafkaMessage[]) => {\n * // Links to producer spans are automatically extracted\n * for (const msg of messages) {\n * await processMessage(msg);\n * }\n * });\n * ```\n *\n * @module\n */\n\nimport { SpanKind, context, propagation } from '@opentelemetry/api';\nimport type {\n Attributes,\n AttributeValue,\n Link,\n SpanContext,\n} from '@opentelemetry/api';\nimport { trace } from './functional';\nimport type { TraceContext } from './trace-context';\nimport { createLinkFromHeaders, extractLinksFromBatch } from './sampling';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Supported messaging systems\n */\nexport type MessagingSystem =\n | 'kafka'\n | 'rabbitmq'\n | 'sqs'\n | 'sns'\n | 'pubsub'\n | 'activemq'\n | 'azure_servicebus'\n | 'eventhubs'\n | (string & {});\n\n/**\n * Messaging operation types\n */\nexport type MessagingOperation = 'publish' | 'receive' | 'process' | 'settle';\n\n/**\n * Configuration for producer tracing\n */\nexport interface ProducerConfig {\n /** Messaging system (kafka, rabbitmq, sqs, etc.) */\n system: MessagingSystem;\n\n /** Destination name (topic/queue) */\n destination: string;\n\n /** Extract message ID from arguments */\n messageIdFrom?: string | ((args: unknown[]) => string | undefined);\n\n /** Extract partition from arguments (Kafka-specific) */\n partitionFrom?: string | ((args: unknown[]) => number | undefined);\n\n /** Extract message key from arguments (Kafka-specific) */\n keyFrom?: string | ((args: unknown[]) => string | undefined);\n\n /** Additional attributes to set on span */\n attributes?: Attributes;\n\n /** Propagate baggage in message headers */\n propagateBaggage?: boolean;\n\n /** Callback before sending (for custom attributes) */\n beforeSend?: (ctx: ProducerContext, args: unknown[]) => void;\n\n /** Callback on error */\n onError?: (error: Error, ctx: ProducerContext) => void;\n\n // ---- Extensible Hooks (\"Bring Your Own\" System Support) ----\n\n /**\n * Hook to add system-specific attributes\n *\n * Use this to add attributes for messaging systems not explicitly supported\n * (e.g., NATS, Temporal, Cloudflare Queues, Redis Streams).\n *\n * @example NATS attributes\n * ```typescript\n * customAttributes: (ctx, args) => ({\n * 'nats.subject': args[0].subject,\n * 'nats.reply_to': args[0].replyTo,\n * 'nats.stream': 'orders',\n * })\n * ```\n *\n * @example Temporal attributes\n * ```typescript\n * customAttributes: (ctx, args) => ({\n * 'temporal.workflow_id': args[0].workflowId,\n * 'temporal.run_id': args[0].runId,\n * 'temporal.task_queue': 'orders-queue',\n * })\n * ```\n */\n customAttributes?: (\n ctx: ProducerContext,\n args: unknown[],\n ) => Record<string, AttributeValue>;\n\n /**\n * Hook for custom header injection (beyond W3C traceparent)\n *\n * Use this to inject headers for systems that use non-standard\n * context propagation formats.\n *\n * @example Datadog headers\n * ```typescript\n * customHeaders: (ctx) => ({\n * 'x-datadog-trace-id': ctx.getTraceId(),\n * 'x-datadog-parent-id': ctx.getSpanId(),\n * })\n * ```\n *\n * @example Custom correlation headers\n * ```typescript\n * customHeaders: (ctx) => ({\n * 'x-correlation-id': correlationId,\n * 'x-request-id': requestId,\n * })\n * ```\n */\n customHeaders?: (ctx: ProducerContext) => Record<string, string>;\n}\n\n/**\n * Configuration for consumer tracing\n */\nexport interface ConsumerConfig {\n /** Messaging system (kafka, rabbitmq, sqs, etc.) */\n system: MessagingSystem;\n\n /** Destination name (topic/queue) */\n destination: string;\n\n /** Consumer group name */\n consumerGroup?: string;\n\n /** Extract headers from message for link creation */\n headersFrom?: string | ((msg: unknown) => Record<string, string> | undefined);\n\n /** Enable batch mode - extract links from all messages */\n batchMode?: boolean;\n\n /** Extract baggage from message headers */\n extractBaggage?: boolean;\n\n /** Additional attributes to set on span */\n attributes?: Attributes;\n\n /** Consumer lag metrics extraction */\n lagMetrics?: LagMetricsConfig;\n\n /** Callback when message goes to DLQ */\n onDLQ?: (ctx: ConsumerContext, reason: string) => void;\n\n /** Callback on error */\n onError?: (error: Error, ctx: ConsumerContext) => void;\n\n // ---- Message Ordering Support ----\n\n /**\n * Message ordering configuration\n *\n * Enable sequence tracking, out-of-order detection, and deduplication.\n *\n * @example Kafka ordering\n * ```typescript\n * ordering: {\n * sequenceFrom: (msg) => msg.offset,\n * partitionKeyFrom: (msg) => msg.key,\n * detectOutOfOrder: true,\n * onOutOfOrder: (ctx, info) => {\n * console.warn(`Out of order: expected ${info.expectedSequence}, got ${info.currentSequence}`);\n * },\n * }\n * ```\n */\n ordering?: OrderingConfig;\n\n // ---- Consumer Group Tracking ----\n\n /**\n * Consumer group tracking configuration\n *\n * Enables observability of consumer group state, including membership,\n * partition assignments, and rebalancing events.\n *\n * @example Kafka consumer group tracking\n * ```typescript\n * consumerGroupTracking: {\n * memberId: () => consumer.memberId,\n * groupInstanceId: process.env.KAFKA_GROUP_INSTANCE_ID,\n * onRebalance: (ctx, event) => {\n * if (event.type === 'revoked') {\n * logger.warn('Partitions revoked', event.partitions);\n * }\n * },\n * trackPartitionLag: true,\n * }\n * ```\n */\n consumerGroupTracking?: ConsumerGroupTrackingConfig;\n\n // ---- Extensible Hooks (\"Bring Your Own\" System Support) ----\n\n /**\n * Hook to add system-specific attributes\n *\n * Use this to add attributes for messaging systems not explicitly supported\n * (e.g., NATS, Temporal, Cloudflare Queues, Redis Streams).\n *\n * @example NATS consumer attributes\n * ```typescript\n * customAttributes: (ctx, msg) => ({\n * 'nats.subject': msg.subject,\n * 'nats.stream': msg.info?.stream,\n * 'nats.consumer': msg.info?.consumer,\n * 'nats.delivered_count': msg.info?.redeliveryCount,\n * })\n * ```\n *\n * @example Cloudflare Queue attributes\n * ```typescript\n * customAttributes: (ctx, msg) => ({\n * 'cloudflare.queue_id': msg.id,\n * 'cloudflare.timestamp_ms': msg.timestamp.getTime(),\n * 'cloudflare.attempts': msg.attempts,\n * })\n * ```\n */\n customAttributes?: (\n ctx: ConsumerContext,\n msg: unknown,\n ) => Record<string, AttributeValue>;\n\n /**\n * Hook for custom context extraction (beyond W3C traceparent)\n *\n * Use this to extract parent span context from systems that use\n * non-standard header formats.\n *\n * @example Datadog context extraction\n * ```typescript\n * customContextExtractor: (headers) => {\n * const traceId = headers['x-datadog-trace-id'];\n * const spanId = headers['x-datadog-parent-id'];\n * if (!traceId || !spanId) return null;\n * return {\n * traceId: traceIdToOtel(traceId),\n * spanId: spanIdToOtel(spanId),\n * traceFlags: TraceFlags.SAMPLED,\n * };\n * }\n * ```\n *\n * @example B3 format extraction\n * ```typescript\n * customContextExtractor: (headers) => {\n * const traceId = headers['x-b3-traceid'];\n * const spanId = headers['x-b3-spanid'];\n * const sampled = headers['x-b3-sampled'] === '1';\n * if (!traceId || !spanId) return null;\n * return {\n * traceId,\n * spanId,\n * traceFlags: sampled ? TraceFlags.SAMPLED : TraceFlags.NONE,\n * };\n * }\n * ```\n */\n customContextExtractor?: (\n headers: Record<string, string>,\n ) => SpanContext | null;\n}\n\n/**\n * Configuration for consumer lag metrics\n */\nexport interface LagMetricsConfig {\n /** Get current message offset */\n getCurrentOffset?: (msg: unknown) => number | undefined;\n\n /** Get end offset (high watermark) - can be async */\n getEndOffset?: () => number | Promise<number>;\n\n /** Get committed offset - can be async */\n getCommittedOffset?: () => number | Promise<number>;\n\n /** Get partition from message */\n getPartition?: (msg: unknown) => number | undefined;\n}\n\n/**\n * Configuration for message ordering tracking\n */\nexport interface OrderingConfig {\n /**\n * Extract sequence number from message\n *\n * Sequence numbers enable out-of-order detection and gap analysis.\n *\n * @example Kafka offset\n * ```typescript\n * sequenceFrom: (msg) => msg.offset\n * ```\n */\n sequenceFrom?: (msg: unknown) => number | undefined;\n\n /**\n * Extract partition key from message\n *\n * Partition keys determine message ordering in Kafka.\n *\n * @example Message key\n * ```typescript\n * partitionKeyFrom: (msg) => msg.key\n * ```\n */\n partitionKeyFrom?: (msg: unknown) => string | undefined;\n\n /**\n * Extract message ID for deduplication\n *\n * Used to detect duplicate messages.\n *\n * @example Idempotency key\n * ```typescript\n * messageIdFrom: (msg) => msg.headers['idempotency-key']\n * ```\n */\n messageIdFrom?: (msg: unknown) => string | undefined;\n\n /**\n * Enable out-of-order detection\n *\n * Tracks sequence numbers per partition and detects when messages\n * arrive out of order.\n *\n * @default false\n */\n detectOutOfOrder?: boolean;\n\n /**\n * Enable deduplication detection\n *\n * Tracks message IDs and detects duplicates within the window.\n *\n * @default false\n */\n detectDuplicates?: boolean;\n\n /**\n * Deduplication window size (number of message IDs to track)\n *\n * @default 1000\n */\n deduplicationWindowSize?: number;\n\n /**\n * Callback when out-of-order message detected\n */\n onOutOfOrder?: (ctx: ConsumerContext, info: OutOfOrderInfo) => void;\n\n /**\n * Callback when duplicate message detected\n */\n onDuplicate?: (ctx: ConsumerContext, messageId: string) => void;\n}\n\n/**\n * Information about out-of-order message\n */\nexport interface OutOfOrderInfo {\n /** Current sequence number */\n currentSequence: number;\n\n /** Expected sequence number */\n expectedSequence: number;\n\n /** Partition key (if available) */\n partitionKey?: string;\n\n /** Gap size (positive = gap, negative = out of order) */\n gap: number;\n}\n\n// ============================================================================\n// Consumer Group Tracking Types\n// ============================================================================\n\n/**\n * Configuration for consumer group tracking\n *\n * Enables observability of consumer group state, including membership,\n * partition assignments, and rebalancing events.\n *\n * @example Kafka consumer group tracking\n * ```typescript\n * consumerGroupTracking: {\n * memberId: consumer.memberId,\n * groupInstanceId: process.env.CONSUMER_ID,\n * onRebalance: (ctx, event) => {\n * if (event.type === 'assigned') {\n * console.log(`Assigned partitions: ${event.partitions}`);\n * }\n * },\n * }\n * ```\n */\nexport interface ConsumerGroupTrackingConfig {\n /**\n * Consumer member ID\n *\n * Unique identifier assigned by the broker to this consumer.\n */\n memberId?: string | (() => string | undefined);\n\n /**\n * Static group instance ID (for static membership)\n *\n * If set, enables static group membership which prevents\n * rebalances when consumers restart.\n */\n groupInstanceId?: string | (() => string | undefined);\n\n /**\n * Callback when rebalance occurs\n */\n onRebalance?: (ctx: ConsumerContext, event: RebalanceEvent) => void;\n\n /**\n * Callback when partitions are assigned\n */\n onPartitionsAssigned?: (\n ctx: ConsumerContext,\n partitions: PartitionAssignment[],\n ) => void;\n\n /**\n * Callback when partitions are revoked\n */\n onPartitionsRevoked?: (\n ctx: ConsumerContext,\n partitions: PartitionAssignment[],\n ) => void;\n\n /**\n * Track consumer lag per partition\n *\n * @default true\n */\n trackPartitionLag?: boolean;\n\n /**\n * Track consumer heartbeat health\n *\n * @default false\n */\n trackHeartbeat?: boolean;\n\n /**\n * Heartbeat interval in milliseconds (for health tracking)\n */\n heartbeatIntervalMs?: number;\n}\n\n/**\n * Rebalance event types\n */\nexport type RebalanceType = 'assigned' | 'revoked' | 'lost';\n\n/**\n * Rebalance event information\n */\nexport interface RebalanceEvent {\n /** Type of rebalance event */\n type: RebalanceType;\n\n /** Partitions affected by the rebalance */\n partitions: PartitionAssignment[];\n\n /** Timestamp of the rebalance event */\n timestamp: number;\n\n /** Generation ID (increments on each rebalance) */\n generation?: number;\n\n /** Consumer member ID */\n memberId?: string;\n\n /** Reason for the rebalance (if available) */\n reason?: string;\n}\n\n/**\n * Partition assignment information\n */\nexport interface PartitionAssignment {\n /** Topic name */\n topic: string;\n\n /** Partition number */\n partition: number;\n\n /** Initial offset (if available) */\n offset?: number;\n\n /** Metadata (if available) */\n metadata?: string;\n}\n\n/**\n * Consumer group state snapshot\n */\nexport interface ConsumerGroupState {\n /** Consumer group name */\n groupId: string;\n\n /** Consumer member ID */\n memberId?: string;\n\n /** Static instance ID (if using static membership) */\n groupInstanceId?: string;\n\n /** Currently assigned partitions */\n assignedPartitions: PartitionAssignment[];\n\n /** Group generation ID */\n generation?: number;\n\n /** Whether the consumer is currently active */\n isActive: boolean;\n\n /** Last heartbeat timestamp */\n lastHeartbeat?: number;\n\n /** Consumer state (stable, preparing_rebalance, completing_rebalance, dead) */\n state?:\n | 'stable'\n | 'preparing_rebalance'\n | 'completing_rebalance'\n | 'dead'\n | 'empty';\n}\n\n/**\n * Partition lag information\n */\nexport interface PartitionLag {\n /** Topic name */\n topic: string;\n\n /** Partition number */\n partition: number;\n\n /** Current consumer offset */\n currentOffset: number;\n\n /** End offset (high watermark) */\n endOffset: number;\n\n /** Calculated lag */\n lag: number;\n\n /** Timestamp of measurement */\n timestamp: number;\n}\n\n/**\n * DLQ failure category types\n */\nexport type DLQReasonCategory =\n | 'validation'\n | 'processing'\n | 'timeout'\n | 'poison'\n | 'unknown';\n\n/**\n * Options for enhanced DLQ recording\n */\nexport interface DLQOptions {\n /**\n * Automatically link to the producer span context\n *\n * When true, creates a span link from the DLQ event back to\n * the original producer span for correlation.\n *\n * @default true\n */\n linkToProducer?: boolean;\n\n /**\n * Category of the failure that caused DLQ routing\n *\n * - validation: Message failed schema/format validation\n * - processing: Business logic error during processing\n * - timeout: Processing exceeded allowed time\n * - poison: Message causes repeated failures (poison pill)\n * - unknown: Uncategorized failure\n */\n reasonCategory?: DLQReasonCategory;\n\n /**\n * Number of processing attempts before DLQ routing\n */\n attemptCount?: number;\n\n /**\n * The original error that caused DLQ routing\n *\n * Error details are recorded as span attributes for debugging.\n */\n originalError?: Error;\n\n /**\n * Additional metadata to record with the DLQ event\n */\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Options for recording DLQ replay\n */\nexport interface DLQReplayOptions {\n /**\n * Original span context from DLQ message\n *\n * If provided, creates a span link to correlate with the original failure.\n */\n originalDLQSpanContext?: SpanContext;\n\n /**\n * Time spent in DLQ before replay (milliseconds)\n */\n dlqDwellTimeMs?: number;\n\n /**\n * Retry attempt number for this replay\n */\n replayAttempt?: number;\n}\n\n/**\n * Extended trace context for producers with header injection\n */\nexport interface ProducerContext extends TraceContext {\n /**\n * Get W3C trace context headers to inject into message\n *\n * @returns Headers object with traceparent and optionally tracestate\n *\n * @example\n * ```typescript\n * const headers = ctx.getTraceHeaders();\n * await producer.send({\n * topic: 'events',\n * messages: [{ value: data, headers }]\n * });\n * ```\n */\n getTraceHeaders(): { traceparent: string; tracestate?: string };\n\n /**\n * Get all propagation headers including baggage if enabled\n *\n * @returns Headers object with all W3C trace context headers\n */\n getAllPropagationHeaders(): Record<string, string>;\n\n /**\n * Get all headers including custom headers from customHeaders hook\n *\n * This combines W3C trace context headers, baggage (if enabled),\n * and any custom headers defined via the customHeaders hook.\n *\n * @returns Combined headers object\n *\n * @example\n * ```typescript\n * const headers = ctx.getFullHeaders();\n * // Contains: traceparent, tracestate, baggage (if enabled), and custom headers\n * await producer.send({ topic, messages: [{ value, headers }] });\n * ```\n */\n getFullHeaders(): Record<string, string>;\n}\n\n/**\n * Extended trace context for consumers\n */\nexport interface ConsumerContext extends TraceContext {\n /**\n * Record that a message is being sent to DLQ\n *\n * Enhanced with auto-linking to producer span, failure categorization,\n * and detailed error recording for comprehensive DLQ observability.\n *\n * @param reason - Human-readable reason for DLQ routing\n * @param dlqNameOrOptions - DLQ name (string) or enhanced options object\n * @param options - Enhanced DLQ options (when second param is dlqName)\n *\n * @example Basic usage (backwards compatible)\n * ```typescript\n * ctx.recordDLQ('Schema validation failed', 'orders-dlq');\n * ```\n *\n * @example Enhanced usage with options\n * ```typescript\n * ctx.recordDLQ('Invalid order total', 'orders-dlq', {\n * reasonCategory: 'validation',\n * attemptCount: 3,\n * originalError: error,\n * linkToProducer: true, // Auto-links to producer span\n * });\n * ```\n *\n * @example Using options object as second param\n * ```typescript\n * ctx.recordDLQ('Processing timeout', {\n * reasonCategory: 'timeout',\n * attemptCount: 5,\n * metadata: { processingTimeMs: 30000 },\n * });\n * ```\n */\n recordDLQ(reason: string, dlqName?: string, options?: DLQOptions): void;\n recordDLQ(reason: string, options?: DLQOptions): void;\n\n /**\n * Record replay of a message from DLQ\n *\n * Use this when processing a message that was replayed from the DLQ\n * to create links for correlation and track replay metrics.\n *\n * @param options - Replay tracking options\n *\n * @example\n * ```typescript\n * export const processReplay = traceConsumer({\n * system: 'kafka',\n * destination: 'orders-dlq-replay',\n * })(ctx => async (message) => {\n * ctx.recordReplay({\n * originalDLQSpanContext: extractSpanContext(message.headers),\n * dlqDwellTimeMs: Date.now() - message.timestamp,\n * replayAttempt: message.replayCount,\n * });\n * await processOrder(message);\n * });\n * ```\n */\n recordReplay(options?: DLQReplayOptions): void;\n\n /**\n * Record retry attempt\n *\n * @param attemptNumber - Current retry attempt (1-based)\n * @param maxAttempts - Maximum retry attempts\n */\n recordRetry(attemptNumber: number, maxAttempts?: number): void;\n\n /**\n * Get the producer span context links extracted from message headers\n *\n * Useful for accessing the producer span context when implementing\n * custom DLQ or retry logic.\n *\n * @returns Array of span links extracted from the message, or empty array\n */\n getProducerLinks(): Link[];\n\n // ---- Message Ordering Methods ----\n\n /**\n * Check if the current message is a duplicate\n *\n * @returns True if the message has been seen before\n */\n isDuplicate(): boolean;\n\n /**\n * Check if the current message arrived out of order\n *\n * @returns Out of order info, or null if in order\n */\n getOutOfOrderInfo(): OutOfOrderInfo | null;\n\n /**\n * Get current sequence number\n *\n * @returns The sequence number, or null if not configured\n */\n getSequenceNumber(): number | null;\n\n /**\n * Get partition key\n *\n * @returns The partition key, or null if not configured\n */\n getPartitionKey(): string | null;\n\n // ---- Consumer Group Methods ----\n\n /**\n * Record a rebalance event\n *\n * Call this when the consumer group undergoes a rebalance to capture\n * the event as a span event with partition assignment details.\n *\n * @param event - The rebalance event details\n *\n * @example\n * ```typescript\n * consumer.on('rebalance', (event) => {\n * ctx.recordRebalance({\n * type: event.type,\n * partitions: event.assignment,\n * generation: event.generationId,\n * timestamp: Date.now(),\n * });\n * });\n * ```\n */\n recordRebalance(event: RebalanceEvent): void;\n\n /**\n * Record a heartbeat event\n *\n * Call this on each heartbeat to track consumer health.\n *\n * @param healthy - Whether the heartbeat was successful\n * @param latencyMs - Optional latency of the heartbeat in milliseconds\n */\n recordHeartbeat(healthy: boolean, latencyMs?: number): void;\n\n /**\n * Record partition lag for a specific partition\n *\n * @param lag - The partition lag information\n */\n recordPartitionLag(lag: PartitionLag): void;\n\n /**\n * Get the current consumer group state\n *\n * @returns The current consumer group state, or null if not configured\n */\n getConsumerGroupState(): ConsumerGroupState | null;\n\n /**\n * Get the consumer member ID\n *\n * @returns The member ID, or null if not available\n */\n getMemberId(): string | null;\n\n /**\n * Get the current partition assignments\n *\n * @returns Array of assigned partitions, or empty array if none\n */\n getAssignedPartitions(): PartitionAssignment[];\n}\n\n// ============================================================================\n// Producer Helper\n// ============================================================================\n\n/**\n * Create a traced message producer function\n *\n * Sets SpanKind.PRODUCER, OTel messaging semantic attributes,\n * and provides context injection helpers.\n *\n * @param config - Producer configuration\n * @returns Factory function that wraps your producer logic\n *\n * @example Kafka producer\n * ```typescript\n * export const publishUserEvent = traceProducer({\n * system: 'kafka',\n * destination: 'user-events',\n * messageIdFrom: (args) => args[0]?.eventId,\n * })(ctx => async (event: UserEvent) => {\n * const headers = ctx.getTraceHeaders();\n * await producer.send({\n * topic: 'user-events',\n * messages: [{\n * key: event.userId,\n * value: JSON.stringify(event),\n * headers,\n * }]\n * });\n * });\n * ```\n *\n * @example SQS producer\n * ```typescript\n * export const sendToSQS = traceProducer({\n * system: 'sqs',\n * destination: 'orders-queue',\n * })(ctx => async (order: Order) => {\n * const headers = ctx.getAllPropagationHeaders();\n * await sqs.sendMessage({\n * QueueUrl: QUEUE_URL,\n * MessageBody: JSON.stringify(order),\n * MessageAttributes: headersToSQSAttributes(headers),\n * });\n * });\n * ```\n */\nexport function traceProducer<TArgs extends unknown[], TReturn>(\n config: ProducerConfig,\n) {\n const spanName = `${config.system}.publish ${config.destination}`;\n\n return (\n fnFactory: (ctx: ProducerContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>(\n { name: spanName, spanKind: SpanKind.PRODUCER },\n (baseCtx) => {\n // Extend context with producer-specific methods\n const ctx = extendContextForProducer(baseCtx, config);\n\n // Set semantic convention attributes\n setProducerAttributes(ctx, config);\n\n // Call beforeSend callback if provided\n return (...args: TArgs) => {\n // Extract dynamic attributes from args\n setDynamicProducerAttributes(ctx, config, args);\n\n // Apply custom attributes hook if provided\n if (config.customAttributes) {\n const customAttrs = config.customAttributes(ctx, args);\n for (const [key, value] of Object.entries(customAttrs)) {\n if (value !== undefined && value !== null) {\n ctx.setAttribute(key, value as string | number | boolean);\n }\n }\n }\n\n if (config.beforeSend) {\n config.beforeSend(ctx, args);\n }\n\n // Execute user's function\n const userFn = fnFactory(ctx);\n return userFn(...args).catch((error) => {\n if (config.onError) {\n config.onError(error as Error, ctx);\n }\n throw error;\n });\n };\n },\n );\n };\n}\n\n// ============================================================================\n// Consumer Helper\n// ============================================================================\n\n/**\n * Create a traced message consumer function\n *\n * Sets SpanKind.CONSUMER, OTel messaging semantic attributes,\n * automatically extracts links from producer trace headers,\n * and provides DLQ/retry recording helpers.\n *\n * @param config - Consumer configuration\n * @returns Factory function that wraps your consumer logic\n *\n * @example Kafka consumer (single message)\n * ```typescript\n * export const processUserEvent = traceConsumer({\n * system: 'kafka',\n * destination: 'user-events',\n * consumerGroup: 'event-processor',\n * headersFrom: (msg) => msg.headers,\n * })(ctx => async (message: KafkaMessage) => {\n * // Link to producer span is automatically created\n * const event = JSON.parse(message.value.toString());\n * await processEvent(event);\n * });\n * ```\n *\n * @example Kafka consumer (batch mode)\n * ```typescript\n * export const processUserEventBatch = traceConsumer({\n * system: 'kafka',\n * destination: 'user-events',\n * consumerGroup: 'event-processor',\n * batchMode: true,\n * headersFrom: (msg) => msg.headers,\n * lagMetrics: {\n * getCurrentOffset: (msg) => msg.offset,\n * getEndOffset: () => consumer.getHighWatermark(),\n * getPartition: (msg) => msg.partition,\n * },\n * })(ctx => async (messages: KafkaMessage[]) => {\n * // Links to all producer spans are automatically created\n * for (const msg of messages) {\n * await processEvent(JSON.parse(msg.value.toString()));\n * }\n * });\n * ```\n *\n * @example SQS consumer with DLQ handling\n * ```typescript\n * export const processSQSMessage = traceConsumer({\n * system: 'sqs',\n * destination: 'orders-queue',\n * headersFrom: (msg) => sqsAttributesToHeaders(msg.MessageAttributes),\n * onDLQ: (ctx, reason) => {\n * ctx.recordDLQ(reason, 'orders-dlq');\n * },\n * })(ctx => async (message: SQSMessage) => {\n * try {\n * await processOrder(JSON.parse(message.Body));\n * } catch (error) {\n * if (message.ApproximateReceiveCount > 3) {\n * ctx.recordDLQ(error.message);\n * throw error;\n * }\n * ctx.recordRetry(message.ApproximateReceiveCount, 3);\n * throw error;\n * }\n * });\n * ```\n */\nexport function traceConsumer<TArgs extends unknown[], TReturn>(\n config: ConsumerConfig,\n) {\n const operation = config.batchMode ? 'receive' : 'process';\n const spanName = `${config.system}.${operation} ${config.destination}`;\n\n return (\n fnFactory: (ctx: ConsumerContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>(\n { name: spanName, spanKind: SpanKind.CONSUMER },\n (baseCtx) => {\n // Create mutable storage for producer links (populated during extractAndAddLinks)\n const linkStorage: ProducerLinkStorage = { links: [] };\n\n // Create mutable ordering state (populated during extractOrdering)\n const orderingState: OrderingState = {\n sequenceNumber: null,\n partitionKey: null,\n messageId: null,\n isDuplicate: false,\n outOfOrderInfo: null,\n };\n\n // Create consumer group state\n const groupTracking = config.consumerGroupTracking;\n const groupState: ConsumerGroupStateInternal = {\n memberId:\n typeof groupTracking?.memberId === 'function'\n ? (groupTracking.memberId() ?? null)\n : (groupTracking?.memberId ?? null),\n groupInstanceId:\n typeof groupTracking?.groupInstanceId === 'function'\n ? (groupTracking.groupInstanceId() ?? null)\n : (groupTracking?.groupInstanceId ?? null),\n assignedPartitions: [],\n generation: null,\n isActive: true,\n lastHeartbeat: null,\n state: null,\n };\n\n // Extend context with consumer-specific methods\n const ctx = extendContextForConsumer(\n baseCtx,\n config,\n linkStorage,\n orderingState,\n groupState,\n );\n\n // Set semantic convention attributes\n setConsumerAttributes(ctx, config);\n\n return async (...args: TArgs) => {\n // Extract links from message headers (includes customContextExtractor if provided)\n // This also populates linkStorage.links for getProducerLinks() and DLQ auto-linking\n await extractAndAddLinks(ctx, config, args, linkStorage);\n\n // Extract and process ordering information\n if (config.ordering) {\n extractAndProcessOrdering(ctx, config, args, orderingState);\n }\n\n // Extract lag metrics if configured\n if (config.lagMetrics) {\n await extractLagMetrics(ctx, config.lagMetrics, args);\n }\n\n // Apply custom attributes hook if provided\n if (config.customAttributes) {\n // For batch mode, extract first message; for single mode, use args[0] directly\n const batch = args[0];\n const msg =\n config.batchMode && Array.isArray(batch) && batch.length > 0\n ? batch[0]\n : batch;\n // Only call hook if we have a message\n if (msg !== undefined) {\n const customAttrs = config.customAttributes(ctx, msg);\n for (const [key, value] of Object.entries(customAttrs)) {\n if (value !== undefined && value !== null) {\n ctx.setAttribute(key, value as string | number | boolean);\n }\n }\n }\n }\n\n // Execute user's function\n const userFn = fnFactory(ctx);\n return userFn(...args).catch((error) => {\n if (config.onError) {\n config.onError(error as Error, ctx);\n }\n throw error;\n });\n };\n },\n );\n };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Extend base context with producer-specific methods\n */\nfunction extendContextForProducer(\n baseCtx: TraceContext,\n config: ProducerConfig,\n): ProducerContext {\n // Create a reference for `this` binding in getFullHeaders\n const producerCtx: ProducerContext = {\n ...baseCtx,\n\n getTraceHeaders(): { traceparent: string; tracestate?: string } {\n const headers: Record<string, string> = {};\n propagation.inject(context.active(), headers);\n\n const result: { traceparent: string; tracestate?: string } = {\n traceparent: headers['traceparent'] || '',\n };\n\n if (headers['tracestate']) {\n result.tracestate = headers['tracestate'];\n }\n\n return result;\n },\n\n getAllPropagationHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n propagation.inject(context.active(), headers);\n\n // Include baggage if configured\n if (config.propagateBaggage) {\n const baggage = propagation.getBaggage(context.active());\n if (baggage) {\n const entries: string[] = [];\n for (const [key, value] of baggage.getAllEntries()) {\n entries.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(value.value)}`,\n );\n }\n if (entries.length > 0) {\n headers['baggage'] = entries.join(',');\n }\n }\n }\n\n return headers;\n },\n\n getFullHeaders(): Record<string, string> {\n // Start with all propagation headers (W3C + baggage)\n const headers = producerCtx.getAllPropagationHeaders();\n\n // Add custom headers from hook if configured\n if (config.customHeaders) {\n const customHeaders = config.customHeaders(producerCtx);\n Object.assign(headers, customHeaders);\n }\n\n return headers;\n },\n };\n\n return producerCtx;\n}\n\n/**\n * Mutable storage for producer links (populated during extractAndAddLinks)\n */\ninterface ProducerLinkStorage {\n links: Link[];\n}\n\n/**\n * Ordering state for a single message\n */\ninterface OrderingState {\n sequenceNumber: number | null;\n partitionKey: string | null;\n messageId: string | null;\n isDuplicate: boolean;\n outOfOrderInfo: OutOfOrderInfo | null;\n}\n\n/**\n * Global sequence tracker for out-of-order detection (per partition)\n */\nconst sequenceTrackers = new Map<string, number>();\n\n/**\n * Global deduplication window (LRU-style using Map insertion order)\n */\nconst deduplicationWindow = new Map<string, number>();\nconst DEFAULT_DEDUP_WINDOW_SIZE = 1000;\n\n/**\n * Clean up old entries from deduplication window\n */\nfunction trimDeduplicationWindow(maxSize: number): void {\n if (deduplicationWindow.size > maxSize) {\n const excess = deduplicationWindow.size - maxSize;\n const iterator = deduplicationWindow.keys();\n for (let i = 0; i < excess; i++) {\n const key = iterator.next().value;\n if (key) deduplicationWindow.delete(key);\n }\n }\n}\n\n/**\n * Consumer group state tracking for a single consumer\n */\ninterface ConsumerGroupStateInternal {\n memberId: string | null;\n groupInstanceId: string | null;\n assignedPartitions: PartitionAssignment[];\n generation: number | null;\n isActive: boolean;\n lastHeartbeat: number | null;\n state: ConsumerGroupState['state'] | null;\n}\n\n/**\n * Extend base context with consumer-specific methods\n */\nfunction extendContextForConsumer(\n baseCtx: TraceContext,\n config: ConsumerConfig,\n linkStorage: ProducerLinkStorage,\n orderingState: OrderingState,\n groupState: ConsumerGroupStateInternal,\n): ConsumerContext {\n const consumerCtx: ConsumerContext = {\n ...baseCtx,\n\n recordDLQ(\n reason: string,\n dlqNameOrOptions?: string | DLQOptions,\n optionsParam?: DLQOptions,\n ): void {\n // Parse overloaded arguments\n let dlqName: string | undefined;\n let options: DLQOptions | undefined;\n\n if (typeof dlqNameOrOptions === 'string') {\n dlqName = dlqNameOrOptions;\n options = optionsParam;\n } else if (typeof dlqNameOrOptions === 'object') {\n options = dlqNameOrOptions;\n }\n\n // Default linkToProducer to true\n const linkToProducer = options?.linkToProducer ?? true;\n\n // Set basic DLQ attributes\n baseCtx.setAttribute('messaging.dlq.reason', reason);\n if (dlqName) {\n baseCtx.setAttribute('messaging.dlq.name', dlqName);\n }\n\n // Set enhanced DLQ attributes\n if (options?.reasonCategory) {\n baseCtx.setAttribute(\n 'messaging.dlq.reason_category',\n options.reasonCategory,\n );\n }\n if (options?.attemptCount !== undefined) {\n baseCtx.setAttribute(\n 'messaging.dlq.attempt_count',\n options.attemptCount,\n );\n }\n if (options?.originalError) {\n baseCtx.setAttribute(\n 'messaging.dlq.error.type',\n options.originalError.name,\n );\n baseCtx.setAttribute(\n 'messaging.dlq.error.message',\n options.originalError.message,\n );\n }\n\n // Set custom metadata\n if (options?.metadata) {\n for (const [key, value] of Object.entries(options.metadata)) {\n baseCtx.setAttribute(`messaging.dlq.metadata.${key}`, value);\n }\n }\n\n // Auto-link to producer span if available and enabled\n const producerLink = linkStorage.links[0];\n if (linkToProducer && producerLink) {\n baseCtx.setAttribute(\n 'messaging.dlq.producer_trace_id',\n producerLink.context.traceId,\n );\n baseCtx.setAttribute(\n 'messaging.dlq.producer_span_id',\n producerLink.context.spanId,\n );\n }\n\n // Record event with all attributes\n const eventAttrs: Record<string, string | number | boolean> = {\n 'messaging.dlq.reason': reason,\n ...(dlqName && { 'messaging.dlq.name': dlqName }),\n ...(options?.reasonCategory && {\n 'messaging.dlq.reason_category': options.reasonCategory,\n }),\n ...(options?.attemptCount !== undefined && {\n 'messaging.dlq.attempt_count': options.attemptCount,\n }),\n ...(options?.originalError && {\n 'messaging.dlq.error.type': options.originalError.name,\n 'messaging.dlq.error.message': options.originalError.message,\n }),\n };\n\n // Add producer link info to event if available\n if (linkToProducer && producerLink) {\n eventAttrs['messaging.dlq.producer_trace_id'] =\n producerLink.context.traceId;\n eventAttrs['messaging.dlq.producer_span_id'] =\n producerLink.context.spanId;\n }\n\n baseCtx.addEvent('dlq_routed', eventAttrs);\n\n // Call user's onDLQ callback if provided\n if (config.onDLQ) {\n config.onDLQ(consumerCtx, reason);\n }\n },\n\n recordReplay(options?: DLQReplayOptions): void {\n baseCtx.setAttribute('messaging.replay', true);\n\n if (options?.replayAttempt !== undefined) {\n baseCtx.setAttribute('messaging.replay.attempt', options.replayAttempt);\n }\n if (options?.dlqDwellTimeMs !== undefined) {\n baseCtx.setAttribute(\n 'messaging.replay.dwell_time_ms',\n options.dlqDwellTimeMs,\n );\n }\n\n // Create span link to original DLQ span if provided\n if (options?.originalDLQSpanContext) {\n baseCtx.addLinks([\n {\n context: options.originalDLQSpanContext,\n attributes: { 'messaging.link.source': 'dlq_replay' },\n },\n ]);\n }\n\n const eventAttrs: Record<string, string | number | boolean> = {\n 'messaging.replay': true,\n ...(options?.replayAttempt !== undefined && {\n 'messaging.replay.attempt': options.replayAttempt,\n }),\n ...(options?.dlqDwellTimeMs !== undefined && {\n 'messaging.replay.dwell_time_ms': options.dlqDwellTimeMs,\n }),\n };\n\n baseCtx.addEvent('dlq_replay', eventAttrs);\n },\n\n recordRetry(attemptNumber: number, maxAttempts?: number): void {\n baseCtx.setAttribute('messaging.retry.count', attemptNumber);\n if (maxAttempts !== undefined) {\n baseCtx.setAttribute('messaging.retry.max_attempts', maxAttempts);\n }\n baseCtx.addEvent('retry_attempt', {\n 'messaging.retry.count': attemptNumber,\n ...(maxAttempts !== undefined && {\n 'messaging.retry.max_attempts': maxAttempts,\n }),\n });\n },\n\n getProducerLinks(): Link[] {\n return [...linkStorage.links];\n },\n\n // ---- Ordering Methods ----\n\n isDuplicate(): boolean {\n return orderingState.isDuplicate;\n },\n\n getOutOfOrderInfo(): OutOfOrderInfo | null {\n return orderingState.outOfOrderInfo;\n },\n\n getSequenceNumber(): number | null {\n return orderingState.sequenceNumber;\n },\n\n getPartitionKey(): string | null {\n return orderingState.partitionKey;\n },\n\n // ---- Consumer Group Methods ----\n\n recordRebalance(event: RebalanceEvent): void {\n // Update internal state including consumer group state\n if (event.type === 'assigned') {\n groupState.assignedPartitions = event.partitions;\n groupState.isActive = true;\n // After assignment completes, group is stable\n groupState.state = 'stable';\n } else if (event.type === 'revoked' || event.type === 'lost') {\n // Remove revoked partitions from assignments\n const revokedSet = new Set(\n event.partitions.map((p) => `${p.topic}:${p.partition}`),\n );\n groupState.assignedPartitions = groupState.assignedPartitions.filter(\n (p) => !revokedSet.has(`${p.topic}:${p.partition}`),\n );\n if (event.type === 'lost') {\n groupState.isActive = false;\n // Consumer lost connection, mark as dead\n groupState.state = 'dead';\n } else {\n // Revoked means rebalance is starting\n // If no partitions remain, consumer is empty; otherwise preparing for rebalance\n groupState.state =\n groupState.assignedPartitions.length === 0\n ? 'empty'\n : 'preparing_rebalance';\n }\n }\n\n if (event.generation !== undefined) {\n groupState.generation = event.generation;\n }\n if (event.memberId) {\n groupState.memberId = event.memberId;\n }\n\n // Set span attributes\n baseCtx.setAttribute(\n 'messaging.consumer_group.rebalance.type',\n event.type,\n );\n baseCtx.setAttribute(\n 'messaging.consumer_group.rebalance.partition_count',\n event.partitions.length,\n );\n if (event.generation !== undefined) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.generation',\n event.generation,\n );\n }\n if (event.memberId) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.member_id',\n event.memberId,\n );\n }\n if (event.reason) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.rebalance.reason',\n event.reason,\n );\n }\n\n // Set the new state on the span\n if (groupState.state) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.state',\n groupState.state,\n );\n }\n\n // Record event\n const eventAttrs: Record<string, string | number | boolean> = {\n 'messaging.consumer_group.rebalance.type': event.type,\n 'messaging.consumer_group.rebalance.partition_count':\n event.partitions.length,\n 'messaging.consumer_group.rebalance.timestamp': event.timestamp,\n ...(event.generation !== undefined && {\n 'messaging.consumer_group.generation': event.generation,\n }),\n ...(event.memberId && {\n 'messaging.consumer_group.member_id': event.memberId,\n }),\n ...(event.reason && {\n 'messaging.consumer_group.rebalance.reason': event.reason,\n }),\n ...(groupState.state && {\n 'messaging.consumer_group.state': groupState.state,\n }),\n };\n\n // Add partition details if not too many\n if (event.partitions.length <= 10) {\n eventAttrs['messaging.consumer_group.rebalance.partitions'] =\n event.partitions.map((p) => `${p.topic}:${p.partition}`).join(',');\n }\n\n baseCtx.addEvent(`consumer_group_${event.type}`, eventAttrs);\n\n // Call user's onRebalance callback if provided\n if (config.consumerGroupTracking?.onRebalance) {\n config.consumerGroupTracking.onRebalance(consumerCtx, event);\n }\n\n // Call specific callbacks\n if (\n event.type === 'assigned' &&\n config.consumerGroupTracking?.onPartitionsAssigned\n ) {\n config.consumerGroupTracking.onPartitionsAssigned(\n consumerCtx,\n event.partitions,\n );\n }\n if (\n event.type === 'revoked' &&\n config.consumerGroupTracking?.onPartitionsRevoked\n ) {\n config.consumerGroupTracking.onPartitionsRevoked(\n consumerCtx,\n event.partitions,\n );\n }\n },\n\n recordHeartbeat(healthy: boolean, latencyMs?: number): void {\n groupState.lastHeartbeat = Date.now();\n\n baseCtx.setAttribute(\n 'messaging.consumer_group.heartbeat.healthy',\n healthy,\n );\n if (latencyMs !== undefined) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.heartbeat.latency_ms',\n latencyMs,\n );\n }\n\n baseCtx.addEvent('consumer_group_heartbeat', {\n 'messaging.consumer_group.heartbeat.healthy': healthy,\n 'messaging.consumer_group.heartbeat.timestamp':\n groupState.lastHeartbeat,\n ...(latencyMs !== undefined && {\n 'messaging.consumer_group.heartbeat.latency_ms': latencyMs,\n }),\n });\n },\n\n recordPartitionLag(lag: PartitionLag): void {\n const prefix = `messaging.consumer_group.lag.${lag.topic}.${lag.partition}`;\n\n baseCtx.setAttribute(`${prefix}.current_offset`, lag.currentOffset);\n baseCtx.setAttribute(`${prefix}.end_offset`, lag.endOffset);\n baseCtx.setAttribute(`${prefix}.lag`, lag.lag);\n\n baseCtx.addEvent('partition_lag_recorded', {\n 'messaging.consumer_group.lag.topic': lag.topic,\n 'messaging.consumer_group.lag.partition': lag.partition,\n 'messaging.consumer_group.lag.current_offset': lag.currentOffset,\n 'messaging.consumer_group.lag.end_offset': lag.endOffset,\n 'messaging.consumer_group.lag.lag': lag.lag,\n 'messaging.consumer_group.lag.timestamp': lag.timestamp,\n });\n },\n\n getConsumerGroupState(): ConsumerGroupState | null {\n if (!config.consumerGroup) {\n return null;\n }\n\n return {\n groupId: config.consumerGroup,\n memberId: groupState.memberId ?? undefined,\n groupInstanceId: groupState.groupInstanceId ?? undefined,\n assignedPartitions: [...groupState.assignedPartitions],\n generation: groupState.generation ?? undefined,\n isActive: groupState.isActive,\n lastHeartbeat: groupState.lastHeartbeat ?? undefined,\n state: groupState.state ?? undefined,\n };\n },\n\n getMemberId(): string | null {\n return groupState.memberId;\n },\n\n getAssignedPartitions(): PartitionAssignment[] {\n return [...groupState.assignedPartitions];\n },\n };\n\n return consumerCtx;\n}\n\n/**\n * Set OTel semantic convention attributes for producer\n */\nfunction setProducerAttributes(\n ctx: TraceContext,\n config: ProducerConfig,\n): void {\n ctx.setAttribute('messaging.system', config.system);\n ctx.setAttribute('messaging.operation', 'publish');\n ctx.setAttribute('messaging.destination.name', config.destination);\n\n // Set system-specific destination attribute\n if (config.system === 'kafka') {\n ctx.setAttribute('messaging.kafka.destination.topic', config.destination);\n }\n\n // Set custom attributes\n if (config.attributes) {\n setCustomAttributes(ctx, config.attributes);\n }\n}\n\n/**\n * Set dynamic producer attributes from arguments\n */\nfunction setDynamicProducerAttributes(\n ctx: TraceContext,\n config: ProducerConfig,\n args: unknown[],\n): void {\n // Message ID\n if (config.messageIdFrom) {\n const messageId = extractValue(config.messageIdFrom, args);\n if (messageId !== undefined) {\n ctx.setAttribute('messaging.message.id', String(messageId));\n }\n }\n\n // Partition (Kafka-specific)\n if (config.partitionFrom) {\n const partition = extractValue(config.partitionFrom, args);\n if (partition !== undefined) {\n ctx.setAttribute(\n 'messaging.kafka.destination.partition',\n Number(partition),\n );\n }\n }\n\n // Key (Kafka-specific)\n if (config.keyFrom) {\n const key = extractValue(config.keyFrom, args);\n if (key !== undefined) {\n ctx.setAttribute('messaging.kafka.message.key', String(key));\n }\n }\n}\n\n/**\n * Set OTel semantic convention attributes for consumer\n */\nfunction setConsumerAttributes(\n ctx: TraceContext,\n config: ConsumerConfig,\n): void {\n ctx.setAttribute('messaging.system', config.system);\n ctx.setAttribute(\n 'messaging.operation',\n config.batchMode ? 'receive' : 'process',\n );\n ctx.setAttribute('messaging.destination.name', config.destination);\n\n // Consumer group\n if (config.consumerGroup) {\n ctx.setAttribute('messaging.consumer.group', config.consumerGroup);\n\n // System-specific consumer group attribute\n if (config.system === 'kafka') {\n ctx.setAttribute('messaging.kafka.consumer.group', config.consumerGroup);\n }\n }\n\n // Set system-specific destination attribute\n if (config.system === 'kafka') {\n ctx.setAttribute('messaging.kafka.destination.topic', config.destination);\n }\n\n // Set custom attributes\n if (config.attributes) {\n setCustomAttributes(ctx, config.attributes);\n }\n}\n\n/**\n * Extract links from message headers and add to span\n *\n * Uses W3C trace context by default, falls back to customContextExtractor if provided.\n * Also populates linkStorage for getProducerLinks() and DLQ auto-linking.\n */\nasync function extractAndAddLinks(\n ctx: ConsumerContext,\n config: ConsumerConfig,\n args: unknown[],\n linkStorage: ProducerLinkStorage,\n): Promise<void> {\n if (!config.headersFrom && !config.customContextExtractor) {\n return;\n }\n\n const links: Link[] = [];\n\n if (config.batchMode && Array.isArray(args[0])) {\n // Batch mode - extract links from all messages\n const messages = args[0] as unknown[];\n\n if (config.headersFrom) {\n const batchLinks = extractLinksFromBatch(\n messages.map((msg) => {\n const headers = extractHeaders(config.headersFrom!, msg);\n return { headers };\n }),\n 'headers',\n );\n links.push(...batchLinks);\n }\n\n // Try custom context extractor for messages without W3C links\n if (config.customContextExtractor && config.headersFrom) {\n for (const msg of messages) {\n const headers = extractHeaders(config.headersFrom, msg);\n if (headers) {\n // Only use custom extractor if W3C headers weren't present\n const w3cLink = createLinkFromHeaders(headers);\n if (!w3cLink) {\n const customContext = config.customContextExtractor(headers);\n if (customContext) {\n links.push({\n context: customContext,\n attributes: { 'messaging.link.source': 'custom_extractor' },\n });\n }\n }\n }\n }\n }\n\n // Set batch count\n ctx.setAttribute('messaging.batch.message_count', messages.length);\n } else {\n // Single message mode\n const msg = args[0];\n const headers = config.headersFrom\n ? extractHeaders(config.headersFrom, msg)\n : undefined;\n\n if (headers) {\n // Try W3C format first\n const w3cLink = createLinkFromHeaders(headers);\n if (w3cLink) {\n links.push(w3cLink);\n } else if (config.customContextExtractor) {\n // Fall back to custom extractor\n const customContext = config.customContextExtractor(headers);\n if (customContext) {\n links.push({\n context: customContext,\n attributes: { 'messaging.link.source': 'custom_extractor' },\n });\n }\n }\n }\n }\n\n // Add all extracted links and store for getProducerLinks() / DLQ auto-linking\n if (links.length > 0) {\n ctx.addLinks(links);\n linkStorage.links.push(...links);\n }\n}\n\n/**\n * Extract lag metrics and set as span attributes\n */\nasync function extractLagMetrics(\n ctx: ConsumerContext,\n lagConfig: LagMetricsConfig,\n args: unknown[],\n): Promise<void> {\n const msg = Array.isArray(args[0]) ? args[0][0] : args[0];\n\n // Current offset\n let currentOffset: number | undefined;\n if (lagConfig.getCurrentOffset && msg) {\n currentOffset = lagConfig.getCurrentOffset(msg);\n if (currentOffset !== undefined) {\n ctx.setAttribute('messaging.kafka.message.offset', currentOffset);\n }\n }\n\n // Partition\n if (lagConfig.getPartition && msg) {\n const partition = lagConfig.getPartition(msg);\n if (partition !== undefined) {\n ctx.setAttribute('messaging.kafka.partition', partition);\n }\n }\n\n // End offset (high watermark) and lag calculation\n if (lagConfig.getEndOffset) {\n try {\n const endOffset = await Promise.resolve(lagConfig.getEndOffset());\n if (endOffset !== undefined && currentOffset !== undefined) {\n const lag = endOffset - currentOffset;\n ctx.setAttribute('messaging.kafka.consumer_lag', lag);\n\n // Add lag event\n ctx.addEvent('consumer_lag_measured', {\n 'messaging.kafka.consumer_lag': lag,\n 'messaging.kafka.message.offset': currentOffset,\n 'messaging.kafka.high_watermark': endOffset,\n });\n }\n } catch {\n // Ignore lag calculation errors\n }\n }\n\n // Committed offset\n if (lagConfig.getCommittedOffset) {\n try {\n const committedOffset = await Promise.resolve(\n lagConfig.getCommittedOffset(),\n );\n if (committedOffset !== undefined) {\n ctx.setAttribute('messaging.kafka.committed_offset', committedOffset);\n }\n } catch {\n // Ignore committed offset errors\n }\n }\n\n // Batch-specific metrics\n if (Array.isArray(args[0]) && args[0].length > 0) {\n const messages = args[0] as unknown[];\n if (lagConfig.getCurrentOffset) {\n const firstOffset = lagConfig.getCurrentOffset(messages[0]);\n const lastMessage = messages.at(-1);\n const lastOffset =\n lastMessage === undefined\n ? undefined\n : lagConfig.getCurrentOffset(lastMessage);\n\n if (firstOffset !== undefined) {\n ctx.setAttribute('messaging.batch.first_offset', firstOffset);\n }\n if (lastOffset !== undefined) {\n ctx.setAttribute('messaging.batch.last_offset', lastOffset);\n }\n }\n }\n}\n\n/**\n * Extract headers from message using config\n */\nfunction extractHeaders(\n headersFrom: string | ((msg: unknown) => Record<string, string> | undefined),\n msg: unknown,\n): Record<string, string> | undefined {\n if (typeof headersFrom === 'function') {\n return headersFrom(msg);\n }\n\n // String path - extract from message property\n if (typeof msg === 'object' && msg !== null) {\n const value = (msg as Record<string, unknown>)[headersFrom];\n if (typeof value === 'object' && value !== null) {\n return value as Record<string, string>;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract value from arguments using config\n */\nfunction extractValue(\n extractor: string | ((args: unknown[]) => unknown),\n args: unknown[],\n): unknown {\n if (typeof extractor === 'function') {\n return extractor(args);\n }\n\n // String path - extract from first argument\n const firstArg = args[0];\n if (typeof firstArg === 'object' && firstArg !== null) {\n return (firstArg as Record<string, unknown>)[extractor];\n }\n\n return undefined;\n}\n\n/**\n * Set custom attributes on context, handling non-primitive values\n */\nfunction setCustomAttributes(ctx: TraceContext, attributes: Attributes): void {\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute accepts primitives and arrays of primitives\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n ctx.setAttribute(key, value);\n } else if (Array.isArray(value)) {\n // Filter out null/undefined from arrays and ensure proper typing\n const cleanArray = value.filter(\n (v): v is string | number | boolean =>\n v !== null &&\n v !== undefined &&\n (typeof v === 'string' ||\n typeof v === 'number' ||\n typeof v === 'boolean'),\n );\n if (cleanArray.length > 0) {\n ctx.setAttribute(key, cleanArray as string[] | number[] | boolean[]);\n }\n } else {\n ctx.setAttribute(key, JSON.stringify(value));\n }\n }\n }\n}\n\n/**\n * Extract and process ordering information from message\n *\n * Handles:\n * - Sequence number extraction and tracking\n * - Out-of-order detection\n * - Duplicate detection\n * - Span attribute setting\n * - Callback invocation\n */\nfunction extractAndProcessOrdering(\n ctx: ConsumerContext,\n config: ConsumerConfig,\n args: unknown[],\n orderingState: OrderingState,\n): void {\n const ordering = config.ordering;\n if (!ordering) return;\n\n // Get messages to process - all messages in batch mode, single message otherwise\n const messages: unknown[] =\n config.batchMode && Array.isArray(args[0]) ? args[0] : [args[0]];\n\n if (messages.length === 0) return;\n\n // Track aggregate stats for batch reporting\n let outOfOrderCount = 0;\n let duplicateCount = 0;\n let lastSequence: number | null = null;\n let lastPartitionKey: string | null = null;\n let lastMessageId: string | null = null;\n\n for (const [i, msg] of messages.entries()) {\n if (!msg) continue;\n\n // Per-message state for this iteration\n let msgSequence: number | null = null;\n let msgPartitionKey: string | null = null;\n let msgId: string | null = null;\n\n // Extract sequence number\n if (ordering.sequenceFrom) {\n const seq = ordering.sequenceFrom(msg);\n if (seq !== undefined) {\n msgSequence = seq;\n lastSequence = seq;\n }\n }\n\n // Extract partition key\n if (ordering.partitionKeyFrom) {\n const key = ordering.partitionKeyFrom(msg);\n if (key !== undefined) {\n msgPartitionKey = key;\n lastPartitionKey = key;\n }\n }\n\n // Extract message ID for deduplication\n if (ordering.messageIdFrom) {\n const id = ordering.messageIdFrom(msg);\n if (id !== undefined) {\n msgId = id;\n lastMessageId = id;\n }\n }\n\n // Out-of-order detection for this message\n if (ordering.detectOutOfOrder && msgSequence !== null) {\n // Build tracker key using per-message partition key\n const msgOrderingState: OrderingState = {\n sequenceNumber: msgSequence,\n partitionKey: msgPartitionKey,\n messageId: msgId,\n isDuplicate: false,\n outOfOrderInfo: null,\n };\n const trackerKey = buildTrackerKey(config, msgOrderingState);\n const prevSequence = sequenceTrackers.get(trackerKey);\n\n if (prevSequence !== undefined) {\n const expectedSequence = prevSequence + 1;\n\n if (msgSequence !== expectedSequence) {\n outOfOrderCount++;\n const gap = msgSequence - expectedSequence;\n const outOfOrderInfo: OutOfOrderInfo = {\n currentSequence: msgSequence,\n expectedSequence,\n partitionKey: msgPartitionKey ?? undefined,\n gap,\n };\n\n // Store the first out-of-order info for backward compatibility\n if (!orderingState.outOfOrderInfo) {\n orderingState.outOfOrderInfo = outOfOrderInfo;\n }\n\n // Add event for each out-of-order message\n ctx.addEvent('message_out_of_order', {\n 'messaging.ordering.batch_index': i,\n 'messaging.ordering.current_sequence': msgSequence,\n 'messaging.ordering.expected_sequence': expectedSequence,\n 'messaging.ordering.gap': gap,\n ...(msgPartitionKey && {\n 'messaging.ordering.partition_key': msgPartitionKey,\n }),\n });\n\n // Call user callback if provided\n if (ordering.onOutOfOrder) {\n ordering.onOutOfOrder(ctx, outOfOrderInfo);\n }\n }\n }\n\n // Update tracker with this message's sequence\n sequenceTrackers.set(trackerKey, msgSequence);\n }\n\n // Duplicate detection for this message\n if (ordering.detectDuplicates && msgId !== null) {\n const msgOrderingState: OrderingState = {\n sequenceNumber: msgSequence,\n partitionKey: msgPartitionKey,\n messageId: msgId,\n isDuplicate: false,\n outOfOrderInfo: null,\n };\n const dedupKey = buildDedupKey(config, msgOrderingState);\n\n if (deduplicationWindow.has(dedupKey)) {\n duplicateCount++;\n\n // Add event for each duplicate\n ctx.addEvent('message_duplicate', {\n 'messaging.ordering.batch_index': i,\n 'messaging.message.id': msgId,\n });\n\n // Call user callback if provided\n if (ordering.onDuplicate) {\n ordering.onDuplicate(ctx, msgId);\n }\n } else {\n // Add to deduplication window\n deduplicationWindow.set(dedupKey, Date.now());\n\n // Trim window if needed\n const windowSize =\n ordering.deduplicationWindowSize ?? DEFAULT_DEDUP_WINDOW_SIZE;\n trimDeduplicationWindow(windowSize);\n }\n }\n }\n\n // Update orderingState with final values from the batch\n orderingState.sequenceNumber = lastSequence;\n orderingState.partitionKey = lastPartitionKey;\n orderingState.messageId = lastMessageId;\n orderingState.isDuplicate = duplicateCount > 0;\n\n // Set aggregate span attributes\n if (lastSequence !== null) {\n ctx.setAttribute('messaging.message.sequence_number', lastSequence);\n }\n if (lastPartitionKey !== null) {\n ctx.setAttribute('messaging.message.partition_key', lastPartitionKey);\n }\n if (lastMessageId !== null) {\n ctx.setAttribute('messaging.message.id', lastMessageId);\n }\n\n // Report batch-level ordering statistics\n if (outOfOrderCount > 0) {\n ctx.setAttribute('messaging.ordering.out_of_order', true);\n ctx.setAttribute('messaging.ordering.out_of_order_count', outOfOrderCount);\n }\n if (duplicateCount > 0) {\n ctx.setAttribute('messaging.ordering.duplicate', true);\n ctx.setAttribute('messaging.ordering.duplicate_count', duplicateCount);\n }\n}\n\n/**\n * Build a unique key for sequence tracking based on system, destination, and partition\n */\nfunction buildTrackerKey(\n config: ConsumerConfig,\n orderingState: OrderingState,\n): string {\n const parts = [config.system, config.destination];\n if (orderingState.partitionKey) {\n parts.push(orderingState.partitionKey);\n }\n if (config.consumerGroup) {\n parts.push(config.consumerGroup);\n }\n return parts.join(':');\n}\n\n/**\n * Build a unique key for deduplication based on system, destination, and message ID\n */\nfunction buildDedupKey(\n config: ConsumerConfig,\n orderingState: OrderingState,\n): string {\n const parts = [config.system, config.destination];\n if (orderingState.messageId) {\n parts.push(orderingState.messageId);\n }\n return parts.join(':');\n}\n\n/**\n * Clear sequence tracking state (useful for testing)\n */\nexport function clearOrderingState(): void {\n sequenceTrackers.clear();\n deduplicationWindow.clear();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/messaging.ts"],"names":["trace","SpanKind","propagation","context","extractLinksFromBatch","createLinkFromHeaders"],"mappings":"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","file":"chunk-N344PVE5.cjs","sourcesContent":["/**\n * Messaging helpers for event-driven architectures\n *\n * Provides specialized tracing for message producers and consumers\n * with automatic context propagation, link extraction, and OTel\n * semantic convention compliance.\n *\n * @example Producer\n * ```typescript\n * import { traceProducer } from 'autotel/messaging';\n *\n * export const publishEvent = traceProducer({\n * system: 'kafka',\n * destination: 'user-events',\n * })(ctx => async (event: UserEvent) => {\n * const headers = ctx.getTraceHeaders();\n * await producer.send({\n * topic: 'user-events',\n * messages: [{ value: JSON.stringify(event), headers }]\n * });\n * });\n * ```\n *\n * @example Consumer\n * ```typescript\n * import { traceConsumer } from 'autotel/messaging';\n *\n * export const processEvents = traceConsumer({\n * system: 'kafka',\n * destination: 'user-events',\n * consumerGroup: 'event-processor',\n * batchMode: true,\n * })(ctx => async (messages: KafkaMessage[]) => {\n * // Links to producer spans are automatically extracted\n * for (const msg of messages) {\n * await processMessage(msg);\n * }\n * });\n * ```\n *\n * @module\n */\n\nimport { SpanKind, context, propagation } from '@opentelemetry/api';\nimport type {\n Attributes,\n AttributeValue,\n Link,\n SpanContext,\n} from '@opentelemetry/api';\nimport { trace } from './functional';\nimport type { TraceContext } from './trace-context';\nimport { createLinkFromHeaders, extractLinksFromBatch } from './sampling';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Supported messaging systems\n */\nexport type MessagingSystem =\n | 'kafka'\n | 'rabbitmq'\n | 'sqs'\n | 'sns'\n | 'pubsub'\n | 'activemq'\n | 'azure_servicebus'\n | 'eventhubs'\n | (string & {});\n\n/**\n * Messaging operation types\n */\nexport type MessagingOperation = 'publish' | 'receive' | 'process' | 'settle';\n\n/**\n * Configuration for producer tracing\n */\nexport interface ProducerConfig {\n /** Messaging system (kafka, rabbitmq, sqs, etc.) */\n system: MessagingSystem;\n\n /** Destination name (topic/queue) */\n destination: string;\n\n /** Extract message ID from arguments */\n messageIdFrom?: string | ((args: unknown[]) => string | undefined);\n\n /** Extract partition from arguments (Kafka-specific) */\n partitionFrom?: string | ((args: unknown[]) => number | undefined);\n\n /** Extract message key from arguments (Kafka-specific) */\n keyFrom?: string | ((args: unknown[]) => string | undefined);\n\n /** Additional attributes to set on span */\n attributes?: Attributes;\n\n /** Propagate baggage in message headers */\n propagateBaggage?: boolean;\n\n /** Callback before sending (for custom attributes) */\n beforeSend?: (ctx: ProducerContext, args: unknown[]) => void;\n\n /** Callback on error */\n onError?: (error: Error, ctx: ProducerContext) => void;\n\n // ---- Extensible Hooks (\"Bring Your Own\" System Support) ----\n\n /**\n * Hook to add system-specific attributes\n *\n * Use this to add attributes for messaging systems not explicitly supported\n * (e.g., NATS, Temporal, Cloudflare Queues, Redis Streams).\n *\n * @example NATS attributes\n * ```typescript\n * customAttributes: (ctx, args) => ({\n * 'nats.subject': args[0].subject,\n * 'nats.reply_to': args[0].replyTo,\n * 'nats.stream': 'orders',\n * })\n * ```\n *\n * @example Temporal attributes\n * ```typescript\n * customAttributes: (ctx, args) => ({\n * 'temporal.workflow_id': args[0].workflowId,\n * 'temporal.run_id': args[0].runId,\n * 'temporal.task_queue': 'orders-queue',\n * })\n * ```\n */\n customAttributes?: (\n ctx: ProducerContext,\n args: unknown[],\n ) => Record<string, AttributeValue>;\n\n /**\n * Hook for custom header injection (beyond W3C traceparent)\n *\n * Use this to inject headers for systems that use non-standard\n * context propagation formats.\n *\n * @example Datadog headers\n * ```typescript\n * customHeaders: (ctx) => ({\n * 'x-datadog-trace-id': ctx.getTraceId(),\n * 'x-datadog-parent-id': ctx.getSpanId(),\n * })\n * ```\n *\n * @example Custom correlation headers\n * ```typescript\n * customHeaders: (ctx) => ({\n * 'x-correlation-id': correlationId,\n * 'x-request-id': requestId,\n * })\n * ```\n */\n customHeaders?: (ctx: ProducerContext) => Record<string, string>;\n}\n\n/**\n * Configuration for consumer tracing\n */\nexport interface ConsumerConfig {\n /** Messaging system (kafka, rabbitmq, sqs, etc.) */\n system: MessagingSystem;\n\n /** Destination name (topic/queue) */\n destination: string;\n\n /** Consumer group name */\n consumerGroup?: string;\n\n /** Extract headers from message for link creation */\n headersFrom?: string | ((msg: unknown) => Record<string, string> | undefined);\n\n /** Enable batch mode - extract links from all messages */\n batchMode?: boolean;\n\n /** Extract baggage from message headers */\n extractBaggage?: boolean;\n\n /** Additional attributes to set on span */\n attributes?: Attributes;\n\n /** Consumer lag metrics extraction */\n lagMetrics?: LagMetricsConfig;\n\n /** Callback when message goes to DLQ */\n onDLQ?: (ctx: ConsumerContext, reason: string) => void;\n\n /** Callback on error */\n onError?: (error: Error, ctx: ConsumerContext) => void;\n\n // ---- Message Ordering Support ----\n\n /**\n * Message ordering configuration\n *\n * Enable sequence tracking, out-of-order detection, and deduplication.\n *\n * @example Kafka ordering\n * ```typescript\n * ordering: {\n * sequenceFrom: (msg) => msg.offset,\n * partitionKeyFrom: (msg) => msg.key,\n * detectOutOfOrder: true,\n * onOutOfOrder: (ctx, info) => {\n * console.warn(`Out of order: expected ${info.expectedSequence}, got ${info.currentSequence}`);\n * },\n * }\n * ```\n */\n ordering?: OrderingConfig;\n\n // ---- Consumer Group Tracking ----\n\n /**\n * Consumer group tracking configuration\n *\n * Enables observability of consumer group state, including membership,\n * partition assignments, and rebalancing events.\n *\n * @example Kafka consumer group tracking\n * ```typescript\n * consumerGroupTracking: {\n * memberId: () => consumer.memberId,\n * groupInstanceId: process.env.KAFKA_GROUP_INSTANCE_ID,\n * onRebalance: (ctx, event) => {\n * if (event.type === 'revoked') {\n * logger.warn('Partitions revoked', event.partitions);\n * }\n * },\n * trackPartitionLag: true,\n * }\n * ```\n */\n consumerGroupTracking?: ConsumerGroupTrackingConfig;\n\n // ---- Extensible Hooks (\"Bring Your Own\" System Support) ----\n\n /**\n * Hook to add system-specific attributes\n *\n * Use this to add attributes for messaging systems not explicitly supported\n * (e.g., NATS, Temporal, Cloudflare Queues, Redis Streams).\n *\n * @example NATS consumer attributes\n * ```typescript\n * customAttributes: (ctx, msg) => ({\n * 'nats.subject': msg.subject,\n * 'nats.stream': msg.info?.stream,\n * 'nats.consumer': msg.info?.consumer,\n * 'nats.delivered_count': msg.info?.redeliveryCount,\n * })\n * ```\n *\n * @example Cloudflare Queue attributes\n * ```typescript\n * customAttributes: (ctx, msg) => ({\n * 'cloudflare.queue_id': msg.id,\n * 'cloudflare.timestamp_ms': msg.timestamp.getTime(),\n * 'cloudflare.attempts': msg.attempts,\n * })\n * ```\n */\n customAttributes?: (\n ctx: ConsumerContext,\n msg: unknown,\n ) => Record<string, AttributeValue>;\n\n /**\n * Hook for custom context extraction (beyond W3C traceparent)\n *\n * Use this to extract parent span context from systems that use\n * non-standard header formats.\n *\n * @example Datadog context extraction\n * ```typescript\n * customContextExtractor: (headers) => {\n * const traceId = headers['x-datadog-trace-id'];\n * const spanId = headers['x-datadog-parent-id'];\n * if (!traceId || !spanId) return null;\n * return {\n * traceId: traceIdToOtel(traceId),\n * spanId: spanIdToOtel(spanId),\n * traceFlags: TraceFlags.SAMPLED,\n * };\n * }\n * ```\n *\n * @example B3 format extraction\n * ```typescript\n * customContextExtractor: (headers) => {\n * const traceId = headers['x-b3-traceid'];\n * const spanId = headers['x-b3-spanid'];\n * const sampled = headers['x-b3-sampled'] === '1';\n * if (!traceId || !spanId) return null;\n * return {\n * traceId,\n * spanId,\n * traceFlags: sampled ? TraceFlags.SAMPLED : TraceFlags.NONE,\n * };\n * }\n * ```\n */\n customContextExtractor?: (\n headers: Record<string, string>,\n ) => SpanContext | null;\n}\n\n/**\n * Configuration for consumer lag metrics\n */\nexport interface LagMetricsConfig {\n /** Get current message offset */\n getCurrentOffset?: (msg: unknown) => number | undefined;\n\n /** Get end offset (high watermark) - can be async */\n getEndOffset?: () => number | Promise<number>;\n\n /** Get committed offset - can be async */\n getCommittedOffset?: () => number | Promise<number>;\n\n /** Get partition from message */\n getPartition?: (msg: unknown) => number | undefined;\n}\n\n/**\n * Configuration for message ordering tracking\n */\nexport interface OrderingConfig {\n /**\n * Extract sequence number from message\n *\n * Sequence numbers enable out-of-order detection and gap analysis.\n *\n * @example Kafka offset\n * ```typescript\n * sequenceFrom: (msg) => msg.offset\n * ```\n */\n sequenceFrom?: (msg: unknown) => number | undefined;\n\n /**\n * Extract partition key from message\n *\n * Partition keys determine message ordering in Kafka.\n *\n * @example Message key\n * ```typescript\n * partitionKeyFrom: (msg) => msg.key\n * ```\n */\n partitionKeyFrom?: (msg: unknown) => string | undefined;\n\n /**\n * Extract message ID for deduplication\n *\n * Used to detect duplicate messages.\n *\n * @example Idempotency key\n * ```typescript\n * messageIdFrom: (msg) => msg.headers['idempotency-key']\n * ```\n */\n messageIdFrom?: (msg: unknown) => string | undefined;\n\n /**\n * Enable out-of-order detection\n *\n * Tracks sequence numbers per partition and detects when messages\n * arrive out of order.\n *\n * @default false\n */\n detectOutOfOrder?: boolean;\n\n /**\n * Enable deduplication detection\n *\n * Tracks message IDs and detects duplicates within the window.\n *\n * @default false\n */\n detectDuplicates?: boolean;\n\n /**\n * Deduplication window size (number of message IDs to track)\n *\n * @default 1000\n */\n deduplicationWindowSize?: number;\n\n /**\n * Callback when out-of-order message detected\n */\n onOutOfOrder?: (ctx: ConsumerContext, info: OutOfOrderInfo) => void;\n\n /**\n * Callback when duplicate message detected\n */\n onDuplicate?: (ctx: ConsumerContext, messageId: string) => void;\n}\n\n/**\n * Information about out-of-order message\n */\nexport interface OutOfOrderInfo {\n /** Current sequence number */\n currentSequence: number;\n\n /** Expected sequence number */\n expectedSequence: number;\n\n /** Partition key (if available) */\n partitionKey?: string;\n\n /** Gap size (positive = gap, negative = out of order) */\n gap: number;\n}\n\n// ============================================================================\n// Consumer Group Tracking Types\n// ============================================================================\n\n/**\n * Configuration for consumer group tracking\n *\n * Enables observability of consumer group state, including membership,\n * partition assignments, and rebalancing events.\n *\n * @example Kafka consumer group tracking\n * ```typescript\n * consumerGroupTracking: {\n * memberId: consumer.memberId,\n * groupInstanceId: process.env.CONSUMER_ID,\n * onRebalance: (ctx, event) => {\n * if (event.type === 'assigned') {\n * console.log(`Assigned partitions: ${event.partitions}`);\n * }\n * },\n * }\n * ```\n */\nexport interface ConsumerGroupTrackingConfig {\n /**\n * Consumer member ID\n *\n * Unique identifier assigned by the broker to this consumer.\n */\n memberId?: string | (() => string | undefined);\n\n /**\n * Static group instance ID (for static membership)\n *\n * If set, enables static group membership which prevents\n * rebalances when consumers restart.\n */\n groupInstanceId?: string | (() => string | undefined);\n\n /**\n * Callback when rebalance occurs\n */\n onRebalance?: (ctx: ConsumerContext, event: RebalanceEvent) => void;\n\n /**\n * Callback when partitions are assigned\n */\n onPartitionsAssigned?: (\n ctx: ConsumerContext,\n partitions: PartitionAssignment[],\n ) => void;\n\n /**\n * Callback when partitions are revoked\n */\n onPartitionsRevoked?: (\n ctx: ConsumerContext,\n partitions: PartitionAssignment[],\n ) => void;\n\n /**\n * Track consumer lag per partition\n *\n * @default true\n */\n trackPartitionLag?: boolean;\n\n /**\n * Track consumer heartbeat health\n *\n * @default false\n */\n trackHeartbeat?: boolean;\n\n /**\n * Heartbeat interval in milliseconds (for health tracking)\n */\n heartbeatIntervalMs?: number;\n}\n\n/**\n * Rebalance event types\n */\nexport type RebalanceType = 'assigned' | 'revoked' | 'lost';\n\n/**\n * Rebalance event information\n */\nexport interface RebalanceEvent {\n /** Type of rebalance event */\n type: RebalanceType;\n\n /** Partitions affected by the rebalance */\n partitions: PartitionAssignment[];\n\n /** Timestamp of the rebalance event */\n timestamp: number;\n\n /** Generation ID (increments on each rebalance) */\n generation?: number;\n\n /** Consumer member ID */\n memberId?: string;\n\n /** Reason for the rebalance (if available) */\n reason?: string;\n}\n\n/**\n * Partition assignment information\n */\nexport interface PartitionAssignment {\n /** Topic name */\n topic: string;\n\n /** Partition number */\n partition: number;\n\n /** Initial offset (if available) */\n offset?: number;\n\n /** Metadata (if available) */\n metadata?: string;\n}\n\n/**\n * Consumer group state snapshot\n */\nexport interface ConsumerGroupState {\n /** Consumer group name */\n groupId: string;\n\n /** Consumer member ID */\n memberId?: string;\n\n /** Static instance ID (if using static membership) */\n groupInstanceId?: string;\n\n /** Currently assigned partitions */\n assignedPartitions: PartitionAssignment[];\n\n /** Group generation ID */\n generation?: number;\n\n /** Whether the consumer is currently active */\n isActive: boolean;\n\n /** Last heartbeat timestamp */\n lastHeartbeat?: number;\n\n /** Consumer state (stable, preparing_rebalance, completing_rebalance, dead) */\n state?:\n | 'stable'\n | 'preparing_rebalance'\n | 'completing_rebalance'\n | 'dead'\n | 'empty';\n}\n\n/**\n * Partition lag information\n */\nexport interface PartitionLag {\n /** Topic name */\n topic: string;\n\n /** Partition number */\n partition: number;\n\n /** Current consumer offset */\n currentOffset: number;\n\n /** End offset (high watermark) */\n endOffset: number;\n\n /** Calculated lag */\n lag: number;\n\n /** Timestamp of measurement */\n timestamp: number;\n}\n\n/**\n * DLQ failure category types\n */\nexport type DLQReasonCategory =\n | 'validation'\n | 'processing'\n | 'timeout'\n | 'poison'\n | 'unknown';\n\n/**\n * Options for enhanced DLQ recording\n */\nexport interface DLQOptions {\n /**\n * Automatically link to the producer span context\n *\n * When true, creates a span link from the DLQ event back to\n * the original producer span for correlation.\n *\n * @default true\n */\n linkToProducer?: boolean;\n\n /**\n * Category of the failure that caused DLQ routing\n *\n * - validation: Message failed schema/format validation\n * - processing: Business logic error during processing\n * - timeout: Processing exceeded allowed time\n * - poison: Message causes repeated failures (poison pill)\n * - unknown: Uncategorized failure\n */\n reasonCategory?: DLQReasonCategory;\n\n /**\n * Number of processing attempts before DLQ routing\n */\n attemptCount?: number;\n\n /**\n * The original error that caused DLQ routing\n *\n * Error details are recorded as span attributes for debugging.\n */\n originalError?: Error;\n\n /**\n * Additional metadata to record with the DLQ event\n */\n metadata?: Record<string, string | number | boolean>;\n}\n\n/**\n * Options for recording DLQ replay\n */\nexport interface DLQReplayOptions {\n /**\n * Original span context from DLQ message\n *\n * If provided, creates a span link to correlate with the original failure.\n */\n originalDLQSpanContext?: SpanContext;\n\n /**\n * Time spent in DLQ before replay (milliseconds)\n */\n dlqDwellTimeMs?: number;\n\n /**\n * Retry attempt number for this replay\n */\n replayAttempt?: number;\n}\n\n/**\n * Extended trace context for producers with header injection\n */\nexport interface ProducerContext extends TraceContext {\n /**\n * Get W3C trace context headers to inject into message\n *\n * @returns Headers object with traceparent and optionally tracestate\n *\n * @example\n * ```typescript\n * const headers = ctx.getTraceHeaders();\n * await producer.send({\n * topic: 'events',\n * messages: [{ value: data, headers }]\n * });\n * ```\n */\n getTraceHeaders(): { traceparent: string; tracestate?: string };\n\n /**\n * Get all propagation headers including baggage if enabled\n *\n * @returns Headers object with all W3C trace context headers\n */\n getAllPropagationHeaders(): Record<string, string>;\n\n /**\n * Get all headers including custom headers from customHeaders hook\n *\n * This combines W3C trace context headers, baggage (if enabled),\n * and any custom headers defined via the customHeaders hook.\n *\n * @returns Combined headers object\n *\n * @example\n * ```typescript\n * const headers = ctx.getFullHeaders();\n * // Contains: traceparent, tracestate, baggage (if enabled), and custom headers\n * await producer.send({ topic, messages: [{ value, headers }] });\n * ```\n */\n getFullHeaders(): Record<string, string>;\n}\n\n/**\n * Extended trace context for consumers\n */\nexport interface ConsumerContext extends TraceContext {\n /**\n * Record that a message is being sent to DLQ\n *\n * Enhanced with auto-linking to producer span, failure categorization,\n * and detailed error recording for comprehensive DLQ observability.\n *\n * @param reason - Human-readable reason for DLQ routing\n * @param dlqNameOrOptions - DLQ name (string) or enhanced options object\n * @param options - Enhanced DLQ options (when second param is dlqName)\n *\n * @example Basic usage (backwards compatible)\n * ```typescript\n * ctx.recordDLQ('Schema validation failed', 'orders-dlq');\n * ```\n *\n * @example Enhanced usage with options\n * ```typescript\n * ctx.recordDLQ('Invalid order total', 'orders-dlq', {\n * reasonCategory: 'validation',\n * attemptCount: 3,\n * originalError: error,\n * linkToProducer: true, // Auto-links to producer span\n * });\n * ```\n *\n * @example Using options object as second param\n * ```typescript\n * ctx.recordDLQ('Processing timeout', {\n * reasonCategory: 'timeout',\n * attemptCount: 5,\n * metadata: { processingTimeMs: 30000 },\n * });\n * ```\n */\n recordDLQ(reason: string, dlqName?: string, options?: DLQOptions): void;\n recordDLQ(reason: string, options?: DLQOptions): void;\n\n /**\n * Record replay of a message from DLQ\n *\n * Use this when processing a message that was replayed from the DLQ\n * to create links for correlation and track replay metrics.\n *\n * @param options - Replay tracking options\n *\n * @example\n * ```typescript\n * export const processReplay = traceConsumer({\n * system: 'kafka',\n * destination: 'orders-dlq-replay',\n * })(ctx => async (message) => {\n * ctx.recordReplay({\n * originalDLQSpanContext: extractSpanContext(message.headers),\n * dlqDwellTimeMs: Date.now() - message.timestamp,\n * replayAttempt: message.replayCount,\n * });\n * await processOrder(message);\n * });\n * ```\n */\n recordReplay(options?: DLQReplayOptions): void;\n\n /**\n * Record retry attempt\n *\n * @param attemptNumber - Current retry attempt (1-based)\n * @param maxAttempts - Maximum retry attempts\n */\n recordRetry(attemptNumber: number, maxAttempts?: number): void;\n\n /**\n * Get the producer span context links extracted from message headers\n *\n * Useful for accessing the producer span context when implementing\n * custom DLQ or retry logic.\n *\n * @returns Array of span links extracted from the message, or empty array\n */\n getProducerLinks(): Link[];\n\n // ---- Message Ordering Methods ----\n\n /**\n * Check if the current message is a duplicate\n *\n * @returns True if the message has been seen before\n */\n isDuplicate(): boolean;\n\n /**\n * Check if the current message arrived out of order\n *\n * @returns Out of order info, or null if in order\n */\n getOutOfOrderInfo(): OutOfOrderInfo | null;\n\n /**\n * Get current sequence number\n *\n * @returns The sequence number, or null if not configured\n */\n getSequenceNumber(): number | null;\n\n /**\n * Get partition key\n *\n * @returns The partition key, or null if not configured\n */\n getPartitionKey(): string | null;\n\n // ---- Consumer Group Methods ----\n\n /**\n * Record a rebalance event\n *\n * Call this when the consumer group undergoes a rebalance to capture\n * the event as a span event with partition assignment details.\n *\n * @param event - The rebalance event details\n *\n * @example\n * ```typescript\n * consumer.on('rebalance', (event) => {\n * ctx.recordRebalance({\n * type: event.type,\n * partitions: event.assignment,\n * generation: event.generationId,\n * timestamp: Date.now(),\n * });\n * });\n * ```\n */\n recordRebalance(event: RebalanceEvent): void;\n\n /**\n * Record a heartbeat event\n *\n * Call this on each heartbeat to track consumer health.\n *\n * @param healthy - Whether the heartbeat was successful\n * @param latencyMs - Optional latency of the heartbeat in milliseconds\n */\n recordHeartbeat(healthy: boolean, latencyMs?: number): void;\n\n /**\n * Record partition lag for a specific partition\n *\n * @param lag - The partition lag information\n */\n recordPartitionLag(lag: PartitionLag): void;\n\n /**\n * Get the current consumer group state\n *\n * @returns The current consumer group state, or null if not configured\n */\n getConsumerGroupState(): ConsumerGroupState | null;\n\n /**\n * Get the consumer member ID\n *\n * @returns The member ID, or null if not available\n */\n getMemberId(): string | null;\n\n /**\n * Get the current partition assignments\n *\n * @returns Array of assigned partitions, or empty array if none\n */\n getAssignedPartitions(): PartitionAssignment[];\n}\n\n// ============================================================================\n// Producer Helper\n// ============================================================================\n\n/**\n * Create a traced message producer function\n *\n * Sets SpanKind.PRODUCER, OTel messaging semantic attributes,\n * and provides context injection helpers.\n *\n * @param config - Producer configuration\n * @returns Factory function that wraps your producer logic\n *\n * @example Kafka producer\n * ```typescript\n * export const publishUserEvent = traceProducer({\n * system: 'kafka',\n * destination: 'user-events',\n * messageIdFrom: (args) => args[0]?.eventId,\n * })(ctx => async (event: UserEvent) => {\n * const headers = ctx.getTraceHeaders();\n * await producer.send({\n * topic: 'user-events',\n * messages: [{\n * key: event.userId,\n * value: JSON.stringify(event),\n * headers,\n * }]\n * });\n * });\n * ```\n *\n * @example SQS producer\n * ```typescript\n * export const sendToSQS = traceProducer({\n * system: 'sqs',\n * destination: 'orders-queue',\n * })(ctx => async (order: Order) => {\n * const headers = ctx.getAllPropagationHeaders();\n * await sqs.sendMessage({\n * QueueUrl: QUEUE_URL,\n * MessageBody: JSON.stringify(order),\n * MessageAttributes: headersToSQSAttributes(headers),\n * });\n * });\n * ```\n */\nexport function traceProducer<TArgs extends unknown[], TReturn>(\n config: ProducerConfig,\n) {\n const spanName = `${config.system}.publish ${config.destination}`;\n\n return (\n fnFactory: (ctx: ProducerContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>(\n { name: spanName, spanKind: SpanKind.PRODUCER },\n (baseCtx) => {\n // Extend context with producer-specific methods\n const ctx = extendContextForProducer(baseCtx, config);\n\n // Set semantic convention attributes\n setProducerAttributes(ctx, config);\n\n // Call beforeSend callback if provided\n return (...args: TArgs) => {\n // Extract dynamic attributes from args\n setDynamicProducerAttributes(ctx, config, args);\n\n // Apply custom attributes hook if provided\n if (config.customAttributes) {\n const customAttrs = config.customAttributes(ctx, args);\n for (const [key, value] of Object.entries(customAttrs)) {\n if (value !== undefined && value !== null) {\n ctx.setAttribute(key, value as string | number | boolean);\n }\n }\n }\n\n if (config.beforeSend) {\n config.beforeSend(ctx, args);\n }\n\n // Execute user's function\n const userFn = fnFactory(ctx);\n return userFn(...args).catch((error) => {\n if (config.onError) {\n config.onError(error as Error, ctx);\n }\n throw error;\n });\n };\n },\n );\n };\n}\n\n// ============================================================================\n// Consumer Helper\n// ============================================================================\n\n/**\n * Create a traced message consumer function\n *\n * Sets SpanKind.CONSUMER, OTel messaging semantic attributes,\n * automatically extracts links from producer trace headers,\n * and provides DLQ/retry recording helpers.\n *\n * @param config - Consumer configuration\n * @returns Factory function that wraps your consumer logic\n *\n * @example Kafka consumer (single message)\n * ```typescript\n * export const processUserEvent = traceConsumer({\n * system: 'kafka',\n * destination: 'user-events',\n * consumerGroup: 'event-processor',\n * headersFrom: (msg) => msg.headers,\n * })(ctx => async (message: KafkaMessage) => {\n * // Link to producer span is automatically created\n * const event = JSON.parse(message.value.toString());\n * await processEvent(event);\n * });\n * ```\n *\n * @example Kafka consumer (batch mode)\n * ```typescript\n * export const processUserEventBatch = traceConsumer({\n * system: 'kafka',\n * destination: 'user-events',\n * consumerGroup: 'event-processor',\n * batchMode: true,\n * headersFrom: (msg) => msg.headers,\n * lagMetrics: {\n * getCurrentOffset: (msg) => msg.offset,\n * getEndOffset: () => consumer.getHighWatermark(),\n * getPartition: (msg) => msg.partition,\n * },\n * })(ctx => async (messages: KafkaMessage[]) => {\n * // Links to all producer spans are automatically created\n * for (const msg of messages) {\n * await processEvent(JSON.parse(msg.value.toString()));\n * }\n * });\n * ```\n *\n * @example SQS consumer with DLQ handling\n * ```typescript\n * export const processSQSMessage = traceConsumer({\n * system: 'sqs',\n * destination: 'orders-queue',\n * headersFrom: (msg) => sqsAttributesToHeaders(msg.MessageAttributes),\n * onDLQ: (ctx, reason) => {\n * ctx.recordDLQ(reason, 'orders-dlq');\n * },\n * })(ctx => async (message: SQSMessage) => {\n * try {\n * await processOrder(JSON.parse(message.Body));\n * } catch (error) {\n * if (message.ApproximateReceiveCount > 3) {\n * ctx.recordDLQ(error.message);\n * throw error;\n * }\n * ctx.recordRetry(message.ApproximateReceiveCount, 3);\n * throw error;\n * }\n * });\n * ```\n */\nexport function traceConsumer<TArgs extends unknown[], TReturn>(\n config: ConsumerConfig,\n) {\n const operation = config.batchMode ? 'receive' : 'process';\n const spanName = `${config.system}.${operation} ${config.destination}`;\n\n return (\n fnFactory: (ctx: ConsumerContext) => (...args: TArgs) => Promise<TReturn>,\n ): ((...args: TArgs) => Promise<TReturn>) => {\n return trace<TArgs, TReturn>(\n { name: spanName, spanKind: SpanKind.CONSUMER },\n (baseCtx) => {\n // Create mutable storage for producer links (populated during extractAndAddLinks)\n const linkStorage: ProducerLinkStorage = { links: [] };\n\n // Create mutable ordering state (populated during extractOrdering)\n const orderingState: OrderingState = {\n sequenceNumber: null,\n partitionKey: null,\n messageId: null,\n isDuplicate: false,\n outOfOrderInfo: null,\n };\n\n // Create consumer group state\n const groupTracking = config.consumerGroupTracking;\n const groupState: ConsumerGroupStateInternal = {\n memberId:\n typeof groupTracking?.memberId === 'function'\n ? (groupTracking.memberId() ?? null)\n : (groupTracking?.memberId ?? null),\n groupInstanceId:\n typeof groupTracking?.groupInstanceId === 'function'\n ? (groupTracking.groupInstanceId() ?? null)\n : (groupTracking?.groupInstanceId ?? null),\n assignedPartitions: [],\n generation: null,\n isActive: true,\n lastHeartbeat: null,\n state: null,\n };\n\n // Extend context with consumer-specific methods\n const ctx = extendContextForConsumer(\n baseCtx,\n config,\n linkStorage,\n orderingState,\n groupState,\n );\n\n // Set semantic convention attributes\n setConsumerAttributes(ctx, config);\n\n return async (...args: TArgs) => {\n // Extract links from message headers (includes customContextExtractor if provided)\n // This also populates linkStorage.links for getProducerLinks() and DLQ auto-linking\n await extractAndAddLinks(ctx, config, args, linkStorage);\n\n // Extract and process ordering information\n if (config.ordering) {\n extractAndProcessOrdering(ctx, config, args, orderingState);\n }\n\n // Extract lag metrics if configured\n if (config.lagMetrics) {\n await extractLagMetrics(ctx, config.lagMetrics, args);\n }\n\n // Apply custom attributes hook if provided\n if (config.customAttributes) {\n // For batch mode, extract first message; for single mode, use args[0] directly\n const batch = args[0];\n const msg =\n config.batchMode && Array.isArray(batch) && batch.length > 0\n ? batch[0]\n : batch;\n // Only call hook if we have a message\n if (msg !== undefined) {\n const customAttrs = config.customAttributes(ctx, msg);\n for (const [key, value] of Object.entries(customAttrs)) {\n if (value !== undefined && value !== null) {\n ctx.setAttribute(key, value as string | number | boolean);\n }\n }\n }\n }\n\n // Execute user's function\n const userFn = fnFactory(ctx);\n return userFn(...args).catch((error) => {\n if (config.onError) {\n config.onError(error as Error, ctx);\n }\n throw error;\n });\n };\n },\n );\n };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Extend base context with producer-specific methods\n */\nfunction extendContextForProducer(\n baseCtx: TraceContext,\n config: ProducerConfig,\n): ProducerContext {\n // Create a reference for `this` binding in getFullHeaders\n const producerCtx: ProducerContext = {\n ...baseCtx,\n\n getTraceHeaders(): { traceparent: string; tracestate?: string } {\n const headers: Record<string, string> = {};\n propagation.inject(context.active(), headers);\n\n const result: { traceparent: string; tracestate?: string } = {\n traceparent: headers['traceparent'] || '',\n };\n\n if (headers['tracestate']) {\n result.tracestate = headers['tracestate'];\n }\n\n return result;\n },\n\n getAllPropagationHeaders(): Record<string, string> {\n const headers: Record<string, string> = {};\n propagation.inject(context.active(), headers);\n\n // Include baggage if configured\n if (config.propagateBaggage) {\n const baggage = propagation.getBaggage(context.active());\n if (baggage) {\n const entries: string[] = [];\n for (const [key, value] of baggage.getAllEntries()) {\n entries.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(value.value)}`,\n );\n }\n if (entries.length > 0) {\n headers['baggage'] = entries.join(',');\n }\n }\n }\n\n return headers;\n },\n\n getFullHeaders(): Record<string, string> {\n // Start with all propagation headers (W3C + baggage)\n const headers = producerCtx.getAllPropagationHeaders();\n\n // Add custom headers from hook if configured\n if (config.customHeaders) {\n const customHeaders = config.customHeaders(producerCtx);\n Object.assign(headers, customHeaders);\n }\n\n return headers;\n },\n };\n\n return producerCtx;\n}\n\n/**\n * Mutable storage for producer links (populated during extractAndAddLinks)\n */\ninterface ProducerLinkStorage {\n links: Link[];\n}\n\n/**\n * Ordering state for a single message\n */\ninterface OrderingState {\n sequenceNumber: number | null;\n partitionKey: string | null;\n messageId: string | null;\n isDuplicate: boolean;\n outOfOrderInfo: OutOfOrderInfo | null;\n}\n\n/**\n * Global sequence tracker for out-of-order detection (per partition)\n */\nconst sequenceTrackers = new Map<string, number>();\n\n/**\n * Global deduplication window (LRU-style using Map insertion order)\n */\nconst deduplicationWindow = new Map<string, number>();\nconst DEFAULT_DEDUP_WINDOW_SIZE = 1000;\n\n/**\n * Clean up old entries from deduplication window\n */\nfunction trimDeduplicationWindow(maxSize: number): void {\n if (deduplicationWindow.size > maxSize) {\n const excess = deduplicationWindow.size - maxSize;\n const iterator = deduplicationWindow.keys();\n for (let i = 0; i < excess; i++) {\n const key = iterator.next().value;\n if (key) deduplicationWindow.delete(key);\n }\n }\n}\n\n/**\n * Consumer group state tracking for a single consumer\n */\ninterface ConsumerGroupStateInternal {\n memberId: string | null;\n groupInstanceId: string | null;\n assignedPartitions: PartitionAssignment[];\n generation: number | null;\n isActive: boolean;\n lastHeartbeat: number | null;\n state: ConsumerGroupState['state'] | null;\n}\n\n/**\n * Extend base context with consumer-specific methods\n */\nfunction extendContextForConsumer(\n baseCtx: TraceContext,\n config: ConsumerConfig,\n linkStorage: ProducerLinkStorage,\n orderingState: OrderingState,\n groupState: ConsumerGroupStateInternal,\n): ConsumerContext {\n const consumerCtx: ConsumerContext = {\n ...baseCtx,\n\n recordDLQ(\n reason: string,\n dlqNameOrOptions?: string | DLQOptions,\n optionsParam?: DLQOptions,\n ): void {\n // Parse overloaded arguments\n let dlqName: string | undefined;\n let options: DLQOptions | undefined;\n\n if (typeof dlqNameOrOptions === 'string') {\n dlqName = dlqNameOrOptions;\n options = optionsParam;\n } else if (typeof dlqNameOrOptions === 'object') {\n options = dlqNameOrOptions;\n }\n\n // Default linkToProducer to true\n const linkToProducer = options?.linkToProducer ?? true;\n\n // Set basic DLQ attributes\n baseCtx.setAttribute('messaging.dlq.reason', reason);\n if (dlqName) {\n baseCtx.setAttribute('messaging.dlq.name', dlqName);\n }\n\n // Set enhanced DLQ attributes\n if (options?.reasonCategory) {\n baseCtx.setAttribute(\n 'messaging.dlq.reason_category',\n options.reasonCategory,\n );\n }\n if (options?.attemptCount !== undefined) {\n baseCtx.setAttribute(\n 'messaging.dlq.attempt_count',\n options.attemptCount,\n );\n }\n if (options?.originalError) {\n baseCtx.setAttribute(\n 'messaging.dlq.error.type',\n options.originalError.name,\n );\n baseCtx.setAttribute(\n 'messaging.dlq.error.message',\n options.originalError.message,\n );\n }\n\n // Set custom metadata\n if (options?.metadata) {\n for (const [key, value] of Object.entries(options.metadata)) {\n baseCtx.setAttribute(`messaging.dlq.metadata.${key}`, value);\n }\n }\n\n // Auto-link to producer span if available and enabled\n const producerLink = linkStorage.links[0];\n if (linkToProducer && producerLink) {\n baseCtx.setAttribute(\n 'messaging.dlq.producer_trace_id',\n producerLink.context.traceId,\n );\n baseCtx.setAttribute(\n 'messaging.dlq.producer_span_id',\n producerLink.context.spanId,\n );\n }\n\n // Record event with all attributes\n const eventAttrs: Record<string, string | number | boolean> = {\n 'messaging.dlq.reason': reason,\n ...(dlqName && { 'messaging.dlq.name': dlqName }),\n ...(options?.reasonCategory && {\n 'messaging.dlq.reason_category': options.reasonCategory,\n }),\n ...(options?.attemptCount !== undefined && {\n 'messaging.dlq.attempt_count': options.attemptCount,\n }),\n ...(options?.originalError && {\n 'messaging.dlq.error.type': options.originalError.name,\n 'messaging.dlq.error.message': options.originalError.message,\n }),\n };\n\n // Add producer link info to event if available\n if (linkToProducer && producerLink) {\n eventAttrs['messaging.dlq.producer_trace_id'] =\n producerLink.context.traceId;\n eventAttrs['messaging.dlq.producer_span_id'] =\n producerLink.context.spanId;\n }\n\n baseCtx.addEvent('dlq_routed', eventAttrs);\n\n // Call user's onDLQ callback if provided\n if (config.onDLQ) {\n config.onDLQ(consumerCtx, reason);\n }\n },\n\n recordReplay(options?: DLQReplayOptions): void {\n baseCtx.setAttribute('messaging.replay', true);\n\n if (options?.replayAttempt !== undefined) {\n baseCtx.setAttribute('messaging.replay.attempt', options.replayAttempt);\n }\n if (options?.dlqDwellTimeMs !== undefined) {\n baseCtx.setAttribute(\n 'messaging.replay.dwell_time_ms',\n options.dlqDwellTimeMs,\n );\n }\n\n // Create span link to original DLQ span if provided\n if (options?.originalDLQSpanContext) {\n baseCtx.addLinks([\n {\n context: options.originalDLQSpanContext,\n attributes: { 'messaging.link.source': 'dlq_replay' },\n },\n ]);\n }\n\n const eventAttrs: Record<string, string | number | boolean> = {\n 'messaging.replay': true,\n ...(options?.replayAttempt !== undefined && {\n 'messaging.replay.attempt': options.replayAttempt,\n }),\n ...(options?.dlqDwellTimeMs !== undefined && {\n 'messaging.replay.dwell_time_ms': options.dlqDwellTimeMs,\n }),\n };\n\n baseCtx.addEvent('dlq_replay', eventAttrs);\n },\n\n recordRetry(attemptNumber: number, maxAttempts?: number): void {\n baseCtx.setAttribute('messaging.retry.count', attemptNumber);\n if (maxAttempts !== undefined) {\n baseCtx.setAttribute('messaging.retry.max_attempts', maxAttempts);\n }\n baseCtx.addEvent('retry_attempt', {\n 'messaging.retry.count': attemptNumber,\n ...(maxAttempts !== undefined && {\n 'messaging.retry.max_attempts': maxAttempts,\n }),\n });\n },\n\n getProducerLinks(): Link[] {\n return [...linkStorage.links];\n },\n\n // ---- Ordering Methods ----\n\n isDuplicate(): boolean {\n return orderingState.isDuplicate;\n },\n\n getOutOfOrderInfo(): OutOfOrderInfo | null {\n return orderingState.outOfOrderInfo;\n },\n\n getSequenceNumber(): number | null {\n return orderingState.sequenceNumber;\n },\n\n getPartitionKey(): string | null {\n return orderingState.partitionKey;\n },\n\n // ---- Consumer Group Methods ----\n\n recordRebalance(event: RebalanceEvent): void {\n // Update internal state including consumer group state\n if (event.type === 'assigned') {\n groupState.assignedPartitions = event.partitions;\n groupState.isActive = true;\n // After assignment completes, group is stable\n groupState.state = 'stable';\n } else if (event.type === 'revoked' || event.type === 'lost') {\n // Remove revoked partitions from assignments\n const revokedSet = new Set(\n event.partitions.map((p) => `${p.topic}:${p.partition}`),\n );\n groupState.assignedPartitions = groupState.assignedPartitions.filter(\n (p) => !revokedSet.has(`${p.topic}:${p.partition}`),\n );\n if (event.type === 'lost') {\n groupState.isActive = false;\n // Consumer lost connection, mark as dead\n groupState.state = 'dead';\n } else {\n // Revoked means rebalance is starting\n // If no partitions remain, consumer is empty; otherwise preparing for rebalance\n groupState.state =\n groupState.assignedPartitions.length === 0\n ? 'empty'\n : 'preparing_rebalance';\n }\n }\n\n if (event.generation !== undefined) {\n groupState.generation = event.generation;\n }\n if (event.memberId) {\n groupState.memberId = event.memberId;\n }\n\n // Set span attributes\n baseCtx.setAttribute(\n 'messaging.consumer_group.rebalance.type',\n event.type,\n );\n baseCtx.setAttribute(\n 'messaging.consumer_group.rebalance.partition_count',\n event.partitions.length,\n );\n if (event.generation !== undefined) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.generation',\n event.generation,\n );\n }\n if (event.memberId) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.member_id',\n event.memberId,\n );\n }\n if (event.reason) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.rebalance.reason',\n event.reason,\n );\n }\n\n // Set the new state on the span\n if (groupState.state) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.state',\n groupState.state,\n );\n }\n\n // Record event\n const eventAttrs: Record<string, string | number | boolean> = {\n 'messaging.consumer_group.rebalance.type': event.type,\n 'messaging.consumer_group.rebalance.partition_count':\n event.partitions.length,\n 'messaging.consumer_group.rebalance.timestamp': event.timestamp,\n ...(event.generation !== undefined && {\n 'messaging.consumer_group.generation': event.generation,\n }),\n ...(event.memberId && {\n 'messaging.consumer_group.member_id': event.memberId,\n }),\n ...(event.reason && {\n 'messaging.consumer_group.rebalance.reason': event.reason,\n }),\n ...(groupState.state && {\n 'messaging.consumer_group.state': groupState.state,\n }),\n };\n\n // Add partition details if not too many\n if (event.partitions.length <= 10) {\n eventAttrs['messaging.consumer_group.rebalance.partitions'] =\n event.partitions.map((p) => `${p.topic}:${p.partition}`).join(',');\n }\n\n baseCtx.addEvent(`consumer_group_${event.type}`, eventAttrs);\n\n // Call user's onRebalance callback if provided\n if (config.consumerGroupTracking?.onRebalance) {\n config.consumerGroupTracking.onRebalance(consumerCtx, event);\n }\n\n // Call specific callbacks\n if (\n event.type === 'assigned' &&\n config.consumerGroupTracking?.onPartitionsAssigned\n ) {\n config.consumerGroupTracking.onPartitionsAssigned(\n consumerCtx,\n event.partitions,\n );\n }\n if (\n event.type === 'revoked' &&\n config.consumerGroupTracking?.onPartitionsRevoked\n ) {\n config.consumerGroupTracking.onPartitionsRevoked(\n consumerCtx,\n event.partitions,\n );\n }\n },\n\n recordHeartbeat(healthy: boolean, latencyMs?: number): void {\n groupState.lastHeartbeat = Date.now();\n\n baseCtx.setAttribute(\n 'messaging.consumer_group.heartbeat.healthy',\n healthy,\n );\n if (latencyMs !== undefined) {\n baseCtx.setAttribute(\n 'messaging.consumer_group.heartbeat.latency_ms',\n latencyMs,\n );\n }\n\n baseCtx.addEvent('consumer_group_heartbeat', {\n 'messaging.consumer_group.heartbeat.healthy': healthy,\n 'messaging.consumer_group.heartbeat.timestamp':\n groupState.lastHeartbeat,\n ...(latencyMs !== undefined && {\n 'messaging.consumer_group.heartbeat.latency_ms': latencyMs,\n }),\n });\n },\n\n recordPartitionLag(lag: PartitionLag): void {\n const prefix = `messaging.consumer_group.lag.${lag.topic}.${lag.partition}`;\n\n baseCtx.setAttribute(`${prefix}.current_offset`, lag.currentOffset);\n baseCtx.setAttribute(`${prefix}.end_offset`, lag.endOffset);\n baseCtx.setAttribute(`${prefix}.lag`, lag.lag);\n\n baseCtx.addEvent('partition_lag_recorded', {\n 'messaging.consumer_group.lag.topic': lag.topic,\n 'messaging.consumer_group.lag.partition': lag.partition,\n 'messaging.consumer_group.lag.current_offset': lag.currentOffset,\n 'messaging.consumer_group.lag.end_offset': lag.endOffset,\n 'messaging.consumer_group.lag.lag': lag.lag,\n 'messaging.consumer_group.lag.timestamp': lag.timestamp,\n });\n },\n\n getConsumerGroupState(): ConsumerGroupState | null {\n if (!config.consumerGroup) {\n return null;\n }\n\n return {\n groupId: config.consumerGroup,\n memberId: groupState.memberId ?? undefined,\n groupInstanceId: groupState.groupInstanceId ?? undefined,\n assignedPartitions: [...groupState.assignedPartitions],\n generation: groupState.generation ?? undefined,\n isActive: groupState.isActive,\n lastHeartbeat: groupState.lastHeartbeat ?? undefined,\n state: groupState.state ?? undefined,\n };\n },\n\n getMemberId(): string | null {\n return groupState.memberId;\n },\n\n getAssignedPartitions(): PartitionAssignment[] {\n return [...groupState.assignedPartitions];\n },\n };\n\n return consumerCtx;\n}\n\n/**\n * Set OTel semantic convention attributes for producer\n */\nfunction setProducerAttributes(\n ctx: TraceContext,\n config: ProducerConfig,\n): void {\n ctx.setAttribute('messaging.system', config.system);\n ctx.setAttribute('messaging.operation', 'publish');\n ctx.setAttribute('messaging.destination.name', config.destination);\n\n // Set system-specific destination attribute\n if (config.system === 'kafka') {\n ctx.setAttribute('messaging.kafka.destination.topic', config.destination);\n }\n\n // Set custom attributes\n if (config.attributes) {\n setCustomAttributes(ctx, config.attributes);\n }\n}\n\n/**\n * Set dynamic producer attributes from arguments\n */\nfunction setDynamicProducerAttributes(\n ctx: TraceContext,\n config: ProducerConfig,\n args: unknown[],\n): void {\n // Message ID\n if (config.messageIdFrom) {\n const messageId = extractValue(config.messageIdFrom, args);\n if (messageId !== undefined) {\n ctx.setAttribute('messaging.message.id', String(messageId));\n }\n }\n\n // Partition (Kafka-specific)\n if (config.partitionFrom) {\n const partition = extractValue(config.partitionFrom, args);\n if (partition !== undefined) {\n ctx.setAttribute(\n 'messaging.kafka.destination.partition',\n Number(partition),\n );\n }\n }\n\n // Key (Kafka-specific)\n if (config.keyFrom) {\n const key = extractValue(config.keyFrom, args);\n if (key !== undefined) {\n ctx.setAttribute('messaging.kafka.message.key', String(key));\n }\n }\n}\n\n/**\n * Set OTel semantic convention attributes for consumer\n */\nfunction setConsumerAttributes(\n ctx: TraceContext,\n config: ConsumerConfig,\n): void {\n ctx.setAttribute('messaging.system', config.system);\n ctx.setAttribute(\n 'messaging.operation',\n config.batchMode ? 'receive' : 'process',\n );\n ctx.setAttribute('messaging.destination.name', config.destination);\n\n // Consumer group\n if (config.consumerGroup) {\n ctx.setAttribute('messaging.consumer.group', config.consumerGroup);\n\n // System-specific consumer group attribute\n if (config.system === 'kafka') {\n ctx.setAttribute('messaging.kafka.consumer.group', config.consumerGroup);\n }\n }\n\n // Set system-specific destination attribute\n if (config.system === 'kafka') {\n ctx.setAttribute('messaging.kafka.destination.topic', config.destination);\n }\n\n // Set custom attributes\n if (config.attributes) {\n setCustomAttributes(ctx, config.attributes);\n }\n}\n\n/**\n * Extract links from message headers and add to span\n *\n * Uses W3C trace context by default, falls back to customContextExtractor if provided.\n * Also populates linkStorage for getProducerLinks() and DLQ auto-linking.\n */\nasync function extractAndAddLinks(\n ctx: ConsumerContext,\n config: ConsumerConfig,\n args: unknown[],\n linkStorage: ProducerLinkStorage,\n): Promise<void> {\n if (!config.headersFrom && !config.customContextExtractor) {\n return;\n }\n\n const links: Link[] = [];\n\n if (config.batchMode && Array.isArray(args[0])) {\n // Batch mode - extract links from all messages\n const messages = args[0] as unknown[];\n\n if (config.headersFrom) {\n const batchLinks = extractLinksFromBatch(\n messages.map((msg) => {\n const headers = extractHeaders(config.headersFrom!, msg);\n return { headers };\n }),\n 'headers',\n );\n links.push(...batchLinks);\n }\n\n // Try custom context extractor for messages without W3C links\n if (config.customContextExtractor && config.headersFrom) {\n for (const msg of messages) {\n const headers = extractHeaders(config.headersFrom, msg);\n if (headers) {\n // Only use custom extractor if W3C headers weren't present\n const w3cLink = createLinkFromHeaders(headers);\n if (!w3cLink) {\n const customContext = config.customContextExtractor(headers);\n if (customContext) {\n links.push({\n context: customContext,\n attributes: { 'messaging.link.source': 'custom_extractor' },\n });\n }\n }\n }\n }\n }\n\n // Set batch count\n ctx.setAttribute('messaging.batch.message_count', messages.length);\n } else {\n // Single message mode\n const msg = args[0];\n const headers = config.headersFrom\n ? extractHeaders(config.headersFrom, msg)\n : undefined;\n\n if (headers) {\n // Try W3C format first\n const w3cLink = createLinkFromHeaders(headers);\n if (w3cLink) {\n links.push(w3cLink);\n } else if (config.customContextExtractor) {\n // Fall back to custom extractor\n const customContext = config.customContextExtractor(headers);\n if (customContext) {\n links.push({\n context: customContext,\n attributes: { 'messaging.link.source': 'custom_extractor' },\n });\n }\n }\n }\n }\n\n // Add all extracted links and store for getProducerLinks() / DLQ auto-linking\n if (links.length > 0) {\n ctx.addLinks(links);\n linkStorage.links.push(...links);\n }\n}\n\n/**\n * Extract lag metrics and set as span attributes\n */\nasync function extractLagMetrics(\n ctx: ConsumerContext,\n lagConfig: LagMetricsConfig,\n args: unknown[],\n): Promise<void> {\n const msg = Array.isArray(args[0]) ? args[0][0] : args[0];\n\n // Current offset\n let currentOffset: number | undefined;\n if (lagConfig.getCurrentOffset && msg) {\n currentOffset = lagConfig.getCurrentOffset(msg);\n if (currentOffset !== undefined) {\n ctx.setAttribute('messaging.kafka.message.offset', currentOffset);\n }\n }\n\n // Partition\n if (lagConfig.getPartition && msg) {\n const partition = lagConfig.getPartition(msg);\n if (partition !== undefined) {\n ctx.setAttribute('messaging.kafka.partition', partition);\n }\n }\n\n // End offset (high watermark) and lag calculation\n if (lagConfig.getEndOffset) {\n try {\n const endOffset = await Promise.resolve(lagConfig.getEndOffset());\n if (endOffset !== undefined && currentOffset !== undefined) {\n const lag = endOffset - currentOffset;\n ctx.setAttribute('messaging.kafka.consumer_lag', lag);\n\n // Add lag event\n ctx.addEvent('consumer_lag_measured', {\n 'messaging.kafka.consumer_lag': lag,\n 'messaging.kafka.message.offset': currentOffset,\n 'messaging.kafka.high_watermark': endOffset,\n });\n }\n } catch {\n // Ignore lag calculation errors\n }\n }\n\n // Committed offset\n if (lagConfig.getCommittedOffset) {\n try {\n const committedOffset = await Promise.resolve(\n lagConfig.getCommittedOffset(),\n );\n if (committedOffset !== undefined) {\n ctx.setAttribute('messaging.kafka.committed_offset', committedOffset);\n }\n } catch {\n // Ignore committed offset errors\n }\n }\n\n // Batch-specific metrics\n if (Array.isArray(args[0]) && args[0].length > 0) {\n const messages = args[0] as unknown[];\n if (lagConfig.getCurrentOffset) {\n const firstOffset = lagConfig.getCurrentOffset(messages[0]);\n const lastMessage = messages.at(-1);\n const lastOffset =\n lastMessage === undefined\n ? undefined\n : lagConfig.getCurrentOffset(lastMessage);\n\n if (firstOffset !== undefined) {\n ctx.setAttribute('messaging.batch.first_offset', firstOffset);\n }\n if (lastOffset !== undefined) {\n ctx.setAttribute('messaging.batch.last_offset', lastOffset);\n }\n }\n }\n}\n\n/**\n * Extract headers from message using config\n */\nfunction extractHeaders(\n headersFrom: string | ((msg: unknown) => Record<string, string> | undefined),\n msg: unknown,\n): Record<string, string> | undefined {\n if (typeof headersFrom === 'function') {\n return headersFrom(msg);\n }\n\n // String path - extract from message property\n if (typeof msg === 'object' && msg !== null) {\n const value = (msg as Record<string, unknown>)[headersFrom];\n if (typeof value === 'object' && value !== null) {\n return value as Record<string, string>;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract value from arguments using config\n */\nfunction extractValue(\n extractor: string | ((args: unknown[]) => unknown),\n args: unknown[],\n): unknown {\n if (typeof extractor === 'function') {\n return extractor(args);\n }\n\n // String path - extract from first argument\n const firstArg = args[0];\n if (typeof firstArg === 'object' && firstArg !== null) {\n return (firstArg as Record<string, unknown>)[extractor];\n }\n\n return undefined;\n}\n\n/**\n * Set custom attributes on context, handling non-primitive values\n */\nfunction setCustomAttributes(ctx: TraceContext, attributes: Attributes): void {\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== undefined && value !== null) {\n // setAttribute accepts primitives and arrays of primitives\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n ctx.setAttribute(key, value);\n } else if (Array.isArray(value)) {\n // Filter out null/undefined from arrays and ensure proper typing\n const cleanArray = value.filter(\n (v): v is string | number | boolean =>\n v !== null &&\n v !== undefined &&\n (typeof v === 'string' ||\n typeof v === 'number' ||\n typeof v === 'boolean'),\n );\n if (cleanArray.length > 0) {\n ctx.setAttribute(key, cleanArray as string[] | number[] | boolean[]);\n }\n } else {\n ctx.setAttribute(key, JSON.stringify(value));\n }\n }\n }\n}\n\n/**\n * Extract and process ordering information from message\n *\n * Handles:\n * - Sequence number extraction and tracking\n * - Out-of-order detection\n * - Duplicate detection\n * - Span attribute setting\n * - Callback invocation\n */\nfunction extractAndProcessOrdering(\n ctx: ConsumerContext,\n config: ConsumerConfig,\n args: unknown[],\n orderingState: OrderingState,\n): void {\n const ordering = config.ordering;\n if (!ordering) return;\n\n // Get messages to process - all messages in batch mode, single message otherwise\n const messages: unknown[] =\n config.batchMode && Array.isArray(args[0]) ? args[0] : [args[0]];\n\n if (messages.length === 0) return;\n\n // Track aggregate stats for batch reporting\n let outOfOrderCount = 0;\n let duplicateCount = 0;\n let lastSequence: number | null = null;\n let lastPartitionKey: string | null = null;\n let lastMessageId: string | null = null;\n\n for (const [i, msg] of messages.entries()) {\n if (!msg) continue;\n\n // Per-message state for this iteration\n let msgSequence: number | null = null;\n let msgPartitionKey: string | null = null;\n let msgId: string | null = null;\n\n // Extract sequence number\n if (ordering.sequenceFrom) {\n const seq = ordering.sequenceFrom(msg);\n if (seq !== undefined) {\n msgSequence = seq;\n lastSequence = seq;\n }\n }\n\n // Extract partition key\n if (ordering.partitionKeyFrom) {\n const key = ordering.partitionKeyFrom(msg);\n if (key !== undefined) {\n msgPartitionKey = key;\n lastPartitionKey = key;\n }\n }\n\n // Extract message ID for deduplication\n if (ordering.messageIdFrom) {\n const id = ordering.messageIdFrom(msg);\n if (id !== undefined) {\n msgId = id;\n lastMessageId = id;\n }\n }\n\n // Out-of-order detection for this message\n if (ordering.detectOutOfOrder && msgSequence !== null) {\n // Build tracker key using per-message partition key\n const msgOrderingState: OrderingState = {\n sequenceNumber: msgSequence,\n partitionKey: msgPartitionKey,\n messageId: msgId,\n isDuplicate: false,\n outOfOrderInfo: null,\n };\n const trackerKey = buildTrackerKey(config, msgOrderingState);\n const prevSequence = sequenceTrackers.get(trackerKey);\n\n if (prevSequence !== undefined) {\n const expectedSequence = prevSequence + 1;\n\n if (msgSequence !== expectedSequence) {\n outOfOrderCount++;\n const gap = msgSequence - expectedSequence;\n const outOfOrderInfo: OutOfOrderInfo = {\n currentSequence: msgSequence,\n expectedSequence,\n partitionKey: msgPartitionKey ?? undefined,\n gap,\n };\n\n // Store the first out-of-order info for backward compatibility\n if (!orderingState.outOfOrderInfo) {\n orderingState.outOfOrderInfo = outOfOrderInfo;\n }\n\n // Add event for each out-of-order message\n ctx.addEvent('message_out_of_order', {\n 'messaging.ordering.batch_index': i,\n 'messaging.ordering.current_sequence': msgSequence,\n 'messaging.ordering.expected_sequence': expectedSequence,\n 'messaging.ordering.gap': gap,\n ...(msgPartitionKey && {\n 'messaging.ordering.partition_key': msgPartitionKey,\n }),\n });\n\n // Call user callback if provided\n if (ordering.onOutOfOrder) {\n ordering.onOutOfOrder(ctx, outOfOrderInfo);\n }\n }\n }\n\n // Update tracker with this message's sequence\n sequenceTrackers.set(trackerKey, msgSequence);\n }\n\n // Duplicate detection for this message\n if (ordering.detectDuplicates && msgId !== null) {\n const msgOrderingState: OrderingState = {\n sequenceNumber: msgSequence,\n partitionKey: msgPartitionKey,\n messageId: msgId,\n isDuplicate: false,\n outOfOrderInfo: null,\n };\n const dedupKey = buildDedupKey(config, msgOrderingState);\n\n if (deduplicationWindow.has(dedupKey)) {\n duplicateCount++;\n\n // Add event for each duplicate\n ctx.addEvent('message_duplicate', {\n 'messaging.ordering.batch_index': i,\n 'messaging.message.id': msgId,\n });\n\n // Call user callback if provided\n if (ordering.onDuplicate) {\n ordering.onDuplicate(ctx, msgId);\n }\n } else {\n // Add to deduplication window\n deduplicationWindow.set(dedupKey, Date.now());\n\n // Trim window if needed\n const windowSize =\n ordering.deduplicationWindowSize ?? DEFAULT_DEDUP_WINDOW_SIZE;\n trimDeduplicationWindow(windowSize);\n }\n }\n }\n\n // Update orderingState with final values from the batch\n orderingState.sequenceNumber = lastSequence;\n orderingState.partitionKey = lastPartitionKey;\n orderingState.messageId = lastMessageId;\n orderingState.isDuplicate = duplicateCount > 0;\n\n // Set aggregate span attributes\n if (lastSequence !== null) {\n ctx.setAttribute('messaging.message.sequence_number', lastSequence);\n }\n if (lastPartitionKey !== null) {\n ctx.setAttribute('messaging.message.partition_key', lastPartitionKey);\n }\n if (lastMessageId !== null) {\n ctx.setAttribute('messaging.message.id', lastMessageId);\n }\n\n // Report batch-level ordering statistics\n if (outOfOrderCount > 0) {\n ctx.setAttribute('messaging.ordering.out_of_order', true);\n ctx.setAttribute('messaging.ordering.out_of_order_count', outOfOrderCount);\n }\n if (duplicateCount > 0) {\n ctx.setAttribute('messaging.ordering.duplicate', true);\n ctx.setAttribute('messaging.ordering.duplicate_count', duplicateCount);\n }\n}\n\n/**\n * Build a unique key for sequence tracking based on system, destination, and partition\n */\nfunction buildTrackerKey(\n config: ConsumerConfig,\n orderingState: OrderingState,\n): string {\n const parts = [config.system, config.destination];\n if (orderingState.partitionKey) {\n parts.push(orderingState.partitionKey);\n }\n if (config.consumerGroup) {\n parts.push(config.consumerGroup);\n }\n return parts.join(':');\n}\n\n/**\n * Build a unique key for deduplication based on system, destination, and message ID\n */\nfunction buildDedupKey(\n config: ConsumerConfig,\n orderingState: OrderingState,\n): string {\n const parts = [config.system, config.destination];\n if (orderingState.messageId) {\n parts.push(orderingState.messageId);\n }\n return parts.join(':');\n}\n\n/**\n * Clear sequence tracking state (useful for testing)\n */\nexport function clearOrderingState(): void {\n sequenceTrackers.clear();\n deduplicationWindow.clear();\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { trace } from './chunk-
|
|
1
|
+
import { trace } from './chunk-4PTCDOZY.js';
|
|
2
2
|
import { getActiveSpan } from './chunk-B3ZHLLMP.js';
|
|
3
3
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
4
4
|
|
|
@@ -334,5 +334,5 @@ function isInWorkflow() {
|
|
|
334
334
|
}
|
|
335
335
|
|
|
336
336
|
export { getCurrentWorkflowContext, isInWorkflow, traceStep, traceWorkflow };
|
|
337
|
-
//# sourceMappingURL=chunk-
|
|
338
|
-
//# sourceMappingURL=chunk-
|
|
337
|
+
//# sourceMappingURL=chunk-RXFZKLRQ.js.map
|
|
338
|
+
//# sourceMappingURL=chunk-RXFZKLRQ.js.map
|