autotel-plugins 0.19.6 → 0.19.8
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/dist/bigquery.cjs +1 -0
- package/dist/bigquery.cjs.map +1 -1
- package/dist/bigquery.js +1 -0
- package/dist/bigquery.js.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/common/constants.ts","../src/bigquery/index.ts","../src/kafka/headers.ts","../src/kafka/correlation.ts","../src/kafka/processing-span.ts","../src/kafka/producer-span.ts","../src/kafka/batch-lineage.ts","../src/kafka/batch-consumer.ts","../src/kafka/stream-processor.ts","../src/kafka/consumer-metrics.ts","../src/kafka/stream-events.ts","../src/rabbitmq/headers.ts","../src/rabbitmq/correlation.ts","../src/rabbitmq/processing-span.ts","../src/rabbitmq/publish-span.ts","../src/rabbitmq/batch-lineage.ts","../src/rabbitmq/ack-tracking.ts"],"names":["trace","propagation","DEFAULT_TRACER_NAME","SpanKind","context","SpanStatusCode","isValidSpanContext","otelMetrics","normalizeHeaders","caseInsensitiveGetter","extractTraceContext","ROOT_CONTEXT","headerSetter","deriveCorrelationId","extractCorrelationId","injectTraceHeaders","resolveContextAndLinks","setMessagingAttributes","DEFAULT_MAX_LINKS","hashTraceIdsSync","extractBatchLineage"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * OpenTelemetry semantic conventions for database operations.\n * These constants are shared across all plugins.\n */\n\n// Common database attributes\nexport const SEMATTRS_DB_SYSTEM = 'db.system' as const;\nexport const SEMATTRS_DB_SYSTEM_NAME = 'db.system.name' as const;\nexport const SEMATTRS_DB_OPERATION = 'db.operation' as const;\nexport const SEMATTRS_DB_STATEMENT = 'db.statement' as const;\nexport const SEMATTRS_DB_NAME = 'db.name' as const;\nexport const SEMATTRS_DB_NAMESPACE = 'db.namespace' as const;\nexport const SEMATTRS_DB_COLLECTION_NAME = 'db.collection.name' as const;\nexport const SEMATTRS_DB_OPERATION_NAME = 'db.operation.name' as const;\nexport const SEMATTRS_DB_QUERY_TEXT = 'db.query.text' as const;\nexport const SEMATTRS_DB_QUERY_SUMMARY = 'db.query.summary' as const;\n\n// MongoDB-specific attributes\nexport const SEMATTRS_DB_MONGODB_COLLECTION = 'db.mongodb.collection' as const;\n\n// Network attributes\nexport const SEMATTRS_NET_PEER_NAME = 'net.peer.name' as const;\nexport const SEMATTRS_NET_PEER_PORT = 'net.peer.port' as const;\n\n// Messaging attributes (Kafka, etc.)\nexport const SEMATTRS_MESSAGING_SYSTEM = 'messaging.system' as const;\nexport const SEMATTRS_MESSAGING_DESTINATION_NAME =\n 'messaging.destination.name' as const;\nexport const SEMATTRS_MESSAGING_OPERATION = 'messaging.operation' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP =\n 'messaging.kafka.consumer.group' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_PARTITION =\n 'messaging.kafka.partition' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_OFFSET =\n 'messaging.kafka.offset' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY =\n 'messaging.kafka.message.key' as const;\n\n// Batch lineage attributes\nexport const SEMATTRS_LINKED_TRACE_ID_COUNT = 'linked_trace_id_count' as const;\nexport const SEMATTRS_LINKED_TRACE_ID_HASH = 'linked_trace_id_hash' as const;\n\n// Correlation ID header name\nexport const CORRELATION_ID_HEADER = 'x-correlation-id' as const;\n\n// BigQuery-specific attributes (namespaced under gcp.bigquery per OTel spec)\nexport const SEMATTRS_GCP_BIGQUERY_JOB_ID = 'gcp.bigquery.job.id' as const;\nexport const SEMATTRS_GCP_BIGQUERY_JOB_LOCATION =\n 'gcp.bigquery.job.location' as const;\nexport const SEMATTRS_GCP_BIGQUERY_PROJECT_ID =\n 'gcp.bigquery.project.id' as const;\nexport const SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE =\n 'gcp.bigquery.destination.table' as const;\nexport const SEMATTRS_GCP_BIGQUERY_SOURCE_TABLES =\n 'gcp.bigquery.source.tables' as const;\nexport const SEMATTRS_GCP_BIGQUERY_STATEMENT_TYPE =\n 'gcp.bigquery.statement_type' as const;\nexport const SEMATTRS_GCP_BIGQUERY_QUERY_HASH =\n 'gcp.bigquery.query.hash' as const;\nexport const SEMATTRS_GCP_BIGQUERY_ROWS_AFFECTED =\n 'gcp.bigquery.rows.affected' as const;\nexport const SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED =\n 'gcp.bigquery.rows.returned' as const;\nexport const SEMATTRS_GCP_BIGQUERY_SCHEMA_FIELDS =\n 'gcp.bigquery.schema.fields' as const;\n\n// RabbitMQ-specific attributes (aligned with OTel messaging semantic conventions)\nexport const SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY =\n 'messaging.rabbitmq.destination.routing_key' as const;\nexport const SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_EXCHANGE =\n 'messaging.rabbitmq.destination.exchange' as const;\nexport const SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT =\n 'messaging.rabbitmq.ack_result' as const;\nexport const SEMATTRS_MESSAGING_RABBITMQ_REQUEUE =\n 'messaging.rabbitmq.requeue' as const;\n\n// Messaging attributes (shared across messaging systems)\nexport const SEMATTRS_MESSAGING_MESSAGE_ID = 'messaging.message.id' as const;\nexport const SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID =\n 'messaging.message.conversation_id' as const;\nexport const SEMATTRS_MESSAGING_CONSUMER_ID = 'messaging.consumer.id' as const;\nexport const SEMATTRS_MESSAGING_OPERATION_NAME =\n 'messaging.operation.name' as const;\n\n// Kafka batch consumer attributes\nexport const SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT =\n 'messaging.batch.message_count' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET =\n 'messaging.kafka.batch.first_offset' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET =\n 'messaging.kafka.batch.last_offset' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED =\n 'messaging.kafka.batch.messages_processed' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED =\n 'messaging.kafka.batch.messages_failed' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS =\n 'messaging.kafka.batch.processing_time_ms' as const;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n// Note: `any` is only used for dynamic method wrapping on runtime objects.\n// Type-safe interfaces are used for all public APIs.\n// BigQuery is a devDependency so we type-check against the real API; consumers use the peer.\n\nimport type { BigQuery, BigQueryOptions } from '@google-cloud/bigquery';\nimport { SpanKind, otelTrace as trace, type Span, type Tracer } from 'autotel';\nimport {\n SEMATTRS_DB_SYSTEM_NAME,\n SEMATTRS_DB_OPERATION_NAME,\n SEMATTRS_DB_QUERY_TEXT,\n SEMATTRS_DB_QUERY_SUMMARY,\n SEMATTRS_DB_NAMESPACE,\n SEMATTRS_DB_COLLECTION_NAME,\n SEMATTRS_GCP_BIGQUERY_JOB_ID,\n SEMATTRS_GCP_BIGQUERY_JOB_LOCATION,\n SEMATTRS_GCP_BIGQUERY_PROJECT_ID,\n SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE,\n SEMATTRS_GCP_BIGQUERY_QUERY_HASH,\n SEMATTRS_GCP_BIGQUERY_ROWS_AFFECTED,\n SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED,\n} from '../common/constants';\nimport { runWithSpan, finalizeSpan } from 'autotel/trace-helpers';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/bigquery';\nconst DEFAULT_DB_SYSTEM_NAME = 'gcp.bigquery';\nconst INSTRUMENTED_FLAG = '__autotelBigQueryInstrumented' as const;\nconst PROTOTYPE_INSTRUMENTED_FLAG =\n '__autotelBigQueryPrototypeInstrumented' as const;\nconst CONFIG_STORAGE_KEY = '__autotelBigQueryConfig' as const;\nconst TRACER_STORAGE_KEY = '__autotelBigQueryTracer' as const;\n\n/**\n * Helper to get config from a BigQuery instance.\n * For Table/Dataset methods, traverses up to find the BigQuery parent.\n */\nfunction getInstanceConfig(\n instance: any,\n): BigQueryInstrumentationConfig | undefined {\n // Direct config on BigQuery instance\n if (instance?.[CONFIG_STORAGE_KEY]) {\n return instance[CONFIG_STORAGE_KEY];\n }\n // For Table: this.dataset.parent is the BigQuery instance\n if (instance?.dataset?.parent?.[CONFIG_STORAGE_KEY]) {\n return instance.dataset.parent[CONFIG_STORAGE_KEY];\n }\n // For Dataset: this.parent is the BigQuery instance\n if (instance?.parent?.[CONFIG_STORAGE_KEY]) {\n return instance.parent[CONFIG_STORAGE_KEY];\n }\n // For Job: this.parent is the BigQuery instance\n if (instance?.parent?.[CONFIG_STORAGE_KEY]) {\n return instance.parent[CONFIG_STORAGE_KEY];\n }\n return undefined;\n}\n\n/**\n * Helper to get tracer from a BigQuery instance.\n * For Table/Dataset methods, traverses up to find the BigQuery parent.\n */\nfunction getInstanceTracer(instance: any): Tracer | undefined {\n // Direct tracer on BigQuery instance\n if (instance?.[TRACER_STORAGE_KEY]) {\n return instance[TRACER_STORAGE_KEY];\n }\n // For Table: this.dataset.parent is the BigQuery instance\n if (instance?.dataset?.parent?.[TRACER_STORAGE_KEY]) {\n return instance.dataset.parent[TRACER_STORAGE_KEY];\n }\n // For Dataset: this.parent is the BigQuery instance\n if (instance?.parent?.[TRACER_STORAGE_KEY]) {\n return instance.parent[TRACER_STORAGE_KEY];\n }\n // For Job: this.parent is the BigQuery instance\n if (instance?.parent?.[TRACER_STORAGE_KEY]) {\n return instance.parent[TRACER_STORAGE_KEY];\n }\n return undefined;\n}\n\n/**\n * Plugin-only options for BigQuery instrumentation (not part of official BigQueryOptions).\n */\nexport interface BigQueryInstrumentationPluginOptions {\n /**\n * Custom tracer name (default: \"autotel-plugins/bigquery\").\n */\n tracerName?: string;\n\n /**\n * How to handle query text in spans:\n * - 'never': Don't capture any query text\n * - 'summary': Only capture low-cardinality summary (default)\n * - 'sanitized': Sanitize by replacing literals with ?\n * - 'raw': Capture raw query text (opt-in, not recommended for production)\n * @default 'summary'\n */\n captureQueryText?: 'never' | 'summary' | 'sanitized' | 'raw';\n\n /**\n * Maximum length for captured query text. Queries longer than this will be truncated.\n * @default 1000\n */\n maxQueryTextLength?: number;\n\n /**\n * Whether to include a hash of the query for exact matching without exposing text.\n * @default true\n */\n includeQueryHash?: boolean;\n\n /**\n * Whether to instrument admin operations (dataset/table create, delete, metadata).\n * @default false\n */\n instrumentAdminOps?: boolean;\n\n /**\n * Whether to instrument BigQuery ML (model) operations.\n * @default false\n */\n instrumentBqmlOps?: boolean;\n\n /**\n * Whether to instrument routine (stored procedure/function) operations.\n * @default false\n */\n instrumentRoutineOps?: boolean;\n}\n\n/**\n * Configuration options for BigQuery instrumentation.\n * Uses official BigQueryOptions for projectId and location (same semantics as the BigQuery constructor).\n * All other fields are plugin-only options.\n */\nexport type BigQueryInstrumentationConfig = Pick<\n BigQueryOptions,\n 'projectId' | 'location'\n> &\n BigQueryInstrumentationPluginOptions;\n\n/**\n * Creates a simple hash of a string for query identification without exposing text.\n */\nfunction hashQuery(query: string): string {\n let hash = 0;\n for (let i = 0; i < query.length; i++) {\n const char = query.codePointAt(i) ?? 0;\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * Extracts the operation type (SELECT, INSERT, etc.) from SQL query.\n */\nfunction extractOperationType(query: string): string | undefined {\n const trimmed = query.trimStart();\n const match = /^(?<op>\\w+)/iu.exec(trimmed);\n return match?.groups?.op?.toUpperCase();\n}\n\n/**\n * Creates a low-cardinality summary of a query.\n * Example: \"SELECT FROM users WHERE...\" or \"INSERT INTO orders\"\n */\nfunction createQuerySummary(query: string): string {\n const operation = extractOperationType(query);\n if (!operation) {\n return 'UNKNOWN';\n }\n\n // For SELECT/INSERT/UPDATE/DELETE, try to extract table name\n const patterns: Record<string, RegExp> = {\n SELECT: /FROM\\s+(?<table>[\\w.]+)/iu,\n INSERT: /INTO\\s+(?<table>[\\w.]+)/iu,\n UPDATE: /UPDATE\\s+(?<table>[\\w.]+)/iu,\n DELETE: /FROM\\s+(?<table>[\\w.]+)/iu,\n };\n\n const pattern = patterns[operation];\n if (pattern) {\n const match = pattern.exec(query);\n const table = match?.groups?.table;\n if (table) {\n return `${operation} ${table}`;\n }\n }\n\n return operation;\n}\n\n/**\n * Sanitizes a query by replacing literal values with ? placeholders.\n * Handles strings, numbers, and dates.\n */\nfunction sanitizeQuery(query: string): string {\n // Replace string literals: '...' or \"...\"\n let sanitized = query.replaceAll(/'(?:[^'\\\\]|\\\\.)*'/gu, \"'?'\");\n sanitized = sanitized.replaceAll(/\"(?:[^\"\\\\]|\\\\.)*\"/gu, '\"?\"');\n\n // Replace numeric literals (but preserve table names like table_123)\n // Only replace standalone numbers\n sanitized = sanitized.replaceAll(/\\b\\d+\\.?\\d*\\b/gu, '?');\n\n // Replace boolean literals\n sanitized = sanitized.replaceAll(/\\b(?:true|false)\\b/giu, '?');\n\n // Replace NULL\n sanitized = sanitized.replaceAll(/\\bNULL\\b/giu, '?');\n\n return sanitized;\n}\n\n/**\n * Truncates text to max length with ellipsis.\n */\nfunction truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\n/**\n * Extracts project ID from BigQuery instance.\n */\nfunction extractProjectId(bigquery: any): string | undefined {\n try {\n return bigquery.projectId || bigquery.options?.projectId;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Extracts location from BigQuery instance or query options.\n */\nfunction extractLocation(bigquery: any, options?: any): string | undefined {\n try {\n return options?.location || bigquery.location || bigquery.options?.location;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Extracts dataset and table identifiers from various BigQuery objects.\n */\nfunction extractTableReference(obj: any): {\n datasetId?: string;\n tableId?: string;\n projectId?: string;\n} {\n try {\n // Direct properties\n if (obj.dataset?.id || obj.parent?.id) {\n return {\n projectId: obj.dataset?.parent?.projectId || obj.parent?.projectId,\n datasetId: obj.dataset?.id || obj.parent?.datasetId,\n tableId: obj.id,\n };\n }\n\n // From metadata\n if (obj.metadata?.tableReference) {\n return obj.metadata.tableReference;\n }\n\n return {};\n } catch {\n return {};\n }\n}\n\n/**\n * Creates a span for a BigQuery operation.\n */\nfunction createSpan(\n tracer: Tracer,\n operationName: string,\n target?: string,\n projectId?: string,\n config: BigQueryInstrumentationConfig = {},\n): Span {\n const spanName = target ? `${operationName} ${target}` : operationName;\n\n const attributes: Record<string, any> = {\n [SEMATTRS_DB_SYSTEM_NAME]: DEFAULT_DB_SYSTEM_NAME,\n [SEMATTRS_DB_OPERATION_NAME]: operationName,\n };\n\n if (projectId || config.projectId) {\n attributes[SEMATTRS_GCP_BIGQUERY_PROJECT_ID] =\n projectId || config.projectId;\n }\n\n if (config.location) {\n attributes[SEMATTRS_GCP_BIGQUERY_JOB_LOCATION] = config.location;\n }\n\n return tracer.startSpan(spanName, { kind: SpanKind.CLIENT, attributes });\n}\n\n/**\n * Instruments BigQuery.query() method.\n */\nfunction instrumentQueryMethod(BigQuery: any): void {\n const originalQuery = BigQuery.prototype.query;\n if (typeof originalQuery !== 'function') {\n return;\n }\n\n BigQuery.prototype.query = function instrumentedQuery(\n this: any,\n query: string | { query: string; [key: string]: any },\n options?: any,\n callback?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n // Fall back to original if no config/tracer found\n return originalQuery.call(this, query, options, callback);\n }\n\n const queryText = typeof query === 'string' ? query : query.query;\n const projectId = extractProjectId(this);\n const location = extractLocation(this, options);\n\n const operation = queryText ? extractOperationType(queryText) : 'QUERY';\n const summary = queryText ? createQuerySummary(queryText) : 'QUERY';\n\n const span = createSpan(\n tracer,\n operation || 'QUERY',\n summary,\n projectId,\n config,\n );\n\n // Set location if available\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n // Set query summary (always)\n span.setAttribute(SEMATTRS_DB_QUERY_SUMMARY, summary);\n\n // Set query text based on config\n if (config.captureQueryText !== 'never' && queryText) {\n if (config.captureQueryText === 'raw') {\n const truncated = truncateText(\n queryText,\n config.maxQueryTextLength || 1000,\n );\n span.setAttribute(SEMATTRS_DB_QUERY_TEXT, truncated);\n } else if (config.captureQueryText === 'sanitized') {\n const sanitized = sanitizeQuery(queryText);\n const truncated = truncateText(\n sanitized,\n config.maxQueryTextLength || 1000,\n );\n span.setAttribute(SEMATTRS_DB_QUERY_TEXT, truncated);\n }\n // 'summary' mode only includes summary, no raw text\n }\n\n // Set query hash if enabled\n if (config.includeQueryHash !== false && queryText) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_QUERY_HASH, hashQuery(queryText));\n }\n\n // Set destination table if specified in options\n if (options?.destination) {\n const dest = extractTableReference(options.destination);\n if (dest.tableId) {\n const destTable = dest.datasetId\n ? `${dest.datasetId}.${dest.tableId}`\n : dest.tableId;\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE, destTable);\n }\n }\n\n // Handle callback-style API\n if (typeof callback === 'function') {\n const wrappedCallback = (err: any, ...args: any[]) => {\n if (err) {\n finalizeSpan(\n span,\n err instanceof Error ? err : new Error(String(err)),\n );\n } else {\n // Record row count and job ID if available in response\n const [rows, response] = args;\n if (Array.isArray(rows)) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED, rows.length);\n }\n if (response?.jobReference?.jobId) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_JOB_ID,\n response.jobReference.jobId,\n );\n }\n finalizeSpan(span);\n }\n return callback(err, ...args);\n };\n return originalQuery.call(this, query, options, wrappedCallback);\n }\n\n // Handle Promise-style API\n return runWithSpan(span, () => {\n try {\n const result = originalQuery.call(this, query, options);\n\n return Promise.resolve(result)\n .then(([rows, response]: [any[], any]) => {\n // Record row count\n if (Array.isArray(rows)) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED,\n rows.length,\n );\n }\n\n // Extract job ID from response if available\n if (response?.jobReference?.jobId) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_JOB_ID,\n response.jobReference.jobId,\n );\n }\n\n finalizeSpan(span);\n return [rows, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments BigQuery.createQueryJob() method.\n */\nfunction instrumentCreateQueryJob(BigQuery: any): void {\n const originalCreateQueryJob = BigQuery.prototype.createQueryJob;\n if (typeof originalCreateQueryJob !== 'function') {\n return;\n }\n\n BigQuery.prototype.createQueryJob = function instrumentedCreateQueryJob(\n this: any,\n options: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalCreateQueryJob.call(this, options);\n }\n\n const queryText = typeof options === 'string' ? options : options.query;\n const projectId = extractProjectId(this);\n const location = extractLocation(this, options);\n\n const operation = queryText ? extractOperationType(queryText) : 'QUERY';\n const summary = queryText ? createQuerySummary(queryText) : 'QUERY';\n\n const span = createSpan(\n tracer,\n `${operation || 'QUERY'}_JOB`,\n summary,\n projectId,\n config,\n );\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n span.setAttribute(SEMATTRS_DB_QUERY_SUMMARY, summary);\n\n if (config.captureQueryText !== 'never' && queryText) {\n if (config.captureQueryText === 'raw') {\n const truncated = truncateText(\n queryText,\n config.maxQueryTextLength || 1000,\n );\n span.setAttribute(SEMATTRS_DB_QUERY_TEXT, truncated);\n } else if (config.captureQueryText === 'sanitized') {\n const sanitized = sanitizeQuery(queryText);\n const truncated = truncateText(\n sanitized,\n config.maxQueryTextLength || 1000,\n );\n span.setAttribute(SEMATTRS_DB_QUERY_TEXT, truncated);\n }\n }\n\n if (config.includeQueryHash !== false && queryText) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_QUERY_HASH, hashQuery(queryText));\n }\n\n if (options?.destination) {\n const dest = extractTableReference(options.destination);\n if (dest.tableId) {\n const destTable = dest.datasetId\n ? `${dest.datasetId}.${dest.tableId}`\n : dest.tableId;\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE, destTable);\n }\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreateQueryJob.call(this, options);\n\n return Promise.resolve(result)\n .then(([job, response]: [any, any]) => {\n // Record job ID\n if (job?.id) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, job.id);\n } else if (response?.jobReference?.jobId) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_JOB_ID,\n response.jobReference.jobId,\n );\n }\n\n finalizeSpan(span);\n return [job, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.insert() method.\n */\nfunction instrumentTableInsert(Table: any): void {\n const originalInsert = Table.prototype.insert;\n if (typeof originalInsert !== 'function') {\n return;\n }\n\n Table.prototype.insert = function instrumentedInsert(\n this: any,\n rows: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalInsert.call(this, rows, options);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n options,\n );\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'INSERT', target, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n // Record row count\n const rowCount = Array.isArray(rows) ? rows.length : 1;\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_ROWS_AFFECTED, rowCount);\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalInsert.call(this, rows, options);\n\n return Promise.resolve(result)\n .then((response: any) => {\n // Check for insert errors\n if (response?.insertErrors?.length > 0) {\n span.setAttribute(\n 'gcp.bigquery.insert.errors',\n response.insertErrors.length,\n );\n }\n\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.getRows() method.\n */\nfunction instrumentTableGetRows(Table: any): void {\n const originalGetRows = Table.prototype.getRows;\n if (typeof originalGetRows !== 'function') {\n return;\n }\n\n Table.prototype.getRows = function instrumentedGetRows(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalGetRows.call(this, options);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n options,\n );\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'SELECT', target, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalGetRows.call(this, options);\n\n return Promise.resolve(result)\n .then(([rows, nextQuery, apiResponse]: [any[], any, any]) => {\n if (Array.isArray(rows)) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED,\n rows.length,\n );\n }\n finalizeSpan(span);\n return [rows, nextQuery, apiResponse];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.createLoadJob() method.\n */\nfunction instrumentTableCreateLoadJob(Table: any): void {\n const originalCreateLoadJob = Table.prototype.createLoadJob;\n if (typeof originalCreateLoadJob !== 'function') {\n return;\n }\n\n Table.prototype.createLoadJob = function instrumentedCreateLoadJob(\n this: any,\n source: any,\n metadata?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalCreateLoadJob.call(this, source, metadata);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n metadata,\n );\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'LOAD', target, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n // Record source format if available\n if (metadata?.sourceFormat) {\n span.setAttribute('gcp.bigquery.source.format', metadata.sourceFormat);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreateLoadJob.call(this, source, metadata);\n\n return Promise.resolve(result)\n .then(([job, response]: [any, any]) => {\n if (job?.id) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, job.id);\n }\n finalizeSpan(span);\n return [job, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.createCopyJob() method.\n */\nfunction instrumentTableCreateCopyJob(Table: any): void {\n const originalCreateCopyJob = Table.prototype.createCopyJob;\n if (typeof originalCreateCopyJob !== 'function') {\n return;\n }\n\n Table.prototype.createCopyJob = function instrumentedCreateCopyJob(\n this: any,\n destination: any,\n metadata?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalCreateCopyJob.call(this, destination, metadata);\n }\n\n const sourceRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n metadata,\n );\n\n const source = sourceRef.tableId\n ? sourceRef.datasetId\n ? `${sourceRef.datasetId}.${sourceRef.tableId}`\n : sourceRef.tableId\n : 'unknown';\n\n const span = createSpan(tracer, 'COPY', source, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n // Record destination\n if (destination) {\n const destRef = extractTableReference(destination);\n const destTable = destRef.tableId\n ? destRef.datasetId\n ? `${destRef.datasetId}.${destRef.tableId}`\n : destRef.tableId\n : undefined;\n if (destTable) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE, destTable);\n }\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreateCopyJob.call(this, destination, metadata);\n\n return Promise.resolve(result)\n .then(([job, response]: [any, any]) => {\n if (job?.id) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, job.id);\n }\n finalizeSpan(span);\n return [job, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.createExtractJob() method.\n */\nfunction instrumentTableCreateExtractJob(Table: any): void {\n const originalCreateExtractJob = Table.prototype.createExtractJob;\n if (typeof originalCreateExtractJob !== 'function') {\n return;\n }\n\n Table.prototype.createExtractJob = function instrumentedCreateExtractJob(\n this: any,\n destination: any,\n metadata?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalCreateExtractJob.call(this, destination, metadata);\n }\n\n const sourceRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n metadata,\n );\n\n const source = sourceRef.tableId\n ? sourceRef.datasetId\n ? `${sourceRef.datasetId}.${sourceRef.tableId}`\n : sourceRef.tableId\n : 'unknown';\n\n const span = createSpan(tracer, 'EXTRACT', source, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (sourceRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, sourceRef.datasetId);\n }\n if (sourceRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, sourceRef.tableId);\n }\n\n // Record destination URI\n if (typeof destination === 'string') {\n span.setAttribute('gcp.bigquery.destination.uri', destination);\n } else if (Array.isArray(destination) && destination.length > 0) {\n span.setAttribute('gcp.bigquery.destination.uri', destination[0]);\n }\n\n // Record format\n const format = metadata?.destinationFormat || metadata?.format;\n if (format) {\n span.setAttribute('gcp.bigquery.destination.format', format);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreateExtractJob.call(\n this,\n destination,\n metadata,\n );\n\n return Promise.resolve(result)\n .then(([job, response]: [any, any]) => {\n if (job?.id) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, job.id);\n }\n finalizeSpan(span);\n return [job, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Job.getQueryResults() method.\n */\nfunction instrumentJobGetQueryResults(Job: any): void {\n const originalGetQueryResults = Job.prototype.getQueryResults;\n if (typeof originalGetQueryResults !== 'function') {\n return;\n }\n\n Job.prototype.getQueryResults = function instrumentedGetQueryResults(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalGetQueryResults.call(this, options);\n }\n\n const jobId = this.id || this.metadata?.jobReference?.jobId;\n const projectId = this.parent?.projectId || this.projectId;\n const location = this.location || options?.location;\n\n const span = createSpan(\n tracer,\n 'GET_QUERY_RESULTS',\n undefined,\n projectId,\n config,\n );\n\n if (jobId) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, jobId);\n }\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalGetQueryResults.call(this, options);\n\n return Promise.resolve(result)\n .then(([rows, nextQuery, apiResponse]: [any[], any, any]) => {\n if (Array.isArray(rows)) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED,\n rows.length,\n );\n }\n finalizeSpan(span);\n return [rows, nextQuery, apiResponse];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Dataset.create() method (admin operation).\n */\nfunction instrumentDatasetCreate(Dataset: any): void {\n const originalCreate = Dataset.prototype.create;\n if (typeof originalCreate !== 'function') {\n return;\n }\n\n Dataset.prototype.create = function instrumentedCreate(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalCreate.call(this, options);\n }\n\n const datasetId = this.id;\n const projectId = extractProjectId(this.parent);\n const location = extractLocation(this.parent, options);\n\n const span = createSpan(\n tracer,\n 'CREATE_DATASET',\n datasetId,\n projectId,\n config,\n );\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, datasetId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreate.call(this, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Dataset.delete() method (admin operation).\n */\nfunction instrumentDatasetDelete(Dataset: any): void {\n const originalDelete = Dataset.prototype.delete;\n if (typeof originalDelete !== 'function') {\n return;\n }\n\n Dataset.prototype.delete = function instrumentedDelete(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalDelete.call(this, options);\n }\n\n const datasetId = this.id;\n const projectId = extractProjectId(this.parent);\n\n const span = createSpan(\n tracer,\n 'DELETE_DATASET',\n datasetId,\n projectId,\n config,\n );\n\n if (datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, datasetId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalDelete.call(this, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments BigQuery.createDataset() method (admin operation).\n * This is different from Dataset.prototype.create - it's called as bigquery.createDataset(id).\n */\nfunction instrumentBigQueryCreateDataset(BigQuery: any): void {\n const originalCreateDataset = BigQuery.prototype.createDataset;\n if (typeof originalCreateDataset !== 'function') {\n return;\n }\n\n BigQuery.prototype.createDataset = function instrumentedCreateDataset(\n this: any,\n id: string,\n options?: any,\n callback?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalCreateDataset.call(this, id, options, callback);\n }\n\n const datasetId = id;\n const projectId = extractProjectId(this);\n const location = extractLocation(this, options);\n\n const span = createSpan(\n tracer,\n 'CREATE_DATASET',\n datasetId,\n projectId,\n config,\n );\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, datasetId);\n }\n\n // Handle callback-style API\n if (typeof callback === 'function') {\n const wrappedCallback = (err: any, ...args: any[]) => {\n if (err) {\n finalizeSpan(\n span,\n err instanceof Error ? err : new Error(String(err)),\n );\n } else {\n finalizeSpan(span);\n }\n return callback(err, ...args);\n };\n // Call original without runWithSpan for callbacks - the span is already active\n return originalCreateDataset.call(this, id, options, wrappedCallback);\n }\n\n // Handle Promise-style API\n return runWithSpan(span, () => {\n try {\n const result = originalCreateDataset.call(this, id, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.create() method (admin operation).\n */\nfunction instrumentTableCreate(Table: any): void {\n const originalCreate = Table.prototype.create;\n if (typeof originalCreate !== 'function') {\n return;\n }\n\n Table.prototype.create = function instrumentedCreate(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalCreate.call(this, options);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'CREATE_TABLE', target, projectId, config);\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreate.call(this, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.delete() method (admin operation).\n */\nfunction instrumentTableDelete(Table: any): void {\n const originalDelete = Table.prototype.delete;\n if (typeof originalDelete !== 'function') {\n return;\n }\n\n Table.prototype.delete = function instrumentedDelete(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalDelete.call(this, options);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'DELETE_TABLE', target, projectId, config);\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalDelete.call(this, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments BigQuery with OpenTelemetry tracing.\n *\n * This function patches BigQuery, Dataset, Table, and Job methods to create spans\n * for all database operations. The instrumentation is idempotent - calling it multiple\n * times will only instrument once.\n *\n * @example\n * ```typescript\n * import { BigQuery } from '@google-cloud/bigquery';\n * import { init } from 'autotel';\n * import { instrumentBigQuery } from 'autotel-plugins/bigquery';\n *\n * init({ service: 'my-app' });\n *\n * const bigquery = new BigQuery({ projectId: 'my-project' });\n * instrumentBigQuery(bigquery);\n *\n * // All operations are automatically traced\n * const [rows] = await bigquery.query('SELECT * FROM my_dataset.users');\n * ```\n *\n * @example\n * ```typescript\n * // With configuration\n * instrumentBigQuery(bigquery, {\n * captureQueryText: 'sanitized',\n * includeQueryHash: true,\n * instrumentAdminOps: true,\n * });\n * ```\n */\nexport function instrumentBigQuery(\n bigquery: BigQuery,\n config?: BigQueryInstrumentationConfig,\n): BigQuery {\n if (!bigquery) {\n return bigquery;\n }\n\n // Use any for internal storage and prototype patching; public API remains BigQuery-typed\n const bq = bigquery as any;\n\n // Check if already instrumented\n if (bq[INSTRUMENTED_FLAG]) {\n return bigquery;\n }\n\n const finalConfig: Required<BigQueryInstrumentationConfig> = {\n projectId: config?.projectId || '',\n location: config?.location || '',\n tracerName: config?.tracerName || DEFAULT_TRACER_NAME,\n captureQueryText: config?.captureQueryText || 'summary',\n maxQueryTextLength: config?.maxQueryTextLength || 1000,\n includeQueryHash: config?.includeQueryHash ?? true,\n instrumentAdminOps: config?.instrumentAdminOps ?? false,\n instrumentBqmlOps: config?.instrumentBqmlOps ?? false,\n instrumentRoutineOps: config?.instrumentRoutineOps ?? false,\n };\n\n const tracer = trace.getTracer(finalConfig.tracerName);\n\n // Store config and tracer on this instance for per-instance customization\n bq[CONFIG_STORAGE_KEY] = finalConfig;\n bq[TRACER_STORAGE_KEY] = tracer;\n\n // Get the BigQuery class constructor\n const BigQuery = bq.constructor;\n\n // Only patch prototypes once globally (prevent double-wrapping)\n if (!BigQuery[PROTOTYPE_INSTRUMENTED_FLAG]) {\n // Instrument core query methods\n instrumentQueryMethod(BigQuery);\n instrumentCreateQueryJob(BigQuery);\n instrumentBigQueryCreateDataset(BigQuery);\n\n // Instrument Dataset operations (always patch, check config at runtime)\n if (bq.dataset) {\n try {\n // Get Dataset class from a temporary instance\n const tempDataset = bq.dataset('__temp__');\n const Dataset = tempDataset.constructor;\n\n instrumentDatasetCreate(Dataset);\n instrumentDatasetDelete(Dataset);\n\n // Clean up temporary reference\n tempDataset.dataset = null;\n } catch {\n // Ignore errors in getting Dataset class\n }\n }\n\n // Instrument Table operations\n if (bq.dataset) {\n try {\n const tempDataset = bq.dataset('__temp__');\n const tempTable = tempDataset.table('__temp__');\n const Table = tempTable.constructor;\n\n // Core data operations (always instrumented)\n instrumentTableInsert(Table);\n instrumentTableGetRows(Table);\n instrumentTableCreateLoadJob(Table);\n instrumentTableCreateCopyJob(Table);\n instrumentTableCreateExtractJob(Table);\n\n // Admin operations (always patch, check config at runtime)\n instrumentTableCreate(Table);\n instrumentTableDelete(Table);\n\n // Clean up temporary references\n tempTable.table = null;\n tempDataset.dataset = null;\n } catch {\n // Ignore errors in getting Table class\n }\n }\n\n // Instrument Job operations\n if (bq.job) {\n try {\n const tempJob = bq.job('__temp__');\n const Job = tempJob.constructor;\n\n instrumentJobGetQueryResults(Job);\n\n // Clean up temporary reference\n tempJob.job = null;\n } catch {\n // Ignore errors in getting Job class\n }\n }\n\n // Mark prototypes as instrumented globally\n BigQuery[PROTOTYPE_INSTRUMENTED_FLAG] = true;\n }\n\n // Mark this instance as instrumented\n bq[INSTRUMENTED_FLAG] = true;\n\n return bigquery;\n}\n\n/**\n * Legacy export for backwards compatibility.\n * @deprecated Use `instrumentBigQuery` instead.\n */\nexport class BigQueryInstrumentation {\n constructor(private config?: BigQueryInstrumentationConfig) {}\n\n enable(bigquery: BigQuery): void {\n instrumentBigQuery(bigquery, this.config);\n }\n}\n","/**\n * Header utilities for Kafka message processing.\n *\n * Uses OpenTelemetry propagators internally for context extraction,\n * ensuring compatibility with W3C Trace Context, B3, and other formats.\n */\n\nimport { propagation, ROOT_CONTEXT, type Context } from 'autotel';\nimport type { RawKafkaHeaders } from './types';\n\n/**\n * Normalize Kafka headers from raw format to string record.\n *\n * Handles:\n * - undefined/null headers -> empty object\n * - Map headers (e.g., from @platformatic/kafka) -> converts to object\n * - Buffer values -> UTF-8 strings\n * - undefined values -> removed from output\n * - string values -> passed through\n *\n * @param headers - Raw Kafka headers (Record, Map, or undefined)\n * @returns Normalized headers as string record\n *\n * @example\n * ```typescript\n * const raw = {\n * traceparent: Buffer.from('00-abc...'),\n * 'content-type': 'application/json',\n * optionalHeader: undefined,\n * };\n * const normalized = normalizeHeaders(raw);\n * // { traceparent: '00-abc...', 'content-type': 'application/json' }\n * ```\n *\n * @example With Map (e.g., @platformatic/kafka)\n * ```typescript\n * const map = new Map([\n * ['traceparent', '00-abc...'],\n * ['content-type', 'application/json'],\n * ]);\n * const normalized = normalizeHeaders(map);\n * // { traceparent: '00-abc...', 'content-type': 'application/json' }\n * ```\n */\nexport function normalizeHeaders(\n headers?: RawKafkaHeaders,\n): Record<string, string> {\n if (!headers) {\n return {};\n }\n\n // Convert Map to Record if needed\n const record: Record<string, string | Buffer | undefined> =\n headers instanceof Map ? Object.fromEntries(headers) : headers;\n\n const normalized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined) {\n continue;\n }\n\n normalized[key] = Buffer.isBuffer(value) ? value.toString('utf8') : value;\n }\n\n return normalized;\n}\n\n/**\n * TextMapGetter for case-insensitive header lookup.\n *\n * Kafka headers are case-sensitive, but trace context headers\n * (traceparent, tracestate) should be matched case-insensitively\n * for maximum compatibility.\n */\nconst caseInsensitiveGetter = {\n get(carrier: Record<string, string>, key: string): string | undefined {\n const lowerKey = key.toLowerCase();\n for (const [k, v] of Object.entries(carrier)) {\n if (k.toLowerCase() === lowerKey) {\n return v;\n }\n }\n return undefined;\n },\n keys(carrier: Record<string, string>): string[] {\n return Object.keys(carrier);\n },\n};\n\n/**\n * Extract trace context from normalized headers using OTel propagators.\n *\n * This is a pure function that does not activate any context.\n * The returned Context can be used to:\n * - Start spans as children of the extracted context\n * - Create links to the extracted context\n *\n * Returns ROOT_CONTEXT if no trace context is found in headers.\n *\n * @param headers - Normalized headers (use normalizeHeaders first)\n * @returns OpenTelemetry Context with extracted trace context\n *\n * @example\n * ```typescript\n * import { normalizeHeaders, extractTraceContext } from 'autotel-plugins/kafka';\n * import { trace } from '@opentelemetry/api';\n *\n * const headers = normalizeHeaders(message.headers);\n * const extractedCtx = extractTraceContext(headers);\n *\n * // Get span context from extracted context\n * const spanContext = trace.getSpanContext(extractedCtx);\n * if (spanContext && trace.isSpanContextValid(spanContext)) {\n * // Valid remote context extracted\n * }\n * ```\n */\nexport function extractTraceContext(headers: Record<string, string>): Context {\n return propagation.extract(ROOT_CONTEXT, headers, caseInsensitiveGetter);\n}\n","/**\n * Correlation ID utilities for Kafka message tracing.\n *\n * Provides consistent correlation ID handling across producers and consumers:\n * - Inject trace headers and correlation ID into outgoing messages\n * - Extract correlation ID from incoming messages\n * - Derive correlation ID from current trace context\n */\n\nimport {\n propagation,\n context,\n otelTrace as trace,\n type TextMapSetter,\n} from 'autotel';\nimport type { InjectOptions } from './types';\nimport { CORRELATION_ID_HEADER } from '../common/constants';\n\n/**\n * TextMapSetter for injecting headers.\n */\nconst headerSetter: TextMapSetter<Record<string, string>> = {\n set(carrier: Record<string, string>, key: string, value: string): void {\n carrier[key] = value;\n },\n};\n\n/**\n * Derive correlation ID from current trace context.\n *\n * Priority:\n * 1. Baggage 'correlation-id' if present\n * 2. First 16 characters of trace ID (64-bit for compatibility)\n * 3. Empty string if no active trace\n *\n * @returns Correlation ID derived from context\n *\n * @example\n * ```typescript\n * import { deriveCorrelationId } from 'autotel-plugins/kafka';\n *\n * // Inside a traced operation\n * const correlationId = deriveCorrelationId();\n * // '4bf92f3577b34da6' (first 16 chars of trace ID)\n * ```\n */\nexport function deriveCorrelationId(): string {\n // Check baggage first\n const activeBaggage = propagation.getActiveBaggage();\n const baggageCorrelationId = activeBaggage?.getEntry('correlation-id');\n if (baggageCorrelationId?.value) {\n return baggageCorrelationId.value;\n }\n\n // Fall back to trace ID (first 16 chars)\n const activeSpan = trace.getActiveSpan();\n if (activeSpan) {\n const spanContext = activeSpan.spanContext();\n // Return first 16 chars (64-bit) for compatibility with systems\n // that don't support full 128-bit trace IDs\n return spanContext.traceId.slice(0, 16);\n }\n\n return '';\n}\n\n/**\n * Extract correlation ID from message headers.\n *\n * Looks for the x-correlation-id header (case-insensitive).\n *\n * @param headers - Normalized headers (string values)\n * @returns Correlation ID if found, undefined otherwise\n *\n * @example\n * ```typescript\n * import { extractCorrelationId, normalizeHeaders } from 'autotel-plugins/kafka';\n *\n * const headers = normalizeHeaders(message.headers);\n * const correlationId = extractCorrelationId(headers);\n * if (correlationId) {\n * logger.info({ correlationId }, 'Processing message');\n * }\n * ```\n */\nexport function extractCorrelationId(\n headers: Record<string, string>,\n): string | undefined {\n // Case-insensitive lookup\n const lowerKey = CORRELATION_ID_HEADER.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === lowerKey) {\n return value;\n }\n }\n return undefined;\n}\n\n/**\n * Inject trace headers into outgoing message headers.\n *\n * Uses OpenTelemetry propagators to inject W3C Trace Context (traceparent, tracestate)\n * and optionally adds x-correlation-id header (default: true).\n *\n * Note: Baggage is injected automatically when W3CBaggagePropagator is registered.\n *\n * @param base - Base headers to merge with injected headers\n * @param options - Injection options\n * @returns Headers with trace context injected\n *\n * @example\n * ```typescript\n * import { injectTraceHeaders } from 'autotel-plugins/kafka';\n *\n * // Producer: inject headers with correlation ID\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * await producer.send({\n * topic: 'orders',\n * messages: [{ value: JSON.stringify(order), headers }],\n * });\n * ```\n *\n * @example With explicit correlation ID\n * ```typescript\n * const headers = injectTraceHeaders({}, {\n * correlationId: 'order-12345',\n * includeCorrelationIdHeader: true,\n * });\n * ```\n */\nexport function injectTraceHeaders(\n base: Record<string, string> = {},\n options: InjectOptions = {},\n): Record<string, string> {\n const { correlationId, includeCorrelationIdHeader = true } = options;\n\n const carrier = { ...base };\n\n // Inject trace context (traceparent, tracestate)\n // Note: If W3CBaggagePropagator is registered, baggage is also injected automatically\n propagation.inject(context.active(), carrier, headerSetter);\n\n // Add correlation ID if requested\n if (includeCorrelationIdHeader) {\n const corrId = correlationId ?? deriveCorrelationId();\n if (corrId) {\n carrier[CORRELATION_ID_HEADER] = corrId;\n }\n }\n\n return carrier;\n}\n","/**\n * Processing span wrapper for Kafka message handling.\n *\n * Creates processing spans with proper context handling, supporting:\n * - Context mode control (inherit/link/none)\n * - Messaging attributes for consistent querying\n * - Integration with official KafkaJS instrumentation\n */\n\nimport {\n otelTrace as trace,\n context,\n SpanKind,\n SpanStatusCode,\n type Span,\n type SpanContext,\n type SpanLink,\n} from 'autotel';\nimport type {\n ProcessingDescriptor,\n ContextMode,\n ProcessingSpanCallback,\n} from './types';\nimport { normalizeHeaders, extractTraceContext } from './headers';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP,\n SEMATTRS_MESSAGING_KAFKA_PARTITION,\n SEMATTRS_MESSAGING_KAFKA_OFFSET,\n SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY,\n} from '../common/constants';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * Check if a span context is valid (has both traceId and spanId).\n */\nfunction isValidSpanContext(\n spanContext: SpanContext | undefined,\n): spanContext is SpanContext {\n return !!(\n spanContext &&\n spanContext.traceId &&\n spanContext.spanId &&\n trace.isSpanContextValid(spanContext)\n );\n}\n\n/**\n * Create a processing span for Kafka message handling.\n *\n * **Context Mode Behavior:**\n *\n * | Mode | Active Span Exists | No Active Span |\n * |------|-------------------|----------------|\n * | `inherit` | Parent = active span. Link to extracted if different trace. | Parent = extracted context |\n * | `link` | Parent = active span. Link to extracted context. | Parent = root. Link to extracted. |\n * | `none` | Parent = active span. No links. | Parent = root. No links. |\n *\n * **Feature Flag Pattern:**\n * Use `contextMode: 'none'` to disable trace propagation via environment variable:\n * ```typescript\n * contextMode: process.env.KAFKA_PROPAGATE_TRACE !== 'false' ? 'inherit' : 'none'\n * ```\n *\n * @param descriptor - Processing span configuration\n * @param fn - Async callback to execute within the span\n * @returns Promise resolving to callback result\n * @throws Error if span creation fails or callback throws\n *\n * @example Basic usage\n * ```typescript\n * import { withProcessingSpan } from 'autotel-plugins/kafka';\n *\n * await consumer.run({\n * eachMessage: async ({ topic, partition, message }) => {\n * try {\n * await withProcessingSpan({\n * name: 'order.process',\n * headers: message.headers,\n * contextMode: 'inherit',\n * topic,\n * consumerGroup: 'payments',\n * partition,\n * offset: message.offset,\n * }, async (span) => {\n * return await processOrder(message);\n * });\n * } catch (error) {\n * logger.error('Processing failed', { error });\n * }\n * },\n * });\n * ```\n *\n * @example With batch lineage links (using semantic attribute constants)\n * ```typescript\n * import { extractBatchLineage, withProcessingSpan, SEMATTRS_LINKED_TRACE_ID_COUNT, SEMATTRS_LINKED_TRACE_ID_HASH } from 'autotel-plugins/kafka';\n *\n * const lineage = extractBatchLineage(batch, { maxLinks: 50 });\n *\n * await withProcessingSpan({\n * name: 'settlement.batch',\n * headers: {},\n * contextMode: 'none',\n * links: lineage.links,\n * topic: 'settlements',\n * consumerGroup: 'batcher',\n * }, async (span) => {\n * span.setAttribute(SEMATTRS_LINKED_TRACE_ID_COUNT, lineage.linked_trace_id_count);\n * span.setAttribute(SEMATTRS_LINKED_TRACE_ID_HASH, lineage.linked_trace_id_hash);\n * await processSettlement(batch);\n * });\n * ```\n */\nexport async function withProcessingSpan<T>(\n descriptor: ProcessingDescriptor,\n fn: ProcessingSpanCallback<T>,\n): Promise<T> {\n const {\n name,\n headers,\n contextMode = 'inherit',\n links = [],\n topic,\n consumerGroup,\n partition,\n offset,\n key,\n } = descriptor;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n const normalizedHeaders = normalizeHeaders(headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const extractedSpanContext = trace.getSpanContext(extractedCtx);\n\n // Determine parent context and links based on context mode\n const { parentContext, spanLinks } = resolveContextAndLinks(\n contextMode,\n extractedSpanContext,\n links,\n );\n\n // Create span with computed parent and links\n const span = tracer.startSpan(\n name,\n {\n kind: SpanKind.CONSUMER,\n links: spanLinks,\n },\n parentContext,\n );\n\n // Set messaging attributes\n setMessagingAttributes(span, {\n topic,\n consumerGroup,\n partition,\n offset,\n key,\n });\n\n // Execute callback within span context\n const spanContext = trace.setSpan(context.active(), span);\n\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span);\n });\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n\n throw error;\n }\n}\n\n/**\n * Resolve parent context and links based on context mode.\n */\nfunction resolveContextAndLinks(\n contextMode: ContextMode,\n extractedSpanContext: SpanContext | undefined,\n additionalLinks: SpanLink[],\n): {\n parentContext: typeof context extends { active(): infer T } ? T : never;\n spanLinks: SpanLink[];\n} {\n const activeSpan = trace.getActiveSpan();\n const activeContext = context.active();\n const hasActiveSpan = activeSpan !== undefined;\n const hasValidExtracted = isValidSpanContext(extractedSpanContext);\n\n const spanLinks: SpanLink[] = [...additionalLinks];\n\n switch (contextMode) {\n case 'inherit': {\n if (hasActiveSpan) {\n // Parent = active span\n // Link to extracted if different trace\n if (hasValidExtracted) {\n const activeSpanContext = activeSpan.spanContext();\n if (activeSpanContext.traceId !== extractedSpanContext.traceId) {\n spanLinks.push({ context: extractedSpanContext });\n }\n }\n return { parentContext: activeContext, spanLinks };\n } else {\n // No active span: parent = extracted context\n if (hasValidExtracted) {\n const extractedParentCtx = trace.setSpanContext(\n activeContext,\n extractedSpanContext,\n );\n return { parentContext: extractedParentCtx, spanLinks };\n }\n // No extracted context either: root span\n return { parentContext: activeContext, spanLinks };\n }\n }\n\n case 'link': {\n // Always parent to current context (active span or root)\n // Always link to extracted if valid\n if (hasValidExtracted) {\n spanLinks.push({ context: extractedSpanContext });\n }\n return { parentContext: activeContext, spanLinks };\n }\n\n case 'none': {\n // Parent to current context, no links to extracted\n return { parentContext: activeContext, spanLinks };\n }\n\n default: {\n // TypeScript exhaustive check\n const exhaustive: never = contextMode;\n throw new Error(`Unknown context mode: ${exhaustive}`);\n }\n }\n}\n\n/**\n * Set standard messaging attributes on a span.\n */\nfunction setMessagingAttributes(\n span: Span,\n attrs: {\n topic?: string;\n consumerGroup?: string;\n partition?: number;\n offset?: string;\n key?: string;\n },\n): void {\n const { topic, consumerGroup, partition, offset, key } = attrs;\n\n if (topic) {\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);\n }\n\n if (consumerGroup) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP, consumerGroup);\n }\n\n if (partition !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_PARTITION, partition);\n }\n\n if (offset !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_OFFSET, offset);\n }\n\n if (key !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY, key);\n }\n}\n","/**\n * Producer span wrapper for Kafka message publishing.\n *\n * Creates PRODUCER spans with proper messaging semantics,\n * allowing trace context to be injected inside the span.\n *\n * @example Basic producer span\n * ```typescript\n * import { withProducerSpan, injectTraceHeaders } from 'autotel-plugins/kafka';\n *\n * await withProducerSpan({\n * name: 'order.publish',\n * topic: 'orders',\n * messageKey: 'order-123',\n * }, async (span) => {\n * // Inject headers inside the PRODUCER span context\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * await producer.send({\n * topic: 'orders',\n * messages: [{ key: 'order-123', value: JSON.stringify(order), headers }],\n * });\n * });\n * ```\n */\n\nimport { otelTrace as trace, context, SpanKind, SpanStatusCode } from 'autotel';\nimport type { ProducerDescriptor, ProducerSpanCallback } from './types';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY,\n SEMATTRS_MESSAGING_OPERATION,\n} from '../common/constants';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * Create a producer span for Kafka message publishing.\n *\n * This creates a PRODUCER span with proper messaging attributes.\n * The callback runs within the span's context, so you can call\n * `injectTraceHeaders()` inside it to get the correct trace context.\n *\n * @param descriptor - Producer span configuration\n * @param fn - Async callback to execute within the span\n * @returns Promise resolving to callback result\n * @throws Error if span creation fails or callback throws\n *\n * @example\n * ```typescript\n * await withProducerSpan({\n * name: 'payment.publish',\n * topic: 'payments',\n * messageKey: paymentId,\n * }, async (span) => {\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * await producer.send({ topic: 'payments', messages: [{ key: paymentId, value, headers }] });\n * });\n * ```\n */\nexport async function withProducerSpan<T>(\n descriptor: ProducerDescriptor,\n fn: ProducerSpanCallback<T>,\n): Promise<T> {\n const { name, topic, messageKey, system = 'kafka' } = descriptor;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n // Create PRODUCER span\n const span = tracer.startSpan(name, {\n kind: SpanKind.PRODUCER,\n });\n\n // Set messaging attributes\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, system);\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);\n span.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'publish');\n\n if (messageKey !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY, messageKey);\n }\n\n // Execute callback within span context\n const spanContext = trace.setSpan(context.active(), span);\n\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span);\n });\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n\n throw error;\n }\n}\n","/**\n * Batch lineage utilities for fan-in trace correlation.\n *\n * When processing batches of messages (e.g., settlement batches),\n * this utility extracts and correlates trace IDs from all messages\n * to create meaningful span links and aggregation metadata.\n */\n\nimport { otelTrace as trace, type SpanContext, type SpanLink } from 'autotel';\nimport type {\n BatchItem,\n BatchLineageOptions,\n BatchLineageResult,\n ExtractedContext,\n} from './types';\nimport { normalizeHeaders, extractTraceContext } from './headers';\n\nconst DEFAULT_MAX_LINKS = 128;\n\n/**\n * Check if a span context is valid for creating links.\n * Must have both traceId and spanId.\n */\nfunction isValidSpanContext(\n spanContext: SpanContext | undefined,\n): spanContext is SpanContext {\n return !!(\n spanContext &&\n spanContext.traceId &&\n spanContext.spanId &&\n trace.isSpanContextValid(spanContext)\n );\n}\n\n/**\n * Simple SHA-256 hash for batch lineage.\n *\n * Uses Web Crypto API (available in Node.js 15+ and all modern browsers).\n * Falls back to a simple hash if crypto is unavailable.\n */\nasync function hashTraceIds(traceIds: string[]): Promise<string> {\n const input = traceIds.join('|');\n\n try {\n // Use Web Crypto API (available in Node.js 15+)\n const encoder = new TextEncoder();\n const data = encoder.encode(input);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = new Uint8Array(hashBuffer);\n\n // Convert to hex and take first 16 chars (64 bits)\n return [...hashArray]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n .slice(0, 16);\n } catch {\n // Fallback: simple djb2-style hash\n let hash = 5381;\n for (let i = 0; i < input.length; i++) {\n // eslint-disable-next-line unicorn/prefer-code-point\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n // Convert to unsigned 32-bit, then hex, pad to 16 chars\n return (hash >>> 0).toString(16).padStart(16, '0');\n }\n}\n\n/**\n * Synchronous hash fallback for when async is not suitable.\n */\nfunction hashTraceIdsSync(traceIds: string[]): string {\n const input = traceIds.join('|');\n\n // Simple djb2-style hash\n let hash = 5381;\n for (let i = 0; i < input.length; i++) {\n // eslint-disable-next-line unicorn/prefer-code-point\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n\n // Convert to unsigned 32-bit, then hex, pad to 16 chars\n return (hash >>> 0).toString(16).padStart(16, '0');\n}\n\n/**\n * Extract batch lineage from a collection of messages.\n *\n * For each message with headers:\n * 1. Extract SpanContext using OTel propagators\n * 2. Filter to valid SpanContexts (must have traceId + spanId)\n * 3. Deduplicate by traceId\n * 4. Sort trace IDs alphabetically for deterministic hash\n * 5. Create hash of sorted trace IDs\n * 6. Create SpanLinks from valid contexts (capped at maxLinks)\n *\n * @param items - Array of items with optional headers\n * @param options - Extraction options\n * @returns Batch lineage result with links and metadata\n *\n * @example Basic batch lineage\n * ```typescript\n * import { extractBatchLineage, withProcessingSpan } from 'autotel-plugins/kafka';\n *\n * // In batch consumer\n * const lineage = extractBatchLineage(batch, { maxLinks: 50 });\n *\n * await withProcessingSpan({\n * name: 'settlement.batch',\n * headers: {},\n * contextMode: 'none',\n * links: lineage.links,\n * topic: 'settlements',\n * consumerGroup: 'batcher',\n * }, async (span) => {\n * span.setAttribute('linked_trace_id_count', lineage.linked_trace_id_count);\n * span.setAttribute('linked_trace_id_hash', lineage.linked_trace_id_hash);\n * await processSettlement(batch);\n * });\n * ```\n *\n * @example With trace IDs for debugging\n * ```typescript\n * const lineage = extractBatchLineage(batch, {\n * includeTraceIds: true, // Warning: may contain sensitive data\n * maxLinks: 100,\n * });\n *\n * console.log('Processing batch from traces:', lineage.trace_ids);\n * ```\n */\nexport function extractBatchLineage(\n items: BatchItem[],\n options: BatchLineageOptions = {},\n): BatchLineageResult {\n const { includeTraceIds = false, maxLinks = DEFAULT_MAX_LINKS } = options;\n\n // Extract valid span contexts from items\n const extractedContexts: ExtractedContext[] = [];\n const seenTraceIds = new Set<string>();\n\n for (const item of items) {\n const normalizedHeaders = normalizeHeaders(item.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const spanContext = trace.getSpanContext(extractedCtx);\n\n // Check valid span context and deduplicate by traceId\n if (\n isValidSpanContext(spanContext) &&\n !seenTraceIds.has(spanContext.traceId)\n ) {\n seenTraceIds.add(spanContext.traceId);\n extractedContexts.push({\n traceId: spanContext.traceId,\n spanContext,\n });\n }\n }\n\n // Sort by traceId for deterministic hash\n extractedContexts.sort((a, b) => a.traceId.localeCompare(b.traceId));\n\n const traceIds = extractedContexts.map((ec) => ec.traceId);\n\n // Create links (capped at maxLinks)\n const links: SpanLink[] = extractedContexts\n .slice(0, maxLinks)\n .map((ec) => ({ context: ec.spanContext }));\n\n // Compute hash\n const hash =\n traceIds.length > 0 ? hashTraceIdsSync(traceIds) : '0000000000000000';\n\n return {\n linked_trace_id_count: traceIds.length,\n linked_trace_id_hash: hash,\n links,\n ...(includeTraceIds && { trace_ids: traceIds }),\n };\n}\n\n/**\n * Async version of extractBatchLineage that uses crypto.subtle for hashing.\n *\n * Use this when you need cryptographically secure hashing and can await.\n *\n * @param items - Array of items with optional headers\n * @param options - Extraction options\n * @returns Promise resolving to batch lineage result\n *\n * @example\n * ```typescript\n * const lineage = await extractBatchLineageAsync(batch, { maxLinks: 50 });\n * ```\n */\nexport async function extractBatchLineageAsync(\n items: BatchItem[],\n options: BatchLineageOptions = {},\n): Promise<BatchLineageResult> {\n const { includeTraceIds = false, maxLinks = DEFAULT_MAX_LINKS } = options;\n\n // Extract valid span contexts from items\n const extractedContexts: ExtractedContext[] = [];\n const seenTraceIds = new Set<string>();\n\n for (const item of items) {\n const normalizedHeaders = normalizeHeaders(item.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const spanContext = trace.getSpanContext(extractedCtx);\n\n // Check valid span context and deduplicate by traceId\n if (\n isValidSpanContext(spanContext) &&\n !seenTraceIds.has(spanContext.traceId)\n ) {\n seenTraceIds.add(spanContext.traceId);\n extractedContexts.push({\n traceId: spanContext.traceId,\n spanContext,\n });\n }\n }\n\n // Sort by traceId for deterministic hash\n extractedContexts.sort((a, b) => a.traceId.localeCompare(b.traceId));\n\n const traceIds = extractedContexts.map((ec) => ec.traceId);\n\n // Create links (capped at maxLinks)\n const links: SpanLink[] = extractedContexts\n .slice(0, maxLinks)\n .map((ec) => ({ context: ec.spanContext }));\n\n // Compute hash using crypto.subtle\n const hash =\n traceIds.length > 0 ? await hashTraceIds(traceIds) : '0000000000000000';\n\n return {\n linked_trace_id_count: traceIds.length,\n linked_trace_id_hash: hash,\n links,\n ...(includeTraceIds && { trace_ids: traceIds }),\n };\n}\n","/**\n * Batch consumer wrapper for KafkaJS batch processing.\n *\n * Provides observability for eachBatch processing while preserving\n * the exact KafkaJS signature and passing through all functions.\n *\n * @example Basic batch consumer\n * ```typescript\n * import { withBatchConsumer } from 'autotel-plugins/kafka';\n *\n * await consumer.run({\n * eachBatch: withBatchConsumer({\n * name: 'orders.batch',\n * consumerGroup: 'processor',\n * }, async ({ batch, resolveOffset, heartbeat, commitOffsetsIfNecessary, isRunning, isStale, pause }) => {\n * for (const message of batch.messages) {\n * await processOrder(message);\n * resolveOffset(message.offset);\n * }\n * }),\n * });\n * ```\n */\n\nimport {\n otelTrace as trace,\n context,\n SpanKind,\n SpanStatusCode,\n type Span,\n} from 'autotel';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP,\n SEMATTRS_MESSAGING_KAFKA_PARTITION,\n SEMATTRS_MESSAGING_KAFKA_OFFSET,\n SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY,\n SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT,\n SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET,\n SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET,\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,\n SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,\n} from '../common/constants';\nimport { normalizeHeaders, extractTraceContext } from './headers';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * KafkaJS batch payload interface.\n * Matches the exact signature from KafkaJS.\n */\nexport interface EachBatchPayload {\n batch: {\n topic: string;\n partition: number;\n messages: Array<{\n offset: string;\n key?: Buffer | null;\n value: Buffer | null;\n headers?: Record<string, Buffer | string | undefined>;\n }>;\n firstOffset(): string | null;\n lastOffset(): string;\n highWatermark: string;\n };\n resolveOffset(offset: string): void;\n heartbeat(): Promise<void>;\n commitOffsetsIfNecessary(\n offsets?: Record<string, Record<number, string>>,\n ): Promise<void>;\n uncommittedOffsets(): Record<string, Record<number, string>>;\n isRunning(): boolean;\n isStale(): boolean;\n pause(): () => void;\n}\n\n/**\n * Batch consumer handler type.\n */\nexport type EachBatchHandler = (payload: EachBatchPayload) => Promise<void>;\n\n/**\n * Progress metrics during batch processing.\n */\nexport interface BatchProgressMetrics {\n /** Number of messages processed so far */\n processed: number;\n /** Number of messages that failed processing */\n failed: number;\n /** Number of messages skipped */\n skipped: number;\n /** Batch processing time in milliseconds */\n batchProcessingTimeMs: number;\n}\n\n/**\n * Per-message span mode.\n * - 'all': Create spans for every message. Message spans are parented to extracted trace context from message headers when valid (trace continuation); otherwise to the batch span. All per-message spans are ended when the batch completes, including messages never resolved via resolveOffset (no span leak).\n * - 'errors': Only create spans for messages that fail. When the handler throws, a per-message error span is created for the first message. Use createMessageErrorSpan in your catch block for per-message error spans.\n * - 'none': No per-message spans (default)\n */\nexport type PerMessageSpanMode = 'all' | 'errors' | 'none';\n\n/**\n * Configuration for batch consumer wrapper.\n */\nexport interface BatchConsumerConfig {\n /**\n * Name for the batch processing span (e.g., \"orders.batch\")\n */\n name: string;\n\n /**\n * Consumer group name. Sets `messaging.kafka.consumer.group` attribute.\n */\n consumerGroup?: string;\n\n /**\n * Per-message span creation mode. When 'all', message spans follow extracted trace context from headers when valid (trace continuation), otherwise parent to the batch span; all per-message spans are ended on batch completion.\n * @default 'none' (to avoid cardinality explosion)\n */\n perMessageSpans?: PerMessageSpanMode;\n\n /**\n * Optional callback for real-time visibility into batch processing.\n */\n onProgress?: (metrics: BatchProgressMetrics) => void;\n}\n\n/**\n * Wrap a KafkaJS eachBatch handler with observability.\n *\n * Preserves the exact KafkaJS signature, passing through all functions unchanged.\n * Per-message spans are never leaked: all are ended on batch success or on handler throw.\n *\n * @param config - Batch consumer configuration\n * @param handler - The eachBatch handler to wrap\n * @returns Wrapped handler with observability\n *\n * @example With progress tracking\n * ```typescript\n * await consumer.run({\n * eachBatch: withBatchConsumer({\n * name: 'orders.batch',\n * consumerGroup: 'processor',\n * perMessageSpans: 'errors',\n * onProgress: (metrics) => {\n * console.log(`Processed ${metrics.processed}, failed ${metrics.failed}`);\n * },\n * }, async ({ batch, resolveOffset, heartbeat }) => {\n * for (const message of batch.messages) {\n * try {\n * await processOrder(message);\n * resolveOffset(message.offset);\n * } catch (error) {\n * // Per-message span created on error when perMessageSpans='errors'\n * }\n * await heartbeat();\n * }\n * }),\n * });\n * ```\n */\nexport function withBatchConsumer(\n config: BatchConsumerConfig,\n handler: EachBatchHandler,\n): EachBatchHandler {\n const { name, consumerGroup, perMessageSpans = 'none', onProgress } = config;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n return async (payload: EachBatchPayload): Promise<void> => {\n const { batch } = payload;\n const startTime = Date.now();\n\n // Metrics tracking\n let processed = 0;\n let failed = 0;\n let skipped = 0;\n\n // Create batch span\n const batchSpan = tracer.startSpan(name, {\n kind: SpanKind.CONSUMER,\n });\n\n // Set batch attributes\n setBatchAttributes(batchSpan, {\n topic: batch.topic,\n partition: batch.partition,\n consumerGroup,\n messageCount: batch.messages.length,\n firstOffset: batch.firstOffset() ?? undefined,\n lastOffset: batch.lastOffset(),\n });\n\n const spanContext = trace.setSpan(context.active(), batchSpan);\n\n // Create wrapped payload with optional per-message tracking\n const {\n wrappedPayload,\n endOpenMessageSpans,\n endRemainingMessageSpansOnSuccess,\n } = createWrappedPayload(\n payload,\n perMessageSpans,\n tracer,\n spanContext,\n (type: 'processed' | 'failed' | 'skipped') => {\n if (type === 'processed') processed++;\n else if (type === 'failed') failed++;\n else skipped++;\n\n if (onProgress) {\n onProgress({\n processed,\n failed,\n skipped,\n batchProcessingTimeMs: Date.now() - startTime,\n });\n }\n },\n );\n\n try {\n await context.with(spanContext, async () => {\n await handler(wrappedPayload);\n });\n\n // End any per-message spans that were never resolved (skipped/unresolved messages)\n endRemainingMessageSpansOnSuccess?.();\n\n // Set final metrics\n const processingTime = Date.now() - startTime;\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,\n processed,\n );\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,\n failed,\n );\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,\n processingTime,\n );\n\n batchSpan.setStatus({ code: SpanStatusCode.OK });\n batchSpan.end();\n } catch (error) {\n // End any open per-message spans (e.g. handler threw after accessing message)\n endOpenMessageSpans?.(error);\n\n // In 'errors' mode, create a per-message error span for the first message when handler throws\n const firstMessage = batch.messages[0];\n if (perMessageSpans === 'errors' && firstMessage !== undefined) {\n createMessageErrorSpan(\n name,\n {\n offset: firstMessage.offset,\n key: firstMessage.key ?? undefined,\n headers: firstMessage.headers,\n },\n error instanceof Error ? error : new Error(String(error)),\n batch.topic,\n batch.partition,\n );\n }\n\n const processingTime = Date.now() - startTime;\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,\n processed,\n );\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,\n failed + 1, // Count the batch error\n );\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,\n processingTime,\n );\n\n batchSpan.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n batchSpan.recordException(error);\n } else {\n batchSpan.recordException(new Error(String(error)));\n }\n batchSpan.end();\n\n throw error;\n }\n };\n}\n\n/**\n * Set batch-level attributes on the span.\n */\nfunction setBatchAttributes(\n span: Span,\n attrs: {\n topic: string;\n partition: number;\n consumerGroup?: string;\n messageCount: number;\n firstOffset?: string;\n lastOffset: string;\n },\n): void {\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, attrs.topic);\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_PARTITION, attrs.partition);\n span.setAttribute(SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT, attrs.messageCount);\n\n if (attrs.consumerGroup) {\n span.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP,\n attrs.consumerGroup,\n );\n }\n\n if (attrs.firstOffset) {\n span.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET,\n attrs.firstOffset,\n );\n }\n\n span.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET,\n attrs.lastOffset,\n );\n}\n\n/**\n * Result of createWrappedPayload: wrapped payload and optional cleanup for open spans.\n */\ninterface WrappedPayloadResult {\n wrappedPayload: EachBatchPayload;\n endOpenMessageSpans?: (error: unknown) => void;\n endRemainingMessageSpansOnSuccess?: () => void;\n}\n\n/**\n * Create a wrapped payload that optionally tracks per-message processing.\n */\nfunction createWrappedPayload(\n original: EachBatchPayload,\n perMessageSpans: PerMessageSpanMode,\n tracer: ReturnType<typeof trace.getTracer>,\n parentContext: ReturnType<typeof context.active>,\n onMetric: (type: 'processed' | 'failed' | 'skipped') => void,\n): WrappedPayloadResult {\n if (perMessageSpans === 'none') {\n // Pass through unchanged, just track resolveOffset calls\n return {\n wrappedPayload: {\n ...original,\n resolveOffset: (offset: string) => {\n onMetric('processed');\n original.resolveOffset(offset);\n },\n },\n };\n }\n\n // For 'all' mode, create per-message spans upfront\n const messageSpans = new Map<string, Span>();\n\n // Pre-create spans for 'all' mode so they're created regardless of property access.\n // Use extracted trace context from message headers when valid (trace continuation);\n // otherwise parent to the batch span so message spans are not root spans.\n if (perMessageSpans === 'all') {\n for (const message of original.batch.messages) {\n const normalizedHeaders = normalizeHeaders(message.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const spanContext = trace.getSpanContext(extractedCtx);\n const parentCtx =\n spanContext && trace.isSpanContextValid(spanContext)\n ? extractedCtx\n : parentContext;\n\n const span = tracer.startSpan(\n `${original.batch.topic}.${original.batch.partition}.${message.offset}`,\n {\n kind: SpanKind.CONSUMER,\n },\n parentCtx,\n );\n\n span.setAttributes({\n [SEMATTRS_MESSAGING_SYSTEM]: 'kafka',\n [SEMATTRS_MESSAGING_DESTINATION_NAME]: original.batch.topic,\n [SEMATTRS_MESSAGING_KAFKA_PARTITION]: original.batch.partition,\n [SEMATTRS_MESSAGING_KAFKA_OFFSET]: message.offset,\n ...(message.key && {\n [SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY]: message.key.toString(),\n }),\n });\n\n messageSpans.set(message.offset, span);\n }\n }\n\n const wrappedMessages = original.batch.messages.map((message) => ({\n ...message,\n }));\n\n const wrappedBatch = {\n ...original.batch,\n messages: wrappedMessages,\n };\n\n const wrappedPayload: EachBatchPayload = {\n ...original,\n batch: wrappedBatch,\n resolveOffset: (offset: string) => {\n onMetric('processed');\n // End the per-message span if one was created for this offset\n const span = messageSpans.get(offset);\n if (span) {\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n messageSpans.delete(offset);\n }\n original.resolveOffset(offset);\n },\n };\n\n const endOpenMessageSpans =\n perMessageSpans === 'all'\n ? (error: unknown) => {\n for (const [, span] of messageSpans) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n }\n messageSpans.clear();\n }\n : undefined;\n\n const endRemainingMessageSpansOnSuccess =\n perMessageSpans === 'all'\n ? () => {\n for (const [, span] of messageSpans) {\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n }\n messageSpans.clear();\n }\n : undefined;\n\n return {\n wrappedPayload,\n endOpenMessageSpans,\n endRemainingMessageSpansOnSuccess,\n };\n}\n\n/**\n * Helper to create a per-message span for error cases.\n * Call this in your error handler when using perMessageSpans: 'errors'.\n */\nexport function createMessageErrorSpan(\n name: string,\n message: {\n offset: string;\n key?: Buffer | null;\n headers?: Record<string, Buffer | string | undefined>;\n },\n error: Error,\n topic: string,\n partition: number,\n): void {\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n const normalizedHeaders = normalizeHeaders(message.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n\n const span = tracer.startSpan(\n `${name}.error`,\n {\n kind: SpanKind.CONSUMER,\n },\n extractedCtx,\n );\n\n span.setAttributes({\n [SEMATTRS_MESSAGING_SYSTEM]: 'kafka',\n [SEMATTRS_MESSAGING_DESTINATION_NAME]: topic,\n [SEMATTRS_MESSAGING_KAFKA_PARTITION]: partition,\n [SEMATTRS_MESSAGING_KAFKA_OFFSET]: message.offset,\n ...(message.key && {\n [SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY]: message.key.toString(),\n }),\n });\n\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.recordException(error);\n span.end();\n}\n","/**\n * Stream processor for Kafka pipeline patterns.\n *\n * Provides a structured way to process messages through stages,\n * with proper span nesting and lineage tracking.\n *\n * Propagation story:\n * - Stage spans are children of the processor span\n * - Produce spans are children of the stage span that calls producer.send\n * - Output messages carry context from produce span (injected headers)\n * - For lineage: SpanLink from produce span to input message's extracted context\n *\n * @example\n * ```typescript\n * import { createStreamProcessor } from 'autotel-plugins/kafka';\n *\n * const processor = createStreamProcessor({\n * name: 'order-enrichment',\n * stages: ['validate', 'enrich', 'publish'],\n * });\n *\n * await consumer.run({\n * eachMessage: async ({ message }) => {\n * await processor.run(message, async (ctx) => {\n * const validated = await ctx.stage('validate', () => validate(message));\n * const enriched = await ctx.stage('enrich', () => enrich(validated));\n * await ctx.stage('publish', () =>\n * ctx.produce('enriched-orders', enriched, { linkToInput: true })\n * );\n * });\n * },\n * });\n * ```\n */\n\nimport {\n otelTrace as trace,\n context,\n SpanKind,\n SpanStatusCode,\n type Span,\n type SpanLink,\n type SpanContext,\n} from 'autotel';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_OPERATION,\n} from '../common/constants';\nimport { normalizeHeaders, extractTraceContext } from './headers';\nimport { injectTraceHeaders } from './correlation';\nimport type { RawKafkaHeaders } from './types';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * Input message type for stream processing.\n */\nexport interface StreamMessage {\n headers?: RawKafkaHeaders;\n key?: Buffer | null;\n value: Buffer | null;\n offset?: string;\n}\n\n/**\n * Configuration for stream processor.\n */\nexport interface StreamProcessorConfig {\n /**\n * Name for the processor (e.g., \"order-enrichment\")\n */\n name: string;\n\n /**\n * Expected stage names (for documentation/validation).\n * Stages can be run in any order.\n */\n stages?: string[];\n}\n\n/**\n * Options for producing output messages.\n */\nexport interface ProduceOptions {\n /**\n * Create a SpanLink to the input message's extracted context.\n * Useful for lineage tracking.\n * @default false\n */\n linkToInput?: boolean;\n\n /**\n * Additional headers to include (merged with trace headers).\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Context passed to the processor callback.\n */\nexport interface ProcessorContext {\n /**\n * The processor-level span.\n */\n span: Span;\n\n /**\n * Execute a named stage with automatic span creation.\n *\n * @param stageName - Name of the stage (e.g., \"validate\", \"enrich\")\n * @param fn - Stage function to execute\n * @returns Result of the stage function\n */\n stage<T>(stageName: string, fn: () => T | Promise<T>): Promise<T>;\n\n /**\n * Produce a message with proper span creation and header injection.\n *\n * The returned headers should be used when actually sending the message.\n *\n * @param topic - Destination topic\n * @param payload - Message payload\n * @param options - Produce options\n * @returns Headers to use when sending (includes trace context)\n */\n produce(\n topic: string,\n payload: unknown,\n options?: ProduceOptions,\n ): Promise<Record<string, string>>;\n\n /**\n * Get the extracted context from the input message.\n * Useful for creating manual links or context propagation.\n */\n inputContext: SpanContext | undefined;\n}\n\n/**\n * Processor callback type.\n */\nexport type ProcessorCallback<T> = (ctx: ProcessorContext) => Promise<T>;\n\n/**\n * Stream processor instance.\n */\nexport interface StreamProcessor {\n /**\n * Run the processor on an input message.\n *\n * @param message - Input Kafka message\n * @param callback - Processor callback with stage/produce helpers\n * @returns Result of the processor callback\n */\n run<T>(message: StreamMessage, callback: ProcessorCallback<T>): Promise<T>;\n}\n\n/**\n * Create a stream processor for pipeline-style message processing.\n *\n * @param config - Processor configuration\n * @returns Stream processor instance\n *\n * @example\n * ```typescript\n * const processor = createStreamProcessor({\n * name: 'order-enrichment',\n * stages: ['validate', 'enrich', 'publish'],\n * });\n *\n * await processor.run(message, async (ctx) => {\n * const validated = await ctx.stage('validate', async () => {\n * return validateOrder(message.value);\n * });\n *\n * const enriched = await ctx.stage('enrich', async () => {\n * return enrichWithCustomerData(validated);\n * });\n *\n * await ctx.stage('publish', async () => {\n * const headers = await ctx.produce('enriched-orders', enriched, {\n * linkToInput: true,\n * });\n * await producer.send({\n * topic: 'enriched-orders',\n * messages: [{ value: JSON.stringify(enriched), headers }],\n * });\n * });\n * });\n * ```\n */\nexport function createStreamProcessor(\n config: StreamProcessorConfig,\n): StreamProcessor {\n const { name } = config;\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n return {\n async run<T>(\n message: StreamMessage,\n callback: ProcessorCallback<T>,\n ): Promise<T> {\n // Extract context from input message\n const normalizedHeaders = normalizeHeaders(message.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const inputSpanContext = trace.getSpanContext(extractedCtx);\n\n // Create processor span (inherits from extracted context if valid)\n const processorSpan = tracer.startSpan(\n name,\n {\n kind: SpanKind.CONSUMER,\n },\n inputSpanContext && trace.isSpanContextValid(inputSpanContext)\n ? extractedCtx\n : undefined,\n );\n\n processorSpan.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');\n processorSpan.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'process');\n\n const processorContext = trace.setSpan(context.active(), processorSpan);\n\n // Create context object with helpers\n const ctx: ProcessorContext = {\n span: processorSpan,\n inputContext: inputSpanContext,\n\n async stage<S>(\n stageName: string,\n fn: () => S | Promise<S>,\n ): Promise<S> {\n return context.with(processorContext, async () => {\n const stageSpan = tracer.startSpan(`${name}.${stageName}`, {\n kind: SpanKind.INTERNAL,\n });\n\n stageSpan.setAttribute('stream.stage', stageName);\n\n const stageContext = trace.setSpan(context.active(), stageSpan);\n\n try {\n const result = await context.with(stageContext, async () => {\n return await fn();\n });\n\n stageSpan.setStatus({ code: SpanStatusCode.OK });\n stageSpan.end();\n\n return result;\n } catch (error) {\n stageSpan.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n stageSpan.recordException(error);\n } else {\n stageSpan.recordException(new Error(String(error)));\n }\n stageSpan.end();\n\n throw error;\n }\n });\n },\n\n async produce(\n topic: string,\n _payload: unknown,\n options?: ProduceOptions,\n ): Promise<Record<string, string>> {\n const { linkToInput = false, headers: extraHeaders = {} } =\n options ?? {};\n\n // Build links\n const links: SpanLink[] = [];\n if (\n linkToInput &&\n inputSpanContext &&\n trace.isSpanContextValid(inputSpanContext)\n ) {\n links.push({ context: inputSpanContext });\n }\n\n // Create produce span as child of current context (the stage span)\n const produceSpan = tracer.startSpan(`${name}.produce`, {\n kind: SpanKind.PRODUCER,\n links,\n });\n\n produceSpan.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');\n produceSpan.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);\n produceSpan.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'publish');\n\n // Inject trace context from within the produce span\n const produceContext = trace.setSpan(context.active(), produceSpan);\n\n return context.with(produceContext, () => {\n const headers = injectTraceHeaders(extraHeaders, {\n includeCorrelationIdHeader: true,\n });\n\n produceSpan.setStatus({ code: SpanStatusCode.OK });\n produceSpan.end();\n\n return headers;\n });\n },\n };\n\n try {\n const result = await context.with(processorContext, async () => {\n return await callback(ctx);\n });\n\n processorSpan.setStatus({ code: SpanStatusCode.OK });\n processorSpan.end();\n\n return result;\n } catch (error) {\n processorSpan.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n processorSpan.recordException(error);\n } else {\n processorSpan.recordException(new Error(String(error)));\n }\n processorSpan.end();\n\n throw error;\n }\n },\n };\n}\n","/**\n * Consumer metrics for Kafka observability.\n *\n * Provides opt-in metrics collection for Kafka consumers, including\n * consumer lag tracking with configurable strategies.\n *\n * @example\n * ```typescript\n * import { ConsumerMetrics } from 'autotel-plugins/kafka';\n *\n * const metrics = new ConsumerMetrics({\n * consumer,\n * metricsPrefix: 'kafka.consumer',\n * enableLag: true,\n * lagStrategy: 'polling',\n * lagPollIntervalMs: 30000,\n * });\n *\n * // Start metrics collection\n * await metrics.start();\n *\n * // ... consumer runs ...\n *\n * // Stop metrics collection\n * await metrics.stop();\n * ```\n */\n\nimport { metrics as otelMetrics } from '@opentelemetry/api';\n\n/**\n * Lag tracking strategy.\n * - 'polling': Explicit admin calls (accurate, more overhead)\n * - 'event': Consumer events only (less accurate, no admin calls)\n * - 'hybrid': Event-based with periodic validation (default if enabled)\n */\nexport type LagStrategy = 'polling' | 'event' | 'hybrid';\n\n/**\n * Minimal Kafka consumer interface for metrics collection.\n * Matches KafkaJS consumer shape.\n */\nexport interface KafkaConsumer {\n on(event: string, listener: (...args: unknown[]) => void): void;\n describeGroup?(): Promise<{\n members: Array<{\n memberId: string;\n clientId: string;\n memberAssignment: Buffer;\n }>;\n state: string;\n }>;\n}\n\n/**\n * Minimal Kafka admin interface for lag calculation.\n */\nexport interface KafkaAdmin {\n fetchTopicOffsets(\n topic: string,\n ): Promise<\n Array<{ partition: number; offset: string; high: string; low: string }>\n >;\n fetchOffsets(options: { groupId: string; topics: string[] }): Promise<\n Array<{\n topic: string;\n partitions: Array<{ partition: number; offset: string }>;\n }>\n >;\n}\n\n/**\n * Configuration for consumer metrics.\n */\nexport interface ConsumerMetricsConfig {\n /**\n * The Kafka consumer to monitor.\n */\n consumer: KafkaConsumer;\n\n /**\n * Optional Kafka admin client for lag calculation.\n * Required if enableLag is true and lagStrategy is 'polling' or 'hybrid'.\n */\n admin?: KafkaAdmin;\n\n /**\n * Consumer group ID (required for lag calculation).\n */\n groupId?: string;\n\n /**\n * Topics to monitor for lag.\n */\n topics?: string[];\n\n /**\n * Prefix for metric names.\n * @default 'kafka.consumer'\n */\n metricsPrefix?: string;\n\n /**\n * Enable consumer lag tracking.\n * @default false\n */\n enableLag?: boolean;\n\n /**\n * Strategy for lag calculation.\n * @default 'hybrid'\n */\n lagStrategy?: LagStrategy;\n\n /**\n * Interval for lag polling in milliseconds.\n * Required when enableLag is true and lagStrategy is 'polling'.\n * @default 30000\n */\n lagPollIntervalMs?: number;\n}\n\n/**\n * Internal state for tracking offsets.\n */\ninterface PartitionState {\n topic: string;\n partition: number;\n currentOffset: string;\n highWatermark?: string;\n}\n\n/**\n * Consumer metrics collector.\n *\n * Provides:\n * - kafka.consumer.messages_processed (counter)\n * - kafka.consumer.processing_duration (histogram)\n * - kafka.consumer.batch_size (histogram)\n * - kafka.consumer.rebalances (counter)\n * - kafka.consumer.lag (gauge, opt-in)\n */\nexport class ConsumerMetrics {\n private readonly config: Required<\n Pick<\n ConsumerMetricsConfig,\n 'metricsPrefix' | 'enableLag' | 'lagStrategy' | 'lagPollIntervalMs'\n >\n > &\n ConsumerMetricsConfig;\n\n private readonly meter;\n private readonly messagesProcessed;\n private readonly processingDuration;\n private readonly batchSize;\n private readonly rebalances;\n private readonly lag;\n\n private partitionStates: Map<string, PartitionState> = new Map();\n private lagPollInterval?: ReturnType<typeof setInterval>;\n private isRunning = false;\n\n constructor(config: ConsumerMetricsConfig) {\n // Validate config\n if (\n config.enableLag &&\n config.lagStrategy === 'polling' &&\n !config.lagPollIntervalMs\n ) {\n throw new Error('Lag polling requires lagPollIntervalMs');\n }\n\n if (\n config.enableLag &&\n (config.lagStrategy === 'polling' || config.lagStrategy === 'hybrid')\n ) {\n if (!config.admin) {\n throw new Error(\n `Lag strategy '${config.lagStrategy}' requires admin client`,\n );\n }\n if (!config.groupId) {\n throw new Error('Lag tracking requires groupId');\n }\n if (!config.topics || config.topics.length === 0) {\n throw new Error('Lag tracking requires topics');\n }\n }\n\n this.config = {\n ...config,\n metricsPrefix: config.metricsPrefix ?? 'kafka.consumer',\n enableLag: config.enableLag ?? false,\n lagStrategy: config.lagStrategy ?? 'hybrid',\n lagPollIntervalMs: config.lagPollIntervalMs ?? 30_000,\n };\n\n // Initialize meter\n this.meter = otelMetrics.getMeter('autotel-plugins/kafka');\n const prefix = this.config.metricsPrefix;\n\n // Create metric instruments\n this.messagesProcessed = this.meter.createCounter(\n `${prefix}.messages_processed`,\n {\n description: 'Total number of messages processed',\n },\n );\n\n this.processingDuration = this.meter.createHistogram(\n `${prefix}.processing_duration`,\n {\n description: 'Message processing duration in milliseconds',\n unit: 'ms',\n },\n );\n\n this.batchSize = this.meter.createHistogram(`${prefix}.batch_size`, {\n description: 'Number of messages in each batch',\n });\n\n this.rebalances = this.meter.createCounter(`${prefix}.rebalances`, {\n description: 'Number of consumer group rebalances',\n });\n\n this.lag = this.meter.createObservableGauge(`${prefix}.lag`, {\n description: 'Consumer lag per topic-partition',\n });\n\n // Set up lag observation callback\n if (this.config.enableLag) {\n this.lag.addCallback((observableResult) => {\n for (const [, state] of this.partitionStates.entries()) {\n if (state.highWatermark) {\n const lagValue =\n BigInt(state.highWatermark) - BigInt(state.currentOffset);\n observableResult.observe(Number(lagValue), {\n topic: state.topic,\n partition: state.partition,\n });\n }\n }\n });\n }\n }\n\n /**\n * Start metrics collection.\n */\n async start(): Promise<void> {\n if (this.isRunning) return;\n this.isRunning = true;\n\n const { consumer } = this.config;\n\n // Attach event listeners\n consumer.on('consumer.rebalancing', () => {\n this.rebalances.add(1, { event: 'rebalancing' });\n });\n\n consumer.on('consumer.group_join', () => {\n this.rebalances.add(1, { event: 'group_join' });\n });\n\n // Start lag polling if configured\n if (\n this.config.enableLag &&\n (this.config.lagStrategy === 'polling' ||\n this.config.lagStrategy === 'hybrid')\n ) {\n await this.pollLag();\n this.lagPollInterval = setInterval(\n () => this.pollLag().catch(() => {}),\n this.config.lagPollIntervalMs,\n );\n }\n }\n\n /**\n * Stop metrics collection.\n */\n async stop(): Promise<void> {\n if (!this.isRunning) return;\n this.isRunning = false;\n\n if (this.lagPollInterval) {\n clearInterval(this.lagPollInterval);\n this.lagPollInterval = undefined;\n }\n }\n\n /**\n * Record a message being processed.\n *\n * @param topic - Message topic\n * @param partition - Message partition\n * @param durationMs - Processing duration in milliseconds\n */\n recordMessageProcessed(\n topic: string,\n partition: number,\n durationMs?: number,\n ): void {\n this.messagesProcessed.add(1, { topic, partition });\n\n if (durationMs !== undefined) {\n this.processingDuration.record(durationMs, { topic, partition });\n }\n }\n\n /**\n * Record a batch being processed.\n *\n * @param topic - Batch topic\n * @param partition - Batch partition\n * @param size - Number of messages in the batch\n */\n recordBatch(topic: string, partition: number, size: number): void {\n this.batchSize.record(size, { topic, partition });\n }\n\n /**\n * Update offset state for event-based lag tracking.\n *\n * @param topic - Topic name\n * @param partition - Partition number\n * @param offset - Current consumer offset\n * @param highWatermark - Optional high watermark\n */\n updateOffset(\n topic: string,\n partition: number,\n offset: string,\n highWatermark?: string,\n ): void {\n const key = `${topic}-${partition}`;\n const existing = this.partitionStates.get(key);\n\n this.partitionStates.set(key, {\n topic,\n partition,\n currentOffset: offset,\n highWatermark: highWatermark ?? existing?.highWatermark,\n });\n }\n\n /**\n * Poll for lag using admin client.\n */\n private async pollLag(): Promise<void> {\n const { admin, groupId, topics } = this.config;\n if (!admin || !groupId || !topics) return;\n\n try {\n // Fetch committed offsets for the consumer group\n const committedOffsets = await admin.fetchOffsets({\n groupId,\n topics,\n });\n\n // For each topic, fetch the high watermarks\n for (const topicOffsets of committedOffsets) {\n const topicHighWatermarks = await admin.fetchTopicOffsets(\n topicOffsets.topic,\n );\n\n for (const partition of topicOffsets.partitions) {\n const hwm = topicHighWatermarks.find(\n (p) => p.partition === partition.partition,\n );\n if (hwm) {\n const key = `${topicOffsets.topic}-${partition.partition}`;\n this.partitionStates.set(key, {\n topic: topicOffsets.topic,\n partition: partition.partition,\n currentOffset: partition.offset,\n highWatermark: hwm.high,\n });\n }\n }\n }\n } catch {\n // Silently fail - lag metrics are best-effort\n }\n }\n}\n","/**\n * Stream events instrumentation for Kafka consumers.\n *\n * Provides visibility into consumer lifecycle events like rebalances,\n * errors, and heartbeats. Defaults to events mode (not spans) to\n * avoid span explosion.\n *\n * @example\n * ```typescript\n * import { instrumentConsumerEvents } from 'autotel-plugins/kafka';\n *\n * instrumentConsumerEvents(consumer, {\n * mode: 'events',\n * traceRebalances: true,\n * traceErrors: true,\n * traceHeartbeats: false,\n * });\n * ```\n */\n\nimport {\n otelTrace as trace,\n SpanKind,\n SpanStatusCode,\n type Span,\n} from 'autotel';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * Event mode for consumer events.\n * - 'events': Attach events to existing lifecycle span (lower overhead)\n * - 'spans': Create separate spans for each event (more detail)\n */\nexport type EventMode = 'events' | 'spans';\n\n/**\n * Minimal Kafka consumer interface for event instrumentation.\n */\nexport interface EventConsumer {\n on(event: string, listener: (...args: unknown[]) => void): void;\n off?(event: string, listener: (...args: unknown[]) => void): void;\n}\n\n/**\n * Configuration for consumer event instrumentation.\n */\nexport interface ConsumerEventsConfig {\n /**\n * Event mode: 'events' attaches to spans, 'spans' creates new spans.\n * @default 'events'\n */\n mode?: EventMode;\n\n /**\n * Trace rebalance events (GROUP_JOIN, REBALANCING).\n * @default true\n */\n traceRebalances?: boolean;\n\n /**\n * Trace error events (CRASH, DISCONNECT).\n * @default true\n */\n traceErrors?: boolean;\n\n /**\n * Trace heartbeat events.\n * @default false (too noisy for most use cases)\n */\n traceHeartbeats?: boolean;\n\n /**\n * Optional lifecycle span to attach events to.\n * Only used when mode is 'events'.\n */\n lifecycleSpan?: Span;\n}\n\n/**\n * Cleanup function returned by instrumentConsumerEvents.\n */\nexport type CleanupFunction = () => void;\n\n/**\n * KafkaJS event types we're interested in.\n */\nconst REBALANCE_EVENTS = [\n 'consumer.group_join',\n 'consumer.rebalancing',\n 'consumer.stop',\n] as const;\n\nconst ERROR_EVENTS = [\n 'consumer.crash',\n 'consumer.disconnect',\n 'consumer.network.request_timeout',\n] as const;\n\nconst HEARTBEAT_EVENTS = ['consumer.heartbeat'] as const;\n\n/**\n * Instrument a Kafka consumer's lifecycle events.\n *\n * Returns a cleanup function to remove event listeners.\n *\n * @param consumer - Kafka consumer to instrument\n * @param config - Instrumentation configuration\n * @returns Cleanup function\n *\n * @example\n * ```typescript\n * const cleanup = instrumentConsumerEvents(consumer, {\n * mode: 'events',\n * traceRebalances: true,\n * traceErrors: true,\n * });\n *\n * // Later, to clean up:\n * cleanup();\n * ```\n */\nexport function instrumentConsumerEvents(\n consumer: EventConsumer,\n config: ConsumerEventsConfig = {},\n): CleanupFunction {\n const {\n mode = 'events',\n traceRebalances = true,\n traceErrors = true,\n traceHeartbeats = false,\n lifecycleSpan,\n } = config;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n const listeners: Array<{\n event: string;\n listener: (...args: unknown[]) => void;\n }> = [];\n\n // Helper to add a listener and track it\n const addListener = (\n event: string,\n listener: (...args: unknown[]) => void,\n ) => {\n consumer.on(event, listener);\n listeners.push({ event, listener });\n };\n\n // Rebalance events\n if (traceRebalances) {\n for (const event of REBALANCE_EVENTS) {\n addListener(event, (payload: unknown) => {\n if (mode === 'spans') {\n createEventSpan(tracer, event, payload);\n } else if (lifecycleSpan) {\n lifecycleSpan.addEvent(event, extractEventAttributes(payload));\n }\n });\n }\n }\n\n // Error events\n if (traceErrors) {\n for (const event of ERROR_EVENTS) {\n addListener(event, (payload: unknown) => {\n if (mode === 'spans') {\n createErrorSpan(tracer, event, payload);\n } else if (lifecycleSpan) {\n lifecycleSpan.addEvent(event, {\n ...extractEventAttributes(payload),\n 'event.severity': 'error',\n });\n\n // Also record exception if it's a crash\n if (event === 'consumer.crash' && isErrorPayload(payload)) {\n lifecycleSpan.recordException(payload.error);\n }\n }\n });\n }\n }\n\n // Heartbeat events\n if (traceHeartbeats) {\n for (const event of HEARTBEAT_EVENTS) {\n addListener(event, (payload: unknown) => {\n if (mode === 'spans') {\n createEventSpan(tracer, event, payload);\n } else if (lifecycleSpan) {\n lifecycleSpan.addEvent(event, extractEventAttributes(payload));\n }\n });\n }\n }\n\n // Return cleanup function\n return () => {\n if (consumer.off) {\n for (const { event, listener } of listeners) {\n consumer.off(event, listener);\n }\n }\n listeners.length = 0;\n };\n}\n\n/**\n * Create a span for a consumer event.\n */\nfunction createEventSpan(\n tracer: ReturnType<typeof trace.getTracer>,\n eventName: string,\n payload: unknown,\n): void {\n const span = tracer.startSpan(`kafka.consumer.${eventName}`, {\n kind: SpanKind.INTERNAL,\n });\n\n const attributes = extractEventAttributes(payload);\n for (const [key, value] of Object.entries(attributes)) {\n span.setAttribute(key, value);\n }\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n}\n\n/**\n * Create an error span for a consumer error event.\n */\nfunction createErrorSpan(\n tracer: ReturnType<typeof trace.getTracer>,\n eventName: string,\n payload: unknown,\n): void {\n const span = tracer.startSpan(`kafka.consumer.${eventName}`, {\n kind: SpanKind.INTERNAL,\n });\n\n const attributes = extractEventAttributes(payload);\n for (const [key, value] of Object.entries(attributes)) {\n span.setAttribute(key, value);\n }\n\n span.setStatus({ code: SpanStatusCode.ERROR });\n\n if (isErrorPayload(payload)) {\n span.recordException(payload.error);\n }\n\n span.end();\n}\n\n/**\n * Extract attributes from event payload.\n */\nfunction extractEventAttributes(\n payload: unknown,\n): Record<string, string | number | boolean> {\n const attributes: Record<string, string | number | boolean> = {};\n\n if (!payload || typeof payload !== 'object') {\n return attributes;\n }\n\n const p = payload as Record<string, unknown>;\n\n if (typeof p.groupId === 'string') {\n attributes['messaging.kafka.consumer.group'] = p.groupId;\n }\n\n if (typeof p.memberId === 'string') {\n attributes['messaging.kafka.consumer.member_id'] = p.memberId;\n }\n\n if (typeof p.leaderId === 'string') {\n attributes['messaging.kafka.consumer.leader_id'] = p.leaderId;\n }\n\n if (typeof p.duration === 'number') {\n attributes['event.duration_ms'] = p.duration;\n }\n\n if (typeof p.isLeader === 'boolean') {\n attributes['messaging.kafka.consumer.is_leader'] = p.isLeader;\n }\n\n if (Array.isArray(p.memberAssignment)) {\n attributes['messaging.kafka.consumer.assignment_count'] =\n p.memberAssignment.length;\n }\n\n if (typeof p.type === 'string') {\n attributes['event.type'] = p.type;\n }\n\n return attributes;\n}\n\n/**\n * Type guard for error payloads.\n */\nfunction isErrorPayload(payload: unknown): payload is { error: Error } {\n return (\n payload !== null &&\n typeof payload === 'object' &&\n 'error' in payload &&\n payload.error instanceof Error\n );\n}\n","/**\n * Header utilities for RabbitMQ message processing.\n *\n * Uses OpenTelemetry propagators internally for context extraction,\n * ensuring compatibility with W3C Trace Context, B3, and other formats.\n */\n\nimport { propagation, ROOT_CONTEXT, type Context } from 'autotel';\nimport type { RawAmqpHeaders } from './types';\n\n/**\n * Normalize AMQP headers from raw format to string record.\n *\n * Handles:\n * - undefined/null headers -> empty object\n * - Buffer values -> UTF-8 strings (with base64 fallback for invalid UTF-8)\n * - undefined values -> removed from output\n * - string values -> passed through\n * - number/boolean values -> String() conversion\n * - object values -> JSON.stringify() (dropped if > 1KB)\n *\n * @param headers - Raw AMQP headers (Record or undefined)\n * @returns Normalized headers as string record\n *\n * @example\n * ```typescript\n * const raw = {\n * traceparent: Buffer.from('00-abc...'),\n * 'content-type': 'application/json',\n * optionalHeader: undefined,\n * retryCount: 3,\n * };\n * const normalized = normalizeHeaders(raw);\n * // { traceparent: '00-abc...', 'content-type': 'application/json', retryCount: '3' }\n * ```\n */\nexport function normalizeHeaders(\n headers?: RawAmqpHeaders,\n): Record<string, string> {\n if (!headers) {\n return {};\n }\n\n const normalized: Record<string, string> = {};\n const MAX_OBJECT_SIZE = 1024; // 1KB limit for stringified objects\n\n for (const [key, value] of Object.entries(headers)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (Buffer.isBuffer(value)) {\n // Try UTF-8 decode, fall back to base64 with prefix\n try {\n const decoded = value.toString('utf8');\n // Check if the string is valid UTF-8 by re-encoding and comparing\n normalized[key] = Buffer.from(decoded, 'utf8').equals(value)\n ? decoded\n : `base64:${value.toString('base64')}`;\n } catch {\n normalized[key] = `base64:${value.toString('base64')}`;\n }\n } else if (typeof value === 'string') {\n normalized[key] = value;\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n normalized[key] = String(value);\n } else if (typeof value === 'object') {\n // Stringify objects, drop if too large\n try {\n const json = JSON.stringify(value);\n if (json.length <= MAX_OBJECT_SIZE) {\n normalized[key] = json;\n }\n // Silently drop objects > 1KB\n } catch {\n // Silently drop objects that can't be stringified\n }\n }\n }\n\n return normalized;\n}\n\n/**\n * TextMapGetter for case-insensitive header lookup.\n *\n * AMQP headers can have varying case, but trace context headers\n * (traceparent, tracestate, baggage) should be matched case-insensitively\n * for maximum compatibility.\n */\nconst caseInsensitiveGetter = {\n get(carrier: Record<string, string>, key: string): string | undefined {\n const lowerKey = key.toLowerCase();\n for (const [k, v] of Object.entries(carrier)) {\n if (k.toLowerCase() === lowerKey) {\n return v;\n }\n }\n return undefined;\n },\n keys(carrier: Record<string, string>): string[] {\n return Object.keys(carrier);\n },\n};\n\n/**\n * Extract trace context from normalized headers using OTel propagators.\n *\n * This is a pure function that does not activate any context.\n * The returned Context can be used to:\n * - Start spans as children of the extracted context\n * - Create links to the extracted context\n *\n * Returns ROOT_CONTEXT if no trace context is found in headers.\n *\n * @param headers - Normalized headers (use normalizeHeaders first)\n * @returns OpenTelemetry Context with extracted trace context\n *\n * @example\n * ```typescript\n * import { normalizeHeaders, extractTraceContext } from 'autotel-plugins/rabbitmq';\n * import { trace } from '@opentelemetry/api';\n *\n * const headers = normalizeHeaders(message.properties.headers);\n * const extractedCtx = extractTraceContext(headers);\n *\n * // Get span context from extracted context\n * const spanContext = trace.getSpanContext(extractedCtx);\n * if (spanContext && trace.isSpanContextValid(spanContext)) {\n * // Valid remote context extracted\n * }\n * ```\n */\nexport function extractTraceContext(headers: Record<string, string>): Context {\n return propagation.extract(ROOT_CONTEXT, headers, caseInsensitiveGetter);\n}\n","/**\n * Correlation ID utilities for RabbitMQ message tracing.\n *\n * Provides consistent correlation ID handling across producers and consumers:\n * - Inject trace headers and correlation ID into outgoing messages\n * - Extract correlation ID from incoming messages\n * - Derive correlation ID from current trace context\n */\n\nimport {\n propagation,\n context,\n otelTrace as trace,\n type TextMapSetter,\n} from 'autotel';\nimport type { InjectOptions } from './types';\nimport { CORRELATION_ID_HEADER } from '../common/constants';\n\n/**\n * TextMapSetter for injecting headers.\n */\nconst headerSetter: TextMapSetter<Record<string, string>> = {\n set(carrier: Record<string, string>, key: string, value: string): void {\n carrier[key] = value;\n },\n};\n\n/**\n * Derive correlation ID from current trace context.\n *\n * Priority:\n * 1. Baggage 'correlation-id' if present\n * 2. First 16 characters of trace ID (64-bit for compatibility)\n * 3. Empty string if no active trace\n *\n * Note: Uses first 16 chars of trace ID to be stable per trace, not per attempt.\n *\n * @returns Correlation ID derived from context\n *\n * @example\n * ```typescript\n * import { deriveCorrelationId } from 'autotel-plugins/rabbitmq';\n *\n * // Inside a traced operation\n * const correlationId = deriveCorrelationId();\n * // '4bf92f3577b34da6' (first 16 chars of trace ID)\n * ```\n */\nexport function deriveCorrelationId(): string {\n // Check baggage first\n const activeBaggage = propagation.getActiveBaggage();\n const baggageCorrelationId = activeBaggage?.getEntry('correlation-id');\n if (baggageCorrelationId?.value) {\n return baggageCorrelationId.value;\n }\n\n // Fall back to trace ID (first 16 chars)\n const activeSpan = trace.getActiveSpan();\n if (activeSpan) {\n const spanContext = activeSpan.spanContext();\n // Return first 16 chars (64-bit) for compatibility with systems\n // that don't support full 128-bit trace IDs\n return spanContext.traceId.slice(0, 16);\n }\n\n return '';\n}\n\n/**\n * Extract correlation ID from message headers or AMQP correlationId property.\n *\n * Priority:\n * 1. AMQP correlationId property (if provided)\n * 2. x-correlation-id header (case-insensitive)\n *\n * @param headers - Normalized headers (string values)\n * @param amqpCorrelationId - Optional AMQP correlationId property value\n * @returns Correlation ID if found, undefined otherwise\n *\n * @example\n * ```typescript\n * import { extractCorrelationId, normalizeHeaders } from 'autotel-plugins/rabbitmq';\n *\n * const headers = normalizeHeaders(message.properties.headers);\n * const correlationId = extractCorrelationId(headers, message.properties.correlationId);\n * if (correlationId) {\n * logger.info({ correlationId }, 'Processing message');\n * }\n * ```\n */\nexport function extractCorrelationId(\n headers: Record<string, string>,\n amqpCorrelationId?: string,\n): string | undefined {\n // Priority 1: AMQP correlationId property\n if (amqpCorrelationId) {\n return amqpCorrelationId;\n }\n\n // Priority 2: x-correlation-id header (case-insensitive)\n const lowerKey = CORRELATION_ID_HEADER.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === lowerKey) {\n return value;\n }\n }\n return undefined;\n}\n\n/**\n * Inject trace headers into outgoing message headers.\n *\n * Uses OpenTelemetry propagators to inject W3C Trace Context (traceparent, tracestate)\n * and optionally adds x-correlation-id header (default: true).\n *\n * Note: Baggage is injected automatically when W3CBaggagePropagator is registered.\n *\n * @param base - Base headers to merge with injected headers\n * @param options - Injection options\n * @returns Headers with trace context injected\n *\n * @example\n * ```typescript\n * import { injectTraceHeaders } from 'autotel-plugins/rabbitmq';\n *\n * // Publisher: inject headers with correlation ID\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * channel.publish('exchange', 'routing.key', content, { headers });\n * ```\n *\n * @example With explicit correlation ID\n * ```typescript\n * const headers = injectTraceHeaders({}, {\n * correlationId: 'order-12345',\n * includeCorrelationIdHeader: true,\n * });\n * ```\n */\nexport function injectTraceHeaders(\n base: Record<string, string> = {},\n options: InjectOptions = {},\n): Record<string, string> {\n const { correlationId, includeCorrelationIdHeader = true } = options;\n\n const carrier = { ...base };\n\n // Inject trace context (traceparent, tracestate)\n // Note: If W3CBaggagePropagator is registered, baggage is also injected automatically\n propagation.inject(context.active(), carrier, headerSetter);\n\n // Add correlation ID if requested\n if (includeCorrelationIdHeader) {\n const corrId = correlationId ?? deriveCorrelationId();\n if (corrId) {\n carrier[CORRELATION_ID_HEADER] = corrId;\n }\n }\n\n return carrier;\n}\n","/**\n * Processing span wrapper for RabbitMQ message handling.\n *\n * Creates processing spans with proper context handling, supporting:\n * - Context mode control (inherit/link/none)\n * - Messaging attributes for consistent querying\n * - Integration with official amqplib instrumentation\n * - Deferred ack tracking mode\n */\n\nimport {\n otelTrace as trace,\n context,\n SpanKind,\n SpanStatusCode,\n type Span,\n type SpanContext,\n type SpanLink,\n} from 'autotel';\nimport type {\n ConsumeDescriptor,\n ContextMode,\n ConsumeSpanCallback,\n DeferredConsumeSpanCallback,\n AckControls,\n} from './types';\nimport { normalizeHeaders, extractTraceContext } from './headers';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_OPERATION_NAME,\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_EXCHANGE,\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY,\n SEMATTRS_MESSAGING_MESSAGE_ID,\n SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID,\n SEMATTRS_MESSAGING_CONSUMER_ID,\n SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT,\n SEMATTRS_MESSAGING_RABBITMQ_REQUEUE,\n} from '../common/constants';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/rabbitmq';\n\n/**\n * Check if a span context is valid (has both traceId and spanId).\n */\nfunction isValidSpanContext(\n spanContext: SpanContext | undefined,\n): spanContext is SpanContext {\n return !!(\n spanContext &&\n spanContext.traceId &&\n spanContext.spanId &&\n trace.isSpanContextValid(spanContext)\n );\n}\n\n/**\n * Validate configuration for deferred span mode.\n */\nfunction validateDeferredConfig(descriptor: ConsumeDescriptor): void {\n if (descriptor.deferSpanEnd && !descriptor.ackTimeoutMs) {\n throw new Error('deferSpanEnd requires ackTimeoutMs to be set');\n }\n}\n\n/**\n * Create a consume/processing span for RabbitMQ message handling.\n *\n * **Context Mode Behavior:**\n *\n * | Mode | Behavior |\n * |------|----------|\n * | `inherit` | Extracted remote context becomes the **parent**. If headers contain context, it overrides any active span. |\n * | `link` | Consumer span parents to current active context (or root). Extracted context becomes a **SpanLink**. |\n * | `none` | Ignore extracted context entirely. Consumer span uses current active context (or root). No links created. |\n *\n * @param descriptor - Processing span configuration\n * @param fn - Async callback to execute within the span\n * @returns Promise resolving to callback result\n * @throws Error if span creation fails or callback throws\n *\n * @example Basic usage\n * ```typescript\n * import { withConsumeSpan } from 'autotel-plugins/rabbitmq';\n *\n * channel.consume('queue', async (msg) => {\n * if (!msg) return;\n * try {\n * await withConsumeSpan({\n * name: 'order.process',\n * headers: msg.properties.headers,\n * contextMode: 'inherit',\n * queue: 'orders',\n * exchange: 'orders-exchange',\n * routingKey: msg.fields.routingKey,\n * }, async (span) => {\n * await processOrder(msg);\n * channel.ack(msg);\n * });\n * } catch (error) {\n * channel.nack(msg, false, false);\n * }\n * });\n * ```\n *\n * @example With deferred ack tracking\n * ```typescript\n * await withConsumeSpan({\n * name: 'order.process',\n * headers: msg.properties.headers,\n * deferSpanEnd: true,\n * ackTimeoutMs: 60000,\n * }, async (span, controls) => {\n * await processOrder(msg);\n * controls.ack(); // Ends span with success\n * });\n * ```\n */\nexport function withConsumeSpan<T>(\n descriptor: ConsumeDescriptor & { deferSpanEnd: true; ackTimeoutMs: number },\n fn: DeferredConsumeSpanCallback<T>,\n): Promise<T>;\nexport function withConsumeSpan<T>(\n descriptor: ConsumeDescriptor & { deferSpanEnd?: false },\n fn: ConsumeSpanCallback<T>,\n): Promise<T>;\nexport function withConsumeSpan<T>(\n descriptor: ConsumeDescriptor,\n fn: ConsumeSpanCallback<T> | DeferredConsumeSpanCallback<T>,\n): Promise<T>;\nexport async function withConsumeSpan<T>(\n descriptor: ConsumeDescriptor,\n fn: ConsumeSpanCallback<T> | DeferredConsumeSpanCallback<T>,\n): Promise<T> {\n validateDeferredConfig(descriptor);\n\n const {\n name,\n headers,\n contextMode = 'inherit',\n links = [],\n queue,\n exchange,\n routingKey,\n messageId,\n correlationId,\n consumerTag,\n deferSpanEnd = false,\n ackTimeoutMs,\n } = descriptor;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n const normalizedHeaders = normalizeHeaders(headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const extractedSpanContext = trace.getSpanContext(extractedCtx);\n\n // Determine parent context and links based on context mode\n const { parentContext, spanLinks } = resolveContextAndLinks(\n contextMode,\n extractedSpanContext,\n links,\n );\n\n // Create span with computed parent and links\n const span = tracer.startSpan(\n name,\n {\n kind: SpanKind.CONSUMER,\n links: spanLinks,\n },\n parentContext,\n );\n\n // Set messaging attributes\n setMessagingAttributes(span, {\n queue,\n exchange,\n routingKey,\n messageId,\n correlationId,\n consumerTag,\n });\n\n // Execute callback within span context\n const spanContext = trace.setSpan(context.active(), span);\n\n if (deferSpanEnd) {\n return executeDeferredMode(\n span,\n spanContext,\n fn as DeferredConsumeSpanCallback<T>,\n ackTimeoutMs!,\n );\n }\n\n return executeImmediateMode(span, spanContext, fn as ConsumeSpanCallback<T>);\n}\n\n/**\n * Execute callback in immediate mode - span ends when callback completes.\n */\nasync function executeImmediateMode<T>(\n span: Span,\n spanContext: ReturnType<typeof context.active>,\n fn: ConsumeSpanCallback<T>,\n): Promise<T> {\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span);\n });\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n\n throw error;\n }\n}\n\n/**\n * Execute callback in deferred mode - span ends when ack/nack/reject is called.\n */\nasync function executeDeferredMode<T>(\n span: Span,\n spanContext: ReturnType<typeof context.active>,\n fn: DeferredConsumeSpanCallback<T>,\n ackTimeoutMs: number,\n): Promise<T> {\n let spanEnded = false;\n\n // Create a reference object to hold the timeout ID\n const timeoutRef: { id?: ReturnType<typeof setTimeout> } = {};\n\n const endSpan = (\n status: 'ok' | 'error',\n outcome?: 'ack' | 'nack' | 'reject',\n requeue?: boolean,\n ) => {\n if (spanEnded) return;\n spanEnded = true;\n\n if (timeoutRef.id) {\n clearTimeout(timeoutRef.id);\n }\n\n if (outcome) {\n span.setAttribute(SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT, outcome);\n }\n if (requeue !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_RABBITMQ_REQUEUE, requeue);\n }\n\n span.setStatus({\n code: status === 'ok' ? SpanStatusCode.OK : SpanStatusCode.ERROR,\n });\n span.end();\n };\n\n const controls: AckControls = {\n ack() {\n endSpan('ok', 'ack');\n },\n nack(options?: { requeue?: boolean }) {\n endSpan('ok', 'nack', options?.requeue ?? true);\n },\n reject(options?: { requeue?: boolean }) {\n endSpan('ok', 'reject', options?.requeue ?? false);\n },\n };\n\n // Set up timeout\n timeoutRef.id = setTimeout(() => {\n if (!spanEnded) {\n span.setAttribute('messaging.rabbitmq.ack_timeout', true);\n endSpan('error');\n }\n }, ackTimeoutMs);\n\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span, controls);\n });\n\n // If span wasn't ended by controls, end it now with OK\n if (!spanEnded) {\n endSpan('ok');\n }\n\n return result;\n } catch (error) {\n if (!spanEnded) {\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n endSpan('error');\n }\n\n throw error;\n }\n}\n\n/**\n * Resolve parent context and links based on context mode.\n *\n * RabbitMQ context mode differs from Kafka:\n * - `inherit` mode always uses extracted context as parent (messaging continues producer trace)\n * - This matches the expectation that RabbitMQ messages carry trace context\n */\nfunction resolveContextAndLinks(\n contextMode: ContextMode,\n extractedSpanContext: SpanContext | undefined,\n additionalLinks: SpanLink[],\n): {\n parentContext: ReturnType<typeof context.active>;\n spanLinks: SpanLink[];\n} {\n const activeContext = context.active();\n const hasValidExtracted = isValidSpanContext(extractedSpanContext);\n\n const spanLinks: SpanLink[] = [...additionalLinks];\n\n switch (contextMode) {\n case 'inherit': {\n // In inherit mode, extracted context always wins as parent\n // This is the key difference from Kafka - messaging should continue producer trace\n if (hasValidExtracted) {\n const extractedParentCtx = trace.setSpanContext(\n activeContext,\n extractedSpanContext,\n );\n return { parentContext: extractedParentCtx, spanLinks };\n }\n // No extracted context: use current active context\n return { parentContext: activeContext, spanLinks };\n }\n\n case 'link': {\n // Parent to current context (active span or root)\n // Link to extracted if valid\n if (hasValidExtracted) {\n spanLinks.push({ context: extractedSpanContext });\n }\n return { parentContext: activeContext, spanLinks };\n }\n\n case 'none': {\n // Parent to current context, no links to extracted\n return { parentContext: activeContext, spanLinks };\n }\n\n default: {\n // TypeScript exhaustive check\n const exhaustive: never = contextMode;\n throw new Error(`Unknown context mode: ${exhaustive}`);\n }\n }\n}\n\n/**\n * Set standard RabbitMQ messaging attributes on a span.\n */\nfunction setMessagingAttributes(\n span: Span,\n attrs: {\n queue?: string;\n exchange?: string;\n routingKey?: string;\n messageId?: string;\n correlationId?: string;\n consumerTag?: string;\n },\n): void {\n const { queue, exchange, routingKey, messageId, correlationId, consumerTag } =\n attrs;\n\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'rabbitmq');\n span.setAttribute(SEMATTRS_MESSAGING_OPERATION_NAME, 'receive');\n\n if (queue) {\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, queue);\n }\n\n if (exchange) {\n span.setAttribute(\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_EXCHANGE,\n exchange,\n );\n }\n\n if (routingKey) {\n span.setAttribute(\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY,\n routingKey,\n );\n }\n\n if (messageId) {\n span.setAttribute(SEMATTRS_MESSAGING_MESSAGE_ID, messageId);\n }\n\n if (correlationId) {\n span.setAttribute(\n SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID,\n correlationId,\n );\n }\n\n if (consumerTag) {\n span.setAttribute(SEMATTRS_MESSAGING_CONSUMER_ID, consumerTag);\n }\n}\n","/**\n * Publish span wrapper for RabbitMQ message publishing.\n *\n * Creates PRODUCER spans with proper messaging semantics,\n * allowing trace context to be injected inside the span.\n *\n * @example Basic publish span\n * ```typescript\n * import { withPublishSpan, injectTraceHeaders } from 'autotel-plugins/rabbitmq';\n *\n * await withPublishSpan({\n * name: 'order.publish',\n * exchange: 'orders',\n * routingKey: 'order.created',\n * messageId: 'msg-123',\n * }, async (span) => {\n * // Inject headers inside the PRODUCER span context\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * channel.publish('orders', 'order.created', content, { headers });\n * });\n * ```\n */\n\nimport { otelTrace as trace, context, SpanKind, SpanStatusCode } from 'autotel';\nimport type { PublishDescriptor, PublishSpanCallback } from './types';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_OPERATION_NAME,\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY,\n SEMATTRS_MESSAGING_MESSAGE_ID,\n SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID,\n} from '../common/constants';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/rabbitmq';\n\n/**\n * Create a publish span for RabbitMQ message publishing.\n *\n * This creates a PRODUCER span with proper messaging attributes.\n * The callback runs within the span's context, so you can call\n * `injectTraceHeaders()` inside it to get the correct trace context.\n *\n * @param descriptor - Publish span configuration\n * @param fn - Async callback to execute within the span\n * @returns Promise resolving to callback result\n * @throws Error if span creation fails or callback throws\n *\n * @example\n * ```typescript\n * await withPublishSpan({\n * name: 'payment.publish',\n * exchange: 'payments',\n * routingKey: 'payment.processed',\n * correlationId: paymentId,\n * }, async (span) => {\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * channel.publish('payments', 'payment.processed', content, { headers });\n * });\n * ```\n *\n * @example Using default exchange\n * ```typescript\n * await withPublishSpan({\n * name: 'direct.send',\n * routingKey: 'queue-name', // Queue name when using default exchange\n * }, async (span) => {\n * const headers = injectTraceHeaders({});\n * channel.sendToQueue('queue-name', content, { headers });\n * });\n * ```\n */\nexport async function withPublishSpan<T>(\n descriptor: PublishDescriptor,\n fn: PublishSpanCallback<T>,\n): Promise<T> {\n const {\n name,\n exchange = 'amq.default',\n routingKey,\n messageId,\n correlationId,\n system = 'rabbitmq',\n } = descriptor;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n // Create PRODUCER span\n const span = tracer.startSpan(name, {\n kind: SpanKind.PRODUCER,\n });\n\n // Set messaging attributes\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, system);\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, exchange);\n span.setAttribute(SEMATTRS_MESSAGING_OPERATION_NAME, 'publish');\n span.setAttribute(\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY,\n routingKey,\n );\n\n if (messageId) {\n span.setAttribute(SEMATTRS_MESSAGING_MESSAGE_ID, messageId);\n }\n\n if (correlationId) {\n span.setAttribute(\n SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID,\n correlationId,\n );\n }\n\n // Execute callback within span context\n const spanContext = trace.setSpan(context.active(), span);\n\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span);\n });\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n\n throw error;\n }\n}\n","/**\n * Batch lineage utilities for fan-in trace correlation.\n *\n * When processing batches of messages (e.g., aggregating multiple orders),\n * this utility extracts and correlates trace IDs from all messages\n * to create meaningful span links.\n *\n * This is a minimal implementation focused on SpanLinks only.\n * No body inspection, no complex inference.\n */\n\nimport { otelTrace as trace, type SpanContext, type SpanLink } from 'autotel';\nimport type {\n BatchItem,\n BatchLineageOptions,\n BatchLineageResult,\n ExtractedContext,\n} from './types';\nimport { normalizeHeaders, extractTraceContext } from './headers';\n\nconst DEFAULT_MAX_LINKS = 128;\n\n/**\n * Check if a span context is valid for creating links.\n * Must have both traceId and spanId.\n */\nfunction isValidSpanContext(\n spanContext: SpanContext | undefined,\n): spanContext is SpanContext {\n return !!(\n spanContext &&\n spanContext.traceId &&\n spanContext.spanId &&\n trace.isSpanContextValid(spanContext)\n );\n}\n\n/**\n * Synchronous hash using djb2 algorithm.\n */\nfunction hashTraceIdsSync(traceIds: string[]): string {\n const input = traceIds.join('|');\n\n // Simple djb2-style hash\n let hash = 5381;\n for (let i = 0; i < input.length; i++) {\n // eslint-disable-next-line unicorn/prefer-code-point\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n\n // Convert to unsigned 32-bit, then hex, pad to 16 chars\n return (hash >>> 0).toString(16).padStart(16, '0');\n}\n\n/**\n * Extract batch lineage from a collection of RabbitMQ messages.\n *\n * For each message with headers:\n * 1. Extract SpanContext using OTel propagators\n * 2. Filter to valid SpanContexts (must have traceId + spanId)\n * 3. Deduplicate by traceId\n * 4. Sort trace IDs alphabetically for deterministic hash\n * 5. Create hash of sorted trace IDs\n * 6. Create SpanLinks from valid contexts (capped at maxLinks)\n *\n * @param items - Array of items with optional headers\n * @param options - Extraction options\n * @returns Batch lineage result with links and metadata\n *\n * @example Basic batch lineage\n * ```typescript\n * import { extractBatchLineage, withConsumeSpan } from 'autotel-plugins/rabbitmq';\n *\n * // Aggregate multiple messages\n * const lineage = extractBatchLineage(\n * messages.map(m => ({ headers: m.properties.headers }))\n * );\n *\n * await withConsumeSpan({\n * name: 'batch.aggregate',\n * headers: {},\n * contextMode: 'none',\n * links: lineage.links,\n * queue: 'aggregator',\n * }, async (span) => {\n * span.setAttribute('linked_trace_id_count', lineage.linked_trace_id_count);\n * span.setAttribute('linked_trace_id_hash', lineage.linked_trace_id_hash);\n * await processBatch(messages);\n * });\n * ```\n */\nexport function extractBatchLineage(\n items: BatchItem[],\n options: BatchLineageOptions = {},\n): BatchLineageResult {\n const { includeTraceIds = false, maxLinks = DEFAULT_MAX_LINKS } = options;\n\n // Extract valid span contexts from items\n const extractedContexts: ExtractedContext[] = [];\n const seenTraceIds = new Set<string>();\n\n for (const item of items) {\n const normalizedHeaders = normalizeHeaders(item.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const spanContext = trace.getSpanContext(extractedCtx);\n\n // Check valid span context and deduplicate by traceId\n if (\n isValidSpanContext(spanContext) &&\n !seenTraceIds.has(spanContext.traceId)\n ) {\n seenTraceIds.add(spanContext.traceId);\n extractedContexts.push({\n traceId: spanContext.traceId,\n spanContext,\n });\n }\n }\n\n // Sort by traceId for deterministic hash\n extractedContexts.sort((a, b) => a.traceId.localeCompare(b.traceId));\n\n const traceIds = extractedContexts.map((ec) => ec.traceId);\n\n // Create links (capped at maxLinks)\n const links: SpanLink[] = extractedContexts\n .slice(0, maxLinks)\n .map((ec) => ({ context: ec.spanContext }));\n\n // Compute hash\n const hash =\n traceIds.length > 0 ? hashTraceIdsSync(traceIds) : '0000000000000000';\n\n return {\n linked_trace_id_count: traceIds.length,\n linked_trace_id_hash: hash,\n links,\n ...(includeTraceIds && { trace_ids: traceIds }),\n };\n}\n","/**\n * Ack tracking utilities for RabbitMQ message processing.\n *\n * Provides helpers to record ack/nack/reject outcomes on spans\n * when not using deferred mode in withConsumeSpan.\n */\n\nimport type { Span } from 'autotel';\nimport {\n SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT,\n SEMATTRS_MESSAGING_RABBITMQ_REQUEUE,\n} from '../common/constants';\n\n/**\n * Ack result type for explicit recording.\n */\nexport type AckResult = 'ack' | 'nack' | 'reject';\n\n/**\n * Options for recording ack results.\n */\nexport interface RecordAckOptions {\n /**\n * Whether the message will be requeued (for nack/reject).\n */\n requeue?: boolean;\n}\n\n/**\n * Record an ack result on a span.\n *\n * Use this when not using deferred mode but still want to track\n * ack/nack/reject outcomes as span attributes.\n *\n * @param span - The span to record on\n * @param result - The ack result ('ack', 'nack', or 'reject')\n * @param options - Additional options\n *\n * @example\n * ```typescript\n * import { withConsumeSpan, recordAckResult } from 'autotel-plugins/rabbitmq';\n *\n * await withConsumeSpan({\n * name: 'order.process',\n * headers: msg.properties.headers,\n * queue: 'orders',\n * }, async (span) => {\n * try {\n * await processOrder(msg);\n * recordAckResult(span, 'ack');\n * channel.ack(msg);\n * } catch (error) {\n * recordAckResult(span, 'nack', { requeue: true });\n * channel.nack(msg, false, true);\n * throw error;\n * }\n * });\n * ```\n */\nexport function recordAckResult(\n span: Span,\n result: AckResult,\n options?: RecordAckOptions,\n): void {\n span.setAttribute(SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT, result);\n\n if (options?.requeue !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_RABBITMQ_REQUEUE, options.requeue);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/common/constants.ts","../src/bigquery/index.ts","../src/kafka/headers.ts","../src/kafka/correlation.ts","../src/kafka/processing-span.ts","../src/kafka/producer-span.ts","../src/kafka/batch-lineage.ts","../src/kafka/batch-consumer.ts","../src/kafka/stream-processor.ts","../src/kafka/consumer-metrics.ts","../src/kafka/stream-events.ts","../src/rabbitmq/headers.ts","../src/rabbitmq/correlation.ts","../src/rabbitmq/processing-span.ts","../src/rabbitmq/publish-span.ts","../src/rabbitmq/batch-lineage.ts","../src/rabbitmq/ack-tracking.ts"],"names":["trace","propagation","DEFAULT_TRACER_NAME","SpanKind","context","SpanStatusCode","isValidSpanContext","otelMetrics","normalizeHeaders","caseInsensitiveGetter","extractTraceContext","ROOT_CONTEXT","headerSetter","deriveCorrelationId","extractCorrelationId","injectTraceHeaders","resolveContextAndLinks","setMessagingAttributes","DEFAULT_MAX_LINKS","hashTraceIdsSync","extractBatchLineage"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * OpenTelemetry semantic conventions for database operations.\n * These constants are shared across all plugins.\n */\n\n// Common database attributes\nexport const SEMATTRS_DB_SYSTEM = 'db.system' as const;\nexport const SEMATTRS_DB_SYSTEM_NAME = 'db.system.name' as const;\nexport const SEMATTRS_DB_OPERATION = 'db.operation' as const;\nexport const SEMATTRS_DB_STATEMENT = 'db.statement' as const;\nexport const SEMATTRS_DB_NAME = 'db.name' as const;\nexport const SEMATTRS_DB_NAMESPACE = 'db.namespace' as const;\nexport const SEMATTRS_DB_COLLECTION_NAME = 'db.collection.name' as const;\nexport const SEMATTRS_DB_OPERATION_NAME = 'db.operation.name' as const;\nexport const SEMATTRS_DB_QUERY_TEXT = 'db.query.text' as const;\nexport const SEMATTRS_DB_QUERY_SUMMARY = 'db.query.summary' as const;\n\n// MongoDB-specific attributes\nexport const SEMATTRS_DB_MONGODB_COLLECTION = 'db.mongodb.collection' as const;\n\n// Network attributes\nexport const SEMATTRS_NET_PEER_NAME = 'net.peer.name' as const;\nexport const SEMATTRS_NET_PEER_PORT = 'net.peer.port' as const;\n\n// Messaging attributes (Kafka, etc.)\nexport const SEMATTRS_MESSAGING_SYSTEM = 'messaging.system' as const;\nexport const SEMATTRS_MESSAGING_DESTINATION_NAME =\n 'messaging.destination.name' as const;\nexport const SEMATTRS_MESSAGING_OPERATION = 'messaging.operation' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP =\n 'messaging.kafka.consumer.group' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_PARTITION =\n 'messaging.kafka.partition' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_OFFSET =\n 'messaging.kafka.offset' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY =\n 'messaging.kafka.message.key' as const;\n\n// Batch lineage attributes\nexport const SEMATTRS_LINKED_TRACE_ID_COUNT = 'linked_trace_id_count' as const;\nexport const SEMATTRS_LINKED_TRACE_ID_HASH = 'linked_trace_id_hash' as const;\n\n// Correlation ID header name\nexport const CORRELATION_ID_HEADER = 'x-correlation-id' as const;\n\n// BigQuery-specific attributes (namespaced under gcp.bigquery per OTel spec)\nexport const SEMATTRS_GCP_BIGQUERY_JOB_ID = 'gcp.bigquery.job.id' as const;\nexport const SEMATTRS_GCP_BIGQUERY_JOB_LOCATION =\n 'gcp.bigquery.job.location' as const;\nexport const SEMATTRS_GCP_BIGQUERY_PROJECT_ID =\n 'gcp.bigquery.project.id' as const;\nexport const SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE =\n 'gcp.bigquery.destination.table' as const;\nexport const SEMATTRS_GCP_BIGQUERY_SOURCE_TABLES =\n 'gcp.bigquery.source.tables' as const;\nexport const SEMATTRS_GCP_BIGQUERY_STATEMENT_TYPE =\n 'gcp.bigquery.statement_type' as const;\nexport const SEMATTRS_GCP_BIGQUERY_QUERY_HASH =\n 'gcp.bigquery.query.hash' as const;\nexport const SEMATTRS_GCP_BIGQUERY_ROWS_AFFECTED =\n 'gcp.bigquery.rows.affected' as const;\nexport const SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED =\n 'gcp.bigquery.rows.returned' as const;\nexport const SEMATTRS_GCP_BIGQUERY_SCHEMA_FIELDS =\n 'gcp.bigquery.schema.fields' as const;\n\n// RabbitMQ-specific attributes (aligned with OTel messaging semantic conventions)\nexport const SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY =\n 'messaging.rabbitmq.destination.routing_key' as const;\nexport const SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_EXCHANGE =\n 'messaging.rabbitmq.destination.exchange' as const;\nexport const SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT =\n 'messaging.rabbitmq.ack_result' as const;\nexport const SEMATTRS_MESSAGING_RABBITMQ_REQUEUE =\n 'messaging.rabbitmq.requeue' as const;\n\n// Messaging attributes (shared across messaging systems)\nexport const SEMATTRS_MESSAGING_MESSAGE_ID = 'messaging.message.id' as const;\nexport const SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID =\n 'messaging.message.conversation_id' as const;\nexport const SEMATTRS_MESSAGING_CONSUMER_ID = 'messaging.consumer.id' as const;\nexport const SEMATTRS_MESSAGING_OPERATION_NAME =\n 'messaging.operation.name' as const;\n\n// Kafka batch consumer attributes\nexport const SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT =\n 'messaging.batch.message_count' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET =\n 'messaging.kafka.batch.first_offset' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET =\n 'messaging.kafka.batch.last_offset' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED =\n 'messaging.kafka.batch.messages_processed' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED =\n 'messaging.kafka.batch.messages_failed' as const;\nexport const SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS =\n 'messaging.kafka.batch.processing_time_ms' as const;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n// Note: `any` is only used for dynamic method wrapping on runtime objects.\n// Type-safe interfaces are used for all public APIs.\n// BigQuery is a devDependency so we type-check against the real API; consumers use the peer.\n\nimport type { BigQuery, BigQueryOptions } from '@google-cloud/bigquery';\nimport { SpanKind, otelTrace as trace, type Span, type Tracer } from 'autotel';\nimport {\n SEMATTRS_DB_SYSTEM_NAME,\n SEMATTRS_DB_OPERATION_NAME,\n SEMATTRS_DB_QUERY_TEXT,\n SEMATTRS_DB_QUERY_SUMMARY,\n SEMATTRS_DB_NAMESPACE,\n SEMATTRS_DB_COLLECTION_NAME,\n SEMATTRS_GCP_BIGQUERY_JOB_ID,\n SEMATTRS_GCP_BIGQUERY_JOB_LOCATION,\n SEMATTRS_GCP_BIGQUERY_PROJECT_ID,\n SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE,\n SEMATTRS_GCP_BIGQUERY_QUERY_HASH,\n SEMATTRS_GCP_BIGQUERY_ROWS_AFFECTED,\n SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED,\n} from '../common/constants';\nimport { runWithSpan, finalizeSpan } from 'autotel/trace-helpers';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/bigquery';\nconst DEFAULT_DB_SYSTEM_NAME = 'gcp.bigquery';\nconst INSTRUMENTED_FLAG = '__autotelBigQueryInstrumented' as const;\nconst PROTOTYPE_INSTRUMENTED_FLAG =\n '__autotelBigQueryPrototypeInstrumented' as const;\nconst CONFIG_STORAGE_KEY = '__autotelBigQueryConfig' as const;\nconst TRACER_STORAGE_KEY = '__autotelBigQueryTracer' as const;\n\n/**\n * Helper to get config from a BigQuery instance.\n * For Table/Dataset methods, traverses up to find the BigQuery parent.\n */\nfunction getInstanceConfig(\n instance: any,\n): BigQueryInstrumentationConfig | undefined {\n // Direct config on BigQuery instance\n if (instance?.[CONFIG_STORAGE_KEY]) {\n return instance[CONFIG_STORAGE_KEY];\n }\n // For Table: this.dataset.parent is the BigQuery instance\n if (instance?.dataset?.parent?.[CONFIG_STORAGE_KEY]) {\n return instance.dataset.parent[CONFIG_STORAGE_KEY];\n }\n // For Dataset: this.parent is the BigQuery instance\n if (instance?.parent?.[CONFIG_STORAGE_KEY]) {\n return instance.parent[CONFIG_STORAGE_KEY];\n }\n // For Job: this.parent is the BigQuery instance\n if (instance?.parent?.[CONFIG_STORAGE_KEY]) {\n return instance.parent[CONFIG_STORAGE_KEY];\n }\n return undefined;\n}\n\n/**\n * Helper to get tracer from a BigQuery instance.\n * For Table/Dataset methods, traverses up to find the BigQuery parent.\n */\nfunction getInstanceTracer(instance: any): Tracer | undefined {\n // Direct tracer on BigQuery instance\n if (instance?.[TRACER_STORAGE_KEY]) {\n return instance[TRACER_STORAGE_KEY];\n }\n // For Table: this.dataset.parent is the BigQuery instance\n if (instance?.dataset?.parent?.[TRACER_STORAGE_KEY]) {\n return instance.dataset.parent[TRACER_STORAGE_KEY];\n }\n // For Dataset: this.parent is the BigQuery instance\n if (instance?.parent?.[TRACER_STORAGE_KEY]) {\n return instance.parent[TRACER_STORAGE_KEY];\n }\n // For Job: this.parent is the BigQuery instance\n if (instance?.parent?.[TRACER_STORAGE_KEY]) {\n return instance.parent[TRACER_STORAGE_KEY];\n }\n return undefined;\n}\n\n/**\n * Plugin-only options for BigQuery instrumentation (not part of official BigQueryOptions).\n */\nexport interface BigQueryInstrumentationPluginOptions {\n /**\n * Custom tracer name (default: \"autotel-plugins/bigquery\").\n */\n tracerName?: string;\n\n /**\n * How to handle query text in spans:\n * - 'never': Don't capture any query text\n * - 'summary': Only capture low-cardinality summary (default)\n * - 'sanitized': Sanitize by replacing literals with ?\n * - 'raw': Capture raw query text (opt-in, not recommended for production)\n * @default 'summary'\n */\n captureQueryText?: 'never' | 'summary' | 'sanitized' | 'raw';\n\n /**\n * Maximum length for captured query text. Queries longer than this will be truncated.\n * @default 1000\n */\n maxQueryTextLength?: number;\n\n /**\n * Whether to include a hash of the query for exact matching without exposing text.\n * @default true\n */\n includeQueryHash?: boolean;\n\n /**\n * Whether to instrument admin operations (dataset/table create, delete, metadata).\n * @default false\n */\n instrumentAdminOps?: boolean;\n\n /**\n * Whether to instrument BigQuery ML (model) operations.\n * @default false\n */\n instrumentBqmlOps?: boolean;\n\n /**\n * Whether to instrument routine (stored procedure/function) operations.\n * @default false\n */\n instrumentRoutineOps?: boolean;\n}\n\n/**\n * Configuration options for BigQuery instrumentation.\n * Uses official BigQueryOptions for projectId and location (same semantics as the BigQuery constructor).\n * All other fields are plugin-only options.\n */\nexport type BigQueryInstrumentationConfig = Pick<\n BigQueryOptions,\n 'projectId' | 'location'\n> &\n BigQueryInstrumentationPluginOptions;\n\n/**\n * Creates a simple hash of a string for query identification without exposing text.\n */\nfunction hashQuery(query: string): string {\n let hash = 0;\n for (let i = 0; i < query.length; i++) {\n const char = query.codePointAt(i) ?? 0;\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * Extracts the operation type (SELECT, INSERT, etc.) from SQL query.\n */\nfunction extractOperationType(query: string): string | undefined {\n const trimmed = query.trimStart();\n const match = /^(?<op>\\w+)/iu.exec(trimmed);\n return match?.groups?.op?.toUpperCase();\n}\n\n/**\n * Creates a low-cardinality summary of a query.\n * Example: \"SELECT FROM users WHERE...\" or \"INSERT INTO orders\"\n */\nfunction createQuerySummary(query: string): string {\n const operation = extractOperationType(query);\n if (!operation) {\n return 'UNKNOWN';\n }\n\n // For SELECT/INSERT/UPDATE/DELETE, try to extract table name\n const patterns: Record<string, RegExp> = {\n SELECT: /FROM\\s+(?<table>[\\w.]+)/iu,\n INSERT: /INTO\\s+(?<table>[\\w.]+)/iu,\n UPDATE: /UPDATE\\s+(?<table>[\\w.]+)/iu,\n DELETE: /FROM\\s+(?<table>[\\w.]+)/iu,\n };\n\n const pattern = patterns[operation];\n if (pattern) {\n const match = pattern.exec(query);\n const table = match?.groups?.table;\n if (table) {\n return `${operation} ${table}`;\n }\n }\n\n return operation;\n}\n\n/**\n * Sanitizes a query by replacing literal values with ? placeholders.\n * Handles strings, numbers, and dates.\n */\nfunction sanitizeQuery(query: string): string {\n // Replace string literals: '...' or \"...\"\n let sanitized = query.replaceAll(/'(?:[^'\\\\]|\\\\.)*'/gu, \"'?'\");\n sanitized = sanitized.replaceAll(/\"(?:[^\"\\\\]|\\\\.)*\"/gu, '\"?\"');\n\n // Replace numeric literals (but preserve table names like table_123)\n // Only replace standalone numbers\n sanitized = sanitized.replaceAll(/\\b\\d+\\.?\\d*\\b/gu, '?');\n\n // Replace boolean literals\n sanitized = sanitized.replaceAll(/\\b(?:true|false)\\b/giu, '?');\n\n // Replace NULL\n sanitized = sanitized.replaceAll(/\\bNULL\\b/giu, '?');\n\n return sanitized;\n}\n\n/**\n * Truncates text to max length with ellipsis.\n */\nfunction truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n return `${text.slice(0, Math.max(0, maxLength - 3))}...`;\n}\n\n/**\n * Extracts project ID from BigQuery instance.\n */\nfunction extractProjectId(bigquery: any): string | undefined {\n try {\n return bigquery.projectId || bigquery.options?.projectId;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Extracts location from BigQuery instance or query options.\n */\nfunction extractLocation(bigquery: any, options?: any): string | undefined {\n try {\n return options?.location || bigquery.location || bigquery.options?.location;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Extracts dataset and table identifiers from various BigQuery objects.\n */\nfunction extractTableReference(obj: any): {\n datasetId?: string;\n tableId?: string;\n projectId?: string;\n} {\n try {\n // Direct properties\n if (obj.dataset?.id || obj.parent?.id) {\n return {\n projectId: obj.dataset?.parent?.projectId || obj.parent?.projectId,\n datasetId: obj.dataset?.id || obj.parent?.datasetId,\n tableId: obj.id,\n };\n }\n\n // From metadata\n if (obj.metadata?.tableReference) {\n return obj.metadata.tableReference;\n }\n\n return {};\n } catch {\n return {};\n }\n}\n\n/**\n * Creates a span for a BigQuery operation.\n */\nfunction createSpan(\n tracer: Tracer,\n operationName: string,\n target?: string,\n projectId?: string,\n config: BigQueryInstrumentationConfig = {},\n): Span {\n const spanName = target ? `${operationName} ${target}` : operationName;\n\n const attributes: Record<string, any> = {\n [SEMATTRS_DB_SYSTEM_NAME]: DEFAULT_DB_SYSTEM_NAME,\n [SEMATTRS_DB_OPERATION_NAME]: operationName,\n };\n\n if (projectId || config.projectId) {\n attributes[SEMATTRS_GCP_BIGQUERY_PROJECT_ID] =\n projectId || config.projectId;\n }\n\n if (config.location) {\n attributes[SEMATTRS_GCP_BIGQUERY_JOB_LOCATION] = config.location;\n }\n\n return tracer.startSpan(spanName, { kind: SpanKind.CLIENT, attributes });\n}\n\n/**\n * Instruments BigQuery.query() method.\n */\nfunction instrumentQueryMethod(BigQuery: any): void {\n const originalQuery = BigQuery.prototype.query;\n if (typeof originalQuery !== 'function') {\n return;\n }\n\n BigQuery.prototype.query = function instrumentedQuery(\n this: any,\n query: string | { query: string; [key: string]: any },\n options?: any,\n callback?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n // Fall back to original if no config/tracer found\n return originalQuery.call(this, query, options, callback);\n }\n\n const queryText = typeof query === 'string' ? query : query.query;\n const projectId = extractProjectId(this);\n const location = extractLocation(this, options);\n\n const operation = queryText ? extractOperationType(queryText) : 'QUERY';\n const summary = queryText ? createQuerySummary(queryText) : 'QUERY';\n\n const span = createSpan(\n tracer,\n operation || 'QUERY',\n summary,\n projectId,\n config,\n );\n\n // Set location if available\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n // Set query summary (always)\n span.setAttribute(SEMATTRS_DB_QUERY_SUMMARY, summary);\n\n // Set query text based on config\n if (config.captureQueryText !== 'never' && queryText) {\n if (config.captureQueryText === 'raw') {\n const truncated = truncateText(\n queryText,\n config.maxQueryTextLength || 1000,\n );\n span.setAttribute(SEMATTRS_DB_QUERY_TEXT, truncated);\n } else if (config.captureQueryText === 'sanitized') {\n const sanitized = sanitizeQuery(queryText);\n const truncated = truncateText(\n sanitized,\n config.maxQueryTextLength || 1000,\n );\n span.setAttribute(SEMATTRS_DB_QUERY_TEXT, truncated);\n }\n // 'summary' mode only includes summary, no raw text\n }\n\n // Set query hash if enabled\n if (config.includeQueryHash !== false && queryText) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_QUERY_HASH, hashQuery(queryText));\n }\n\n // Set destination table if specified in options\n if (options?.destination) {\n const dest = extractTableReference(options.destination);\n if (dest.tableId) {\n const destTable = dest.datasetId\n ? `${dest.datasetId}.${dest.tableId}`\n : dest.tableId;\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE, destTable);\n }\n }\n\n // Handle callback-style API\n if (typeof callback === 'function') {\n const wrappedCallback = (err: any, ...args: any[]) => {\n if (err) {\n finalizeSpan(\n span,\n err instanceof Error ? err : new Error(String(err)),\n );\n } else {\n // Record row count and job ID if available in response\n const [rows, response] = args;\n if (Array.isArray(rows)) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED, rows.length);\n }\n if (response?.jobReference?.jobId) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_JOB_ID,\n response.jobReference.jobId,\n );\n }\n finalizeSpan(span);\n }\n return callback(err, ...args);\n };\n return originalQuery.call(this, query, options, wrappedCallback);\n }\n\n // Handle Promise-style API\n return runWithSpan(span, () => {\n try {\n const result = originalQuery.call(this, query, options);\n\n return Promise.resolve(result)\n .then(([rows, response]: [any[], any]) => {\n // Record row count\n if (Array.isArray(rows)) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED,\n rows.length,\n );\n }\n\n // Extract job ID from response if available\n if (response?.jobReference?.jobId) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_JOB_ID,\n response.jobReference.jobId,\n );\n }\n\n finalizeSpan(span);\n return [rows, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments BigQuery.createQueryJob() method.\n */\nfunction instrumentCreateQueryJob(BigQuery: any): void {\n const originalCreateQueryJob = BigQuery.prototype.createQueryJob;\n if (typeof originalCreateQueryJob !== 'function') {\n return;\n }\n\n BigQuery.prototype.createQueryJob = function instrumentedCreateQueryJob(\n this: any,\n options: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalCreateQueryJob.call(this, options);\n }\n\n const queryText = typeof options === 'string' ? options : options.query;\n const projectId = extractProjectId(this);\n const location = extractLocation(this, options);\n\n const operation = queryText ? extractOperationType(queryText) : 'QUERY';\n const summary = queryText ? createQuerySummary(queryText) : 'QUERY';\n\n const span = createSpan(\n tracer,\n `${operation || 'QUERY'}_JOB`,\n summary,\n projectId,\n config,\n );\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n span.setAttribute(SEMATTRS_DB_QUERY_SUMMARY, summary);\n\n if (config.captureQueryText !== 'never' && queryText) {\n if (config.captureQueryText === 'raw') {\n const truncated = truncateText(\n queryText,\n config.maxQueryTextLength || 1000,\n );\n span.setAttribute(SEMATTRS_DB_QUERY_TEXT, truncated);\n } else if (config.captureQueryText === 'sanitized') {\n const sanitized = sanitizeQuery(queryText);\n const truncated = truncateText(\n sanitized,\n config.maxQueryTextLength || 1000,\n );\n span.setAttribute(SEMATTRS_DB_QUERY_TEXT, truncated);\n }\n }\n\n if (config.includeQueryHash !== false && queryText) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_QUERY_HASH, hashQuery(queryText));\n }\n\n if (options?.destination) {\n const dest = extractTableReference(options.destination);\n if (dest.tableId) {\n const destTable = dest.datasetId\n ? `${dest.datasetId}.${dest.tableId}`\n : dest.tableId;\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE, destTable);\n }\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreateQueryJob.call(this, options);\n\n return Promise.resolve(result)\n .then(([job, response]: [any, any]) => {\n // Record job ID\n if (job?.id) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, job.id);\n } else if (response?.jobReference?.jobId) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_JOB_ID,\n response.jobReference.jobId,\n );\n }\n\n finalizeSpan(span);\n return [job, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.insert() method.\n */\nfunction instrumentTableInsert(Table: any): void {\n const originalInsert = Table.prototype.insert;\n if (typeof originalInsert !== 'function') {\n return;\n }\n\n Table.prototype.insert = function instrumentedInsert(\n this: any,\n rows: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalInsert.call(this, rows, options);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n options,\n );\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'INSERT', target, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n // Record row count\n const rowCount = Array.isArray(rows) ? rows.length : 1;\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_ROWS_AFFECTED, rowCount);\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalInsert.call(this, rows, options);\n\n return Promise.resolve(result)\n .then((response: any) => {\n // Check for insert errors\n if (response?.insertErrors?.length > 0) {\n span.setAttribute(\n 'gcp.bigquery.insert.errors',\n response.insertErrors.length,\n );\n }\n\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.getRows() method.\n */\nfunction instrumentTableGetRows(Table: any): void {\n const originalGetRows = Table.prototype.getRows;\n if (typeof originalGetRows !== 'function') {\n return;\n }\n\n Table.prototype.getRows = function instrumentedGetRows(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalGetRows.call(this, options);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n options,\n );\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'SELECT', target, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalGetRows.call(this, options);\n\n return Promise.resolve(result)\n .then(([rows, nextQuery, apiResponse]: [any[], any, any]) => {\n if (Array.isArray(rows)) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED,\n rows.length,\n );\n }\n finalizeSpan(span);\n return [rows, nextQuery, apiResponse];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.createLoadJob() method.\n */\nfunction instrumentTableCreateLoadJob(Table: any): void {\n const originalCreateLoadJob = Table.prototype.createLoadJob;\n if (typeof originalCreateLoadJob !== 'function') {\n return;\n }\n\n Table.prototype.createLoadJob = function instrumentedCreateLoadJob(\n this: any,\n source: any,\n metadata?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalCreateLoadJob.call(this, source, metadata);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n metadata,\n );\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'LOAD', target, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n // Record source format if available\n if (metadata?.sourceFormat) {\n span.setAttribute('gcp.bigquery.source.format', metadata.sourceFormat);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreateLoadJob.call(this, source, metadata);\n\n return Promise.resolve(result)\n .then(([job, response]: [any, any]) => {\n if (job?.id) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, job.id);\n }\n finalizeSpan(span);\n return [job, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.createCopyJob() method.\n */\nfunction instrumentTableCreateCopyJob(Table: any): void {\n const originalCreateCopyJob = Table.prototype.createCopyJob;\n if (typeof originalCreateCopyJob !== 'function') {\n return;\n }\n\n Table.prototype.createCopyJob = function instrumentedCreateCopyJob(\n this: any,\n destination: any,\n metadata?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalCreateCopyJob.call(this, destination, metadata);\n }\n\n const sourceRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n metadata,\n );\n\n const source = sourceRef.tableId\n ? sourceRef.datasetId\n ? `${sourceRef.datasetId}.${sourceRef.tableId}`\n : sourceRef.tableId\n : 'unknown';\n\n const span = createSpan(tracer, 'COPY', source, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n // Record destination\n if (destination) {\n const destRef = extractTableReference(destination);\n const destTable = destRef.tableId\n ? destRef.datasetId\n ? `${destRef.datasetId}.${destRef.tableId}`\n : destRef.tableId\n : undefined;\n if (destTable) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_DESTINATION_TABLE, destTable);\n }\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreateCopyJob.call(this, destination, metadata);\n\n return Promise.resolve(result)\n .then(([job, response]: [any, any]) => {\n if (job?.id) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, job.id);\n }\n finalizeSpan(span);\n return [job, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.createExtractJob() method.\n */\nfunction instrumentTableCreateExtractJob(Table: any): void {\n const originalCreateExtractJob = Table.prototype.createExtractJob;\n if (typeof originalCreateExtractJob !== 'function') {\n return;\n }\n\n Table.prototype.createExtractJob = function instrumentedCreateExtractJob(\n this: any,\n destination: any,\n metadata?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalCreateExtractJob.call(this, destination, metadata);\n }\n\n const sourceRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n const location = extractLocation(\n this.dataset?.parent || this.parent,\n metadata,\n );\n\n const source = sourceRef.tableId\n ? sourceRef.datasetId\n ? `${sourceRef.datasetId}.${sourceRef.tableId}`\n : sourceRef.tableId\n : 'unknown';\n\n const span = createSpan(tracer, 'EXTRACT', source, projectId, config);\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (sourceRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, sourceRef.datasetId);\n }\n if (sourceRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, sourceRef.tableId);\n }\n\n // Record destination URI\n if (typeof destination === 'string') {\n span.setAttribute('gcp.bigquery.destination.uri', destination);\n } else if (Array.isArray(destination) && destination.length > 0) {\n span.setAttribute('gcp.bigquery.destination.uri', destination[0]);\n }\n\n // Record format\n const format = metadata?.destinationFormat || metadata?.format;\n if (format) {\n span.setAttribute('gcp.bigquery.destination.format', format);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreateExtractJob.call(\n this,\n destination,\n metadata,\n );\n\n return Promise.resolve(result)\n .then(([job, response]: [any, any]) => {\n if (job?.id) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, job.id);\n }\n finalizeSpan(span);\n return [job, response];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Job.getQueryResults() method.\n */\nfunction instrumentJobGetQueryResults(Job: any): void {\n const originalGetQueryResults = Job.prototype.getQueryResults;\n if (typeof originalGetQueryResults !== 'function') {\n return;\n }\n\n Job.prototype.getQueryResults = function instrumentedGetQueryResults(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer) {\n return originalGetQueryResults.call(this, options);\n }\n\n const jobId = this.id || this.metadata?.jobReference?.jobId;\n const projectId = this.parent?.projectId || this.projectId;\n const location = this.location || options?.location;\n\n const span = createSpan(\n tracer,\n 'GET_QUERY_RESULTS',\n undefined,\n projectId,\n config,\n );\n\n if (jobId) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_ID, jobId);\n }\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalGetQueryResults.call(this, options);\n\n return Promise.resolve(result)\n .then(([rows, nextQuery, apiResponse]: [any[], any, any]) => {\n if (Array.isArray(rows)) {\n span.setAttribute(\n SEMATTRS_GCP_BIGQUERY_ROWS_RETURNED,\n rows.length,\n );\n }\n finalizeSpan(span);\n return [rows, nextQuery, apiResponse];\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Dataset.create() method (admin operation).\n */\nfunction instrumentDatasetCreate(Dataset: any): void {\n const originalCreate = Dataset.prototype.create;\n if (typeof originalCreate !== 'function') {\n return;\n }\n\n Dataset.prototype.create = function instrumentedCreate(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalCreate.call(this, options);\n }\n\n const datasetId = this.id;\n const projectId = extractProjectId(this.parent);\n const location = extractLocation(this.parent, options);\n\n const span = createSpan(\n tracer,\n 'CREATE_DATASET',\n datasetId,\n projectId,\n config,\n );\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, datasetId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreate.call(this, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Dataset.delete() method (admin operation).\n */\nfunction instrumentDatasetDelete(Dataset: any): void {\n const originalDelete = Dataset.prototype.delete;\n if (typeof originalDelete !== 'function') {\n return;\n }\n\n Dataset.prototype.delete = function instrumentedDelete(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalDelete.call(this, options);\n }\n\n const datasetId = this.id;\n const projectId = extractProjectId(this.parent);\n\n const span = createSpan(\n tracer,\n 'DELETE_DATASET',\n datasetId,\n projectId,\n config,\n );\n\n if (datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, datasetId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalDelete.call(this, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments BigQuery.createDataset() method (admin operation).\n * This is different from Dataset.prototype.create - it's called as bigquery.createDataset(id).\n */\nfunction instrumentBigQueryCreateDataset(BigQuery: any): void {\n const originalCreateDataset = BigQuery.prototype.createDataset;\n if (typeof originalCreateDataset !== 'function') {\n return;\n }\n\n BigQuery.prototype.createDataset = function instrumentedCreateDataset(\n this: any,\n id: string,\n options?: any,\n callback?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalCreateDataset.call(this, id, options, callback);\n }\n\n const datasetId = id;\n const projectId = extractProjectId(this);\n const location = extractLocation(this, options);\n\n const span = createSpan(\n tracer,\n 'CREATE_DATASET',\n datasetId,\n projectId,\n config,\n );\n\n if (location) {\n span.setAttribute(SEMATTRS_GCP_BIGQUERY_JOB_LOCATION, location);\n }\n\n if (datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, datasetId);\n }\n\n // Handle callback-style API\n if (typeof callback === 'function') {\n const wrappedCallback = (err: any, ...args: any[]) => {\n if (err) {\n finalizeSpan(\n span,\n err instanceof Error ? err : new Error(String(err)),\n );\n } else {\n finalizeSpan(span);\n }\n return callback(err, ...args);\n };\n // Call original without runWithSpan for callbacks - the span is already active\n return originalCreateDataset.call(this, id, options, wrappedCallback);\n }\n\n // Handle Promise-style API\n return runWithSpan(span, () => {\n try {\n const result = originalCreateDataset.call(this, id, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.create() method (admin operation).\n */\nfunction instrumentTableCreate(Table: any): void {\n const originalCreate = Table.prototype.create;\n if (typeof originalCreate !== 'function') {\n return;\n }\n\n Table.prototype.create = function instrumentedCreate(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalCreate.call(this, options);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'CREATE_TABLE', target, projectId, config);\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalCreate.call(this, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments Table.delete() method (admin operation).\n */\nfunction instrumentTableDelete(Table: any): void {\n const originalDelete = Table.prototype.delete;\n if (typeof originalDelete !== 'function') {\n return;\n }\n\n Table.prototype.delete = function instrumentedDelete(\n this: any,\n options?: any,\n ): any {\n const config = getInstanceConfig(this);\n const tracer = getInstanceTracer(this);\n\n if (!config || !tracer || !config.instrumentAdminOps) {\n return originalDelete.call(this, options);\n }\n\n const tableRef = extractTableReference(this);\n const projectId = extractProjectId(this.dataset?.parent || this.parent);\n\n const target = tableRef.tableId\n ? tableRef.datasetId\n ? `${tableRef.datasetId}.${tableRef.tableId}`\n : tableRef.tableId\n : undefined;\n\n const span = createSpan(tracer, 'DELETE_TABLE', target, projectId, config);\n\n if (tableRef.datasetId) {\n span.setAttribute(SEMATTRS_DB_NAMESPACE, tableRef.datasetId);\n }\n if (tableRef.tableId) {\n span.setAttribute(SEMATTRS_DB_COLLECTION_NAME, tableRef.tableId);\n }\n\n return runWithSpan(span, () => {\n try {\n const result = originalDelete.call(this, options);\n\n return Promise.resolve(result)\n .then((response) => {\n finalizeSpan(span);\n return response;\n })\n .catch((error: unknown) => {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n });\n } catch (error) {\n finalizeSpan(\n span,\n error instanceof Error ? error : new Error(String(error)),\n );\n throw error;\n }\n });\n };\n}\n\n/**\n * Instruments BigQuery with OpenTelemetry tracing.\n *\n * This function patches BigQuery, Dataset, Table, and Job methods to create spans\n * for all database operations. The instrumentation is idempotent - calling it multiple\n * times will only instrument once.\n *\n * @example\n * ```typescript\n * import { BigQuery } from '@google-cloud/bigquery';\n * import { init } from 'autotel';\n * import { instrumentBigQuery } from 'autotel-plugins/bigquery';\n *\n * init({ service: 'my-app' });\n *\n * const bigquery = new BigQuery({ projectId: 'my-project' });\n * instrumentBigQuery(bigquery);\n *\n * // All operations are automatically traced\n * const [rows] = await bigquery.query('SELECT * FROM my_dataset.users');\n * ```\n *\n * @example\n * ```typescript\n * // With configuration\n * instrumentBigQuery(bigquery, {\n * captureQueryText: 'sanitized',\n * includeQueryHash: true,\n * instrumentAdminOps: true,\n * });\n * ```\n */\nexport function instrumentBigQuery(\n bigquery: BigQuery,\n config?: BigQueryInstrumentationConfig,\n): BigQuery {\n if (!bigquery) {\n return bigquery;\n }\n\n // Use any for internal storage and prototype patching; public API remains BigQuery-typed\n const bq = bigquery as any;\n\n // Check if already instrumented\n if (bq[INSTRUMENTED_FLAG]) {\n return bigquery;\n }\n\n const finalConfig: Required<BigQueryInstrumentationConfig> = {\n projectId: config?.projectId || '',\n location: config?.location || '',\n tracerName: config?.tracerName || DEFAULT_TRACER_NAME,\n captureQueryText: config?.captureQueryText || 'summary',\n maxQueryTextLength: config?.maxQueryTextLength || 1000,\n includeQueryHash: config?.includeQueryHash ?? true,\n instrumentAdminOps: config?.instrumentAdminOps ?? false,\n instrumentBqmlOps: config?.instrumentBqmlOps ?? false,\n instrumentRoutineOps: config?.instrumentRoutineOps ?? false,\n };\n\n const tracer = trace.getTracer(finalConfig.tracerName);\n\n // Store config and tracer on this instance for per-instance customization\n bq[CONFIG_STORAGE_KEY] = finalConfig;\n bq[TRACER_STORAGE_KEY] = tracer;\n\n // Get the BigQuery class constructor\n const BigQuery = bq.constructor;\n\n // Only patch prototypes once globally (prevent double-wrapping)\n if (!BigQuery[PROTOTYPE_INSTRUMENTED_FLAG]) {\n // Instrument core query methods\n instrumentQueryMethod(BigQuery);\n instrumentCreateQueryJob(BigQuery);\n instrumentBigQueryCreateDataset(BigQuery);\n\n // Instrument Dataset operations (always patch, check config at runtime)\n if (bq.dataset) {\n try {\n // Get Dataset class from a temporary instance\n const tempDataset = bq.dataset('__temp__');\n const Dataset = tempDataset.constructor;\n\n instrumentDatasetCreate(Dataset);\n instrumentDatasetDelete(Dataset);\n\n // Clean up temporary reference\n tempDataset.dataset = null;\n } catch {\n // Ignore errors in getting Dataset class\n }\n }\n\n // Instrument Table operations\n if (bq.dataset) {\n try {\n const tempDataset = bq.dataset('__temp__');\n const tempTable = tempDataset.table('__temp__');\n const Table = tempTable.constructor;\n\n // Core data operations (always instrumented)\n instrumentTableInsert(Table);\n instrumentTableGetRows(Table);\n instrumentTableCreateLoadJob(Table);\n instrumentTableCreateCopyJob(Table);\n instrumentTableCreateExtractJob(Table);\n\n // Admin operations (always patch, check config at runtime)\n instrumentTableCreate(Table);\n instrumentTableDelete(Table);\n\n // Clean up temporary references\n tempTable.table = null;\n tempDataset.dataset = null;\n } catch {\n // Ignore errors in getting Table class\n }\n }\n\n // Instrument Job operations\n if (bq.job) {\n try {\n const tempJob = bq.job('__temp__');\n const Job = tempJob.constructor;\n\n instrumentJobGetQueryResults(Job);\n\n // Clean up temporary reference\n tempJob.job = null;\n } catch {\n // Ignore errors in getting Job class\n }\n }\n\n // Mark prototypes as instrumented globally\n BigQuery[PROTOTYPE_INSTRUMENTED_FLAG] = true;\n }\n\n // Mark this instance as instrumented\n bq[INSTRUMENTED_FLAG] = true;\n\n return bigquery;\n}\n\n/**\n * Legacy export for backwards compatibility.\n * @deprecated Use `instrumentBigQuery` instead.\n */\nexport class BigQueryInstrumentation {\n constructor(private config?: BigQueryInstrumentationConfig) {}\n\n enable(bigquery: BigQuery): void {\n instrumentBigQuery(bigquery, this.config);\n }\n}\n","/**\n * Header utilities for Kafka message processing.\n *\n * Uses OpenTelemetry propagators internally for context extraction,\n * ensuring compatibility with W3C Trace Context, B3, and other formats.\n */\n\nimport { propagation, ROOT_CONTEXT, type Context } from 'autotel';\nimport type { RawKafkaHeaders } from './types';\n\n/**\n * Normalize Kafka headers from raw format to string record.\n *\n * Handles:\n * - undefined/null headers -> empty object\n * - Map headers (e.g., from @platformatic/kafka) -> converts to object\n * - Buffer values -> UTF-8 strings\n * - undefined values -> removed from output\n * - string values -> passed through\n *\n * @param headers - Raw Kafka headers (Record, Map, or undefined)\n * @returns Normalized headers as string record\n *\n * @example\n * ```typescript\n * const raw = {\n * traceparent: Buffer.from('00-abc...'),\n * 'content-type': 'application/json',\n * optionalHeader: undefined,\n * };\n * const normalized = normalizeHeaders(raw);\n * // { traceparent: '00-abc...', 'content-type': 'application/json' }\n * ```\n *\n * @example With Map (e.g., @platformatic/kafka)\n * ```typescript\n * const map = new Map([\n * ['traceparent', '00-abc...'],\n * ['content-type', 'application/json'],\n * ]);\n * const normalized = normalizeHeaders(map);\n * // { traceparent: '00-abc...', 'content-type': 'application/json' }\n * ```\n */\nexport function normalizeHeaders(\n headers?: RawKafkaHeaders,\n): Record<string, string> {\n if (!headers) {\n return {};\n }\n\n // Convert Map to Record if needed\n const record: Record<string, string | Buffer | undefined> =\n headers instanceof Map ? Object.fromEntries(headers) : headers;\n\n const normalized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(record)) {\n if (value === undefined) {\n continue;\n }\n\n normalized[key] = Buffer.isBuffer(value) ? value.toString('utf8') : value;\n }\n\n return normalized;\n}\n\n/**\n * TextMapGetter for case-insensitive header lookup.\n *\n * Kafka headers are case-sensitive, but trace context headers\n * (traceparent, tracestate) should be matched case-insensitively\n * for maximum compatibility.\n */\nconst caseInsensitiveGetter = {\n get(carrier: Record<string, string>, key: string): string | undefined {\n const lowerKey = key.toLowerCase();\n for (const [k, v] of Object.entries(carrier)) {\n if (k.toLowerCase() === lowerKey) {\n return v;\n }\n }\n return undefined;\n },\n keys(carrier: Record<string, string>): string[] {\n return Object.keys(carrier);\n },\n};\n\n/**\n * Extract trace context from normalized headers using OTel propagators.\n *\n * This is a pure function that does not activate any context.\n * The returned Context can be used to:\n * - Start spans as children of the extracted context\n * - Create links to the extracted context\n *\n * Returns ROOT_CONTEXT if no trace context is found in headers.\n *\n * @param headers - Normalized headers (use normalizeHeaders first)\n * @returns OpenTelemetry Context with extracted trace context\n *\n * @example\n * ```typescript\n * import { normalizeHeaders, extractTraceContext } from 'autotel-plugins/kafka';\n * import { trace } from '@opentelemetry/api';\n *\n * const headers = normalizeHeaders(message.headers);\n * const extractedCtx = extractTraceContext(headers);\n *\n * // Get span context from extracted context\n * const spanContext = trace.getSpanContext(extractedCtx);\n * if (spanContext && trace.isSpanContextValid(spanContext)) {\n * // Valid remote context extracted\n * }\n * ```\n */\nexport function extractTraceContext(headers: Record<string, string>): Context {\n return propagation.extract(ROOT_CONTEXT, headers, caseInsensitiveGetter);\n}\n","/**\n * Correlation ID utilities for Kafka message tracing.\n *\n * Provides consistent correlation ID handling across producers and consumers:\n * - Inject trace headers and correlation ID into outgoing messages\n * - Extract correlation ID from incoming messages\n * - Derive correlation ID from current trace context\n */\n\nimport {\n propagation,\n context,\n otelTrace as trace,\n type TextMapSetter,\n} from 'autotel';\nimport type { InjectOptions } from './types';\nimport { CORRELATION_ID_HEADER } from '../common/constants';\n\n/**\n * TextMapSetter for injecting headers.\n */\nconst headerSetter: TextMapSetter<Record<string, string>> = {\n set(carrier: Record<string, string>, key: string, value: string): void {\n carrier[key] = value;\n },\n};\n\n/**\n * Derive correlation ID from current trace context.\n *\n * Priority:\n * 1. Baggage 'correlation-id' if present\n * 2. First 16 characters of trace ID (64-bit for compatibility)\n * 3. Empty string if no active trace\n *\n * @returns Correlation ID derived from context\n *\n * @example\n * ```typescript\n * import { deriveCorrelationId } from 'autotel-plugins/kafka';\n *\n * // Inside a traced operation\n * const correlationId = deriveCorrelationId();\n * // '4bf92f3577b34da6' (first 16 chars of trace ID)\n * ```\n */\nexport function deriveCorrelationId(): string {\n // Check baggage first\n const activeBaggage = propagation.getActiveBaggage();\n const baggageCorrelationId = activeBaggage?.getEntry('correlation-id');\n if (baggageCorrelationId?.value) {\n return baggageCorrelationId.value;\n }\n\n // Fall back to trace ID (first 16 chars)\n const activeSpan = trace.getActiveSpan();\n if (activeSpan) {\n const spanContext = activeSpan.spanContext();\n // Return first 16 chars (64-bit) for compatibility with systems\n // that don't support full 128-bit trace IDs\n return spanContext.traceId.slice(0, 16);\n }\n\n return '';\n}\n\n/**\n * Extract correlation ID from message headers.\n *\n * Looks for the x-correlation-id header (case-insensitive).\n *\n * @param headers - Normalized headers (string values)\n * @returns Correlation ID if found, undefined otherwise\n *\n * @example\n * ```typescript\n * import { extractCorrelationId, normalizeHeaders } from 'autotel-plugins/kafka';\n *\n * const headers = normalizeHeaders(message.headers);\n * const correlationId = extractCorrelationId(headers);\n * if (correlationId) {\n * logger.info({ correlationId }, 'Processing message');\n * }\n * ```\n */\nexport function extractCorrelationId(\n headers: Record<string, string>,\n): string | undefined {\n // Case-insensitive lookup\n const lowerKey = CORRELATION_ID_HEADER.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === lowerKey) {\n return value;\n }\n }\n return undefined;\n}\n\n/**\n * Inject trace headers into outgoing message headers.\n *\n * Uses OpenTelemetry propagators to inject W3C Trace Context (traceparent, tracestate)\n * and optionally adds x-correlation-id header (default: true).\n *\n * Note: Baggage is injected automatically when W3CBaggagePropagator is registered.\n *\n * @param base - Base headers to merge with injected headers\n * @param options - Injection options\n * @returns Headers with trace context injected\n *\n * @example\n * ```typescript\n * import { injectTraceHeaders } from 'autotel-plugins/kafka';\n *\n * // Producer: inject headers with correlation ID\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * await producer.send({\n * topic: 'orders',\n * messages: [{ value: JSON.stringify(order), headers }],\n * });\n * ```\n *\n * @example With explicit correlation ID\n * ```typescript\n * const headers = injectTraceHeaders({}, {\n * correlationId: 'order-12345',\n * includeCorrelationIdHeader: true,\n * });\n * ```\n */\nexport function injectTraceHeaders(\n base: Record<string, string> = {},\n options: InjectOptions = {},\n): Record<string, string> {\n const { correlationId, includeCorrelationIdHeader = true } = options;\n\n const carrier = { ...base };\n\n // Inject trace context (traceparent, tracestate)\n // Note: If W3CBaggagePropagator is registered, baggage is also injected automatically\n propagation.inject(context.active(), carrier, headerSetter);\n\n // Add correlation ID if requested\n if (includeCorrelationIdHeader) {\n const corrId = correlationId ?? deriveCorrelationId();\n if (corrId) {\n carrier[CORRELATION_ID_HEADER] = corrId;\n }\n }\n\n return carrier;\n}\n","/**\n * Processing span wrapper for Kafka message handling.\n *\n * Creates processing spans with proper context handling, supporting:\n * - Context mode control (inherit/link/none)\n * - Messaging attributes for consistent querying\n * - Integration with official KafkaJS instrumentation\n */\n\nimport {\n otelTrace as trace,\n context,\n SpanKind,\n SpanStatusCode,\n type Span,\n type SpanContext,\n type SpanLink,\n} from 'autotel';\nimport type {\n ProcessingDescriptor,\n ContextMode,\n ProcessingSpanCallback,\n} from './types';\nimport { normalizeHeaders, extractTraceContext } from './headers';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP,\n SEMATTRS_MESSAGING_KAFKA_PARTITION,\n SEMATTRS_MESSAGING_KAFKA_OFFSET,\n SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY,\n} from '../common/constants';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * Check if a span context is valid (has both traceId and spanId).\n */\nfunction isValidSpanContext(\n spanContext: SpanContext | undefined,\n): spanContext is SpanContext {\n return !!(\n spanContext &&\n spanContext.traceId &&\n spanContext.spanId &&\n trace.isSpanContextValid(spanContext)\n );\n}\n\n/**\n * Create a processing span for Kafka message handling.\n *\n * **Context Mode Behavior:**\n *\n * | Mode | Active Span Exists | No Active Span |\n * |------|-------------------|----------------|\n * | `inherit` | Parent = active span. Link to extracted if different trace. | Parent = extracted context |\n * | `link` | Parent = active span. Link to extracted context. | Parent = root. Link to extracted. |\n * | `none` | Parent = active span. No links. | Parent = root. No links. |\n *\n * **Feature Flag Pattern:**\n * Use `contextMode: 'none'` to disable trace propagation via environment variable:\n * ```typescript\n * contextMode: process.env.KAFKA_PROPAGATE_TRACE !== 'false' ? 'inherit' : 'none'\n * ```\n *\n * @param descriptor - Processing span configuration\n * @param fn - Async callback to execute within the span\n * @returns Promise resolving to callback result\n * @throws Error if span creation fails or callback throws\n *\n * @example Basic usage\n * ```typescript\n * import { withProcessingSpan } from 'autotel-plugins/kafka';\n *\n * await consumer.run({\n * eachMessage: async ({ topic, partition, message }) => {\n * try {\n * await withProcessingSpan({\n * name: 'order.process',\n * headers: message.headers,\n * contextMode: 'inherit',\n * topic,\n * consumerGroup: 'payments',\n * partition,\n * offset: message.offset,\n * }, async (span) => {\n * return await processOrder(message);\n * });\n * } catch (error) {\n * logger.error('Processing failed', { error });\n * }\n * },\n * });\n * ```\n *\n * @example With batch lineage links (using semantic attribute constants)\n * ```typescript\n * import { extractBatchLineage, withProcessingSpan, SEMATTRS_LINKED_TRACE_ID_COUNT, SEMATTRS_LINKED_TRACE_ID_HASH } from 'autotel-plugins/kafka';\n *\n * const lineage = extractBatchLineage(batch, { maxLinks: 50 });\n *\n * await withProcessingSpan({\n * name: 'settlement.batch',\n * headers: {},\n * contextMode: 'none',\n * links: lineage.links,\n * topic: 'settlements',\n * consumerGroup: 'batcher',\n * }, async (span) => {\n * span.setAttribute(SEMATTRS_LINKED_TRACE_ID_COUNT, lineage.linked_trace_id_count);\n * span.setAttribute(SEMATTRS_LINKED_TRACE_ID_HASH, lineage.linked_trace_id_hash);\n * await processSettlement(batch);\n * });\n * ```\n */\nexport async function withProcessingSpan<T>(\n descriptor: ProcessingDescriptor,\n fn: ProcessingSpanCallback<T>,\n): Promise<T> {\n const {\n name,\n headers,\n contextMode = 'inherit',\n links = [],\n topic,\n consumerGroup,\n partition,\n offset,\n key,\n } = descriptor;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n const normalizedHeaders = normalizeHeaders(headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const extractedSpanContext = trace.getSpanContext(extractedCtx);\n\n // Determine parent context and links based on context mode\n const { parentContext, spanLinks } = resolveContextAndLinks(\n contextMode,\n extractedSpanContext,\n links,\n );\n\n // Create span with computed parent and links\n const span = tracer.startSpan(\n name,\n {\n kind: SpanKind.CONSUMER,\n links: spanLinks,\n },\n parentContext,\n );\n\n // Set messaging attributes\n setMessagingAttributes(span, {\n topic,\n consumerGroup,\n partition,\n offset,\n key,\n });\n\n // Execute callback within span context\n const spanContext = trace.setSpan(context.active(), span);\n\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span);\n });\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n\n throw error;\n }\n}\n\n/**\n * Resolve parent context and links based on context mode.\n */\nfunction resolveContextAndLinks(\n contextMode: ContextMode,\n extractedSpanContext: SpanContext | undefined,\n additionalLinks: SpanLink[],\n): {\n parentContext: typeof context extends { active(): infer T } ? T : never;\n spanLinks: SpanLink[];\n} {\n const activeSpan = trace.getActiveSpan();\n const activeContext = context.active();\n const hasActiveSpan = activeSpan !== undefined;\n const hasValidExtracted = isValidSpanContext(extractedSpanContext);\n\n const spanLinks: SpanLink[] = [...additionalLinks];\n\n switch (contextMode) {\n case 'inherit': {\n if (hasActiveSpan) {\n // Parent = active span\n // Link to extracted if different trace\n if (hasValidExtracted) {\n const activeSpanContext = activeSpan.spanContext();\n if (activeSpanContext.traceId !== extractedSpanContext.traceId) {\n spanLinks.push({ context: extractedSpanContext });\n }\n }\n return { parentContext: activeContext, spanLinks };\n } else {\n // No active span: parent = extracted context\n if (hasValidExtracted) {\n const extractedParentCtx = trace.setSpanContext(\n activeContext,\n extractedSpanContext,\n );\n return { parentContext: extractedParentCtx, spanLinks };\n }\n // No extracted context either: root span\n return { parentContext: activeContext, spanLinks };\n }\n }\n\n case 'link': {\n // Always parent to current context (active span or root)\n // Always link to extracted if valid\n if (hasValidExtracted) {\n spanLinks.push({ context: extractedSpanContext });\n }\n return { parentContext: activeContext, spanLinks };\n }\n\n case 'none': {\n // Parent to current context, no links to extracted\n return { parentContext: activeContext, spanLinks };\n }\n\n default: {\n // TypeScript exhaustive check\n const exhaustive: never = contextMode;\n throw new Error(`Unknown context mode: ${exhaustive}`);\n }\n }\n}\n\n/**\n * Set standard messaging attributes on a span.\n */\nfunction setMessagingAttributes(\n span: Span,\n attrs: {\n topic?: string;\n consumerGroup?: string;\n partition?: number;\n offset?: string;\n key?: string;\n },\n): void {\n const { topic, consumerGroup, partition, offset, key } = attrs;\n\n if (topic) {\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);\n }\n\n if (consumerGroup) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP, consumerGroup);\n }\n\n if (partition !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_PARTITION, partition);\n }\n\n if (offset !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_OFFSET, offset);\n }\n\n if (key !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY, key);\n }\n}\n","/**\n * Producer span wrapper for Kafka message publishing.\n *\n * Creates PRODUCER spans with proper messaging semantics,\n * allowing trace context to be injected inside the span.\n *\n * @example Basic producer span\n * ```typescript\n * import { withProducerSpan, injectTraceHeaders } from 'autotel-plugins/kafka';\n *\n * await withProducerSpan({\n * name: 'order.publish',\n * topic: 'orders',\n * messageKey: 'order-123',\n * }, async (span) => {\n * // Inject headers inside the PRODUCER span context\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * await producer.send({\n * topic: 'orders',\n * messages: [{ key: 'order-123', value: JSON.stringify(order), headers }],\n * });\n * });\n * ```\n */\n\nimport { otelTrace as trace, context, SpanKind, SpanStatusCode } from 'autotel';\nimport type { ProducerDescriptor, ProducerSpanCallback } from './types';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY,\n SEMATTRS_MESSAGING_OPERATION,\n} from '../common/constants';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * Create a producer span for Kafka message publishing.\n *\n * This creates a PRODUCER span with proper messaging attributes.\n * The callback runs within the span's context, so you can call\n * `injectTraceHeaders()` inside it to get the correct trace context.\n *\n * @param descriptor - Producer span configuration\n * @param fn - Async callback to execute within the span\n * @returns Promise resolving to callback result\n * @throws Error if span creation fails or callback throws\n *\n * @example\n * ```typescript\n * await withProducerSpan({\n * name: 'payment.publish',\n * topic: 'payments',\n * messageKey: paymentId,\n * }, async (span) => {\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * await producer.send({ topic: 'payments', messages: [{ key: paymentId, value, headers }] });\n * });\n * ```\n */\nexport async function withProducerSpan<T>(\n descriptor: ProducerDescriptor,\n fn: ProducerSpanCallback<T>,\n): Promise<T> {\n const { name, topic, messageKey, system = 'kafka' } = descriptor;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n // Create PRODUCER span\n const span = tracer.startSpan(name, {\n kind: SpanKind.PRODUCER,\n });\n\n // Set messaging attributes\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, system);\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);\n span.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'publish');\n\n if (messageKey !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY, messageKey);\n }\n\n // Execute callback within span context\n const spanContext = trace.setSpan(context.active(), span);\n\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span);\n });\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n\n throw error;\n }\n}\n","/**\n * Batch lineage utilities for fan-in trace correlation.\n *\n * When processing batches of messages (e.g., settlement batches),\n * this utility extracts and correlates trace IDs from all messages\n * to create meaningful span links and aggregation metadata.\n */\n\nimport { otelTrace as trace, type SpanContext, type SpanLink } from 'autotel';\nimport type {\n BatchItem,\n BatchLineageOptions,\n BatchLineageResult,\n ExtractedContext,\n} from './types';\nimport { normalizeHeaders, extractTraceContext } from './headers';\n\nconst DEFAULT_MAX_LINKS = 128;\n\n/**\n * Check if a span context is valid for creating links.\n * Must have both traceId and spanId.\n */\nfunction isValidSpanContext(\n spanContext: SpanContext | undefined,\n): spanContext is SpanContext {\n return !!(\n spanContext &&\n spanContext.traceId &&\n spanContext.spanId &&\n trace.isSpanContextValid(spanContext)\n );\n}\n\n/**\n * Simple SHA-256 hash for batch lineage.\n *\n * Uses Web Crypto API (available in Node.js 15+ and all modern browsers).\n * Falls back to a simple hash if crypto is unavailable.\n */\nasync function hashTraceIds(traceIds: string[]): Promise<string> {\n const input = traceIds.join('|');\n\n try {\n // Use Web Crypto API (available in Node.js 15+)\n const encoder = new TextEncoder();\n const data = encoder.encode(input);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = new Uint8Array(hashBuffer);\n\n // Convert to hex and take first 16 chars (64 bits)\n return [...hashArray]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n .slice(0, 16);\n } catch {\n // Fallback: simple djb2-style hash\n let hash = 5381;\n for (let i = 0; i < input.length; i++) {\n // eslint-disable-next-line unicorn/prefer-code-point\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n // Convert to unsigned 32-bit, then hex, pad to 16 chars\n return (hash >>> 0).toString(16).padStart(16, '0');\n }\n}\n\n/**\n * Synchronous hash fallback for when async is not suitable.\n */\nfunction hashTraceIdsSync(traceIds: string[]): string {\n const input = traceIds.join('|');\n\n // Simple djb2-style hash\n let hash = 5381;\n for (let i = 0; i < input.length; i++) {\n // eslint-disable-next-line unicorn/prefer-code-point\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n\n // Convert to unsigned 32-bit, then hex, pad to 16 chars\n return (hash >>> 0).toString(16).padStart(16, '0');\n}\n\n/**\n * Extract batch lineage from a collection of messages.\n *\n * For each message with headers:\n * 1. Extract SpanContext using OTel propagators\n * 2. Filter to valid SpanContexts (must have traceId + spanId)\n * 3. Deduplicate by traceId\n * 4. Sort trace IDs alphabetically for deterministic hash\n * 5. Create hash of sorted trace IDs\n * 6. Create SpanLinks from valid contexts (capped at maxLinks)\n *\n * @param items - Array of items with optional headers\n * @param options - Extraction options\n * @returns Batch lineage result with links and metadata\n *\n * @example Basic batch lineage\n * ```typescript\n * import { extractBatchLineage, withProcessingSpan } from 'autotel-plugins/kafka';\n *\n * // In batch consumer\n * const lineage = extractBatchLineage(batch, { maxLinks: 50 });\n *\n * await withProcessingSpan({\n * name: 'settlement.batch',\n * headers: {},\n * contextMode: 'none',\n * links: lineage.links,\n * topic: 'settlements',\n * consumerGroup: 'batcher',\n * }, async (span) => {\n * span.setAttribute('linked_trace_id_count', lineage.linked_trace_id_count);\n * span.setAttribute('linked_trace_id_hash', lineage.linked_trace_id_hash);\n * await processSettlement(batch);\n * });\n * ```\n *\n * @example With trace IDs for debugging\n * ```typescript\n * const lineage = extractBatchLineage(batch, {\n * includeTraceIds: true, // Warning: may contain sensitive data\n * maxLinks: 100,\n * });\n *\n * console.log('Processing batch from traces:', lineage.trace_ids);\n * ```\n */\nexport function extractBatchLineage(\n items: BatchItem[],\n options: BatchLineageOptions = {},\n): BatchLineageResult {\n const { includeTraceIds = false, maxLinks = DEFAULT_MAX_LINKS } = options;\n\n // Extract valid span contexts from items\n const extractedContexts: ExtractedContext[] = [];\n const seenTraceIds = new Set<string>();\n\n for (const item of items) {\n const normalizedHeaders = normalizeHeaders(item.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const spanContext = trace.getSpanContext(extractedCtx);\n\n // Check valid span context and deduplicate by traceId\n if (\n isValidSpanContext(spanContext) &&\n !seenTraceIds.has(spanContext.traceId)\n ) {\n seenTraceIds.add(spanContext.traceId);\n extractedContexts.push({\n traceId: spanContext.traceId,\n spanContext,\n });\n }\n }\n\n // Sort by traceId for deterministic hash\n extractedContexts.sort((a, b) => a.traceId.localeCompare(b.traceId));\n\n const traceIds = extractedContexts.map((ec) => ec.traceId);\n\n // Create links (capped at maxLinks)\n const links: SpanLink[] = extractedContexts\n .slice(0, maxLinks)\n .map((ec) => ({ context: ec.spanContext }));\n\n // Compute hash\n const hash =\n traceIds.length > 0 ? hashTraceIdsSync(traceIds) : '0000000000000000';\n\n return {\n linked_trace_id_count: traceIds.length,\n linked_trace_id_hash: hash,\n links,\n ...(includeTraceIds && { trace_ids: traceIds }),\n };\n}\n\n/**\n * Async version of extractBatchLineage that uses crypto.subtle for hashing.\n *\n * Use this when you need cryptographically secure hashing and can await.\n *\n * @param items - Array of items with optional headers\n * @param options - Extraction options\n * @returns Promise resolving to batch lineage result\n *\n * @example\n * ```typescript\n * const lineage = await extractBatchLineageAsync(batch, { maxLinks: 50 });\n * ```\n */\nexport async function extractBatchLineageAsync(\n items: BatchItem[],\n options: BatchLineageOptions = {},\n): Promise<BatchLineageResult> {\n const { includeTraceIds = false, maxLinks = DEFAULT_MAX_LINKS } = options;\n\n // Extract valid span contexts from items\n const extractedContexts: ExtractedContext[] = [];\n const seenTraceIds = new Set<string>();\n\n for (const item of items) {\n const normalizedHeaders = normalizeHeaders(item.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const spanContext = trace.getSpanContext(extractedCtx);\n\n // Check valid span context and deduplicate by traceId\n if (\n isValidSpanContext(spanContext) &&\n !seenTraceIds.has(spanContext.traceId)\n ) {\n seenTraceIds.add(spanContext.traceId);\n extractedContexts.push({\n traceId: spanContext.traceId,\n spanContext,\n });\n }\n }\n\n // Sort by traceId for deterministic hash\n extractedContexts.sort((a, b) => a.traceId.localeCompare(b.traceId));\n\n const traceIds = extractedContexts.map((ec) => ec.traceId);\n\n // Create links (capped at maxLinks)\n const links: SpanLink[] = extractedContexts\n .slice(0, maxLinks)\n .map((ec) => ({ context: ec.spanContext }));\n\n // Compute hash using crypto.subtle\n const hash =\n traceIds.length > 0 ? await hashTraceIds(traceIds) : '0000000000000000';\n\n return {\n linked_trace_id_count: traceIds.length,\n linked_trace_id_hash: hash,\n links,\n ...(includeTraceIds && { trace_ids: traceIds }),\n };\n}\n","/**\n * Batch consumer wrapper for KafkaJS batch processing.\n *\n * Provides observability for eachBatch processing while preserving\n * the exact KafkaJS signature and passing through all functions.\n *\n * @example Basic batch consumer\n * ```typescript\n * import { withBatchConsumer } from 'autotel-plugins/kafka';\n *\n * await consumer.run({\n * eachBatch: withBatchConsumer({\n * name: 'orders.batch',\n * consumerGroup: 'processor',\n * }, async ({ batch, resolveOffset, heartbeat, commitOffsetsIfNecessary, isRunning, isStale, pause }) => {\n * for (const message of batch.messages) {\n * await processOrder(message);\n * resolveOffset(message.offset);\n * }\n * }),\n * });\n * ```\n */\n\nimport {\n otelTrace as trace,\n context,\n SpanKind,\n SpanStatusCode,\n type Span,\n} from 'autotel';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP,\n SEMATTRS_MESSAGING_KAFKA_PARTITION,\n SEMATTRS_MESSAGING_KAFKA_OFFSET,\n SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY,\n SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT,\n SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET,\n SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET,\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,\n SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,\n} from '../common/constants';\nimport { normalizeHeaders, extractTraceContext } from './headers';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * KafkaJS batch payload interface.\n * Matches the exact signature from KafkaJS.\n */\nexport interface EachBatchPayload {\n batch: {\n topic: string;\n partition: number;\n messages: Array<{\n offset: string;\n key?: Buffer | null;\n value: Buffer | null;\n headers?: Record<string, Buffer | string | undefined>;\n }>;\n firstOffset(): string | null;\n lastOffset(): string;\n highWatermark: string;\n };\n resolveOffset(offset: string): void;\n heartbeat(): Promise<void>;\n commitOffsetsIfNecessary(\n offsets?: Record<string, Record<number, string>>,\n ): Promise<void>;\n uncommittedOffsets(): Record<string, Record<number, string>>;\n isRunning(): boolean;\n isStale(): boolean;\n pause(): () => void;\n}\n\n/**\n * Batch consumer handler type.\n */\nexport type EachBatchHandler = (payload: EachBatchPayload) => Promise<void>;\n\n/**\n * Progress metrics during batch processing.\n */\nexport interface BatchProgressMetrics {\n /** Number of messages processed so far */\n processed: number;\n /** Number of messages that failed processing */\n failed: number;\n /** Number of messages skipped */\n skipped: number;\n /** Batch processing time in milliseconds */\n batchProcessingTimeMs: number;\n}\n\n/**\n * Per-message span mode.\n * - 'all': Create spans for every message. Message spans are parented to extracted trace context from message headers when valid (trace continuation); otherwise to the batch span. All per-message spans are ended when the batch completes, including messages never resolved via resolveOffset (no span leak).\n * - 'errors': Only create spans for messages that fail. When the handler throws, a per-message error span is created for the first message. Use createMessageErrorSpan in your catch block for per-message error spans.\n * - 'none': No per-message spans (default)\n */\nexport type PerMessageSpanMode = 'all' | 'errors' | 'none';\n\n/**\n * Configuration for batch consumer wrapper.\n */\nexport interface BatchConsumerConfig {\n /**\n * Name for the batch processing span (e.g., \"orders.batch\")\n */\n name: string;\n\n /**\n * Consumer group name. Sets `messaging.kafka.consumer.group` attribute.\n */\n consumerGroup?: string;\n\n /**\n * Per-message span creation mode. When 'all', message spans follow extracted trace context from headers when valid (trace continuation), otherwise parent to the batch span; all per-message spans are ended on batch completion.\n * @default 'none' (to avoid cardinality explosion)\n */\n perMessageSpans?: PerMessageSpanMode;\n\n /**\n * Optional callback for real-time visibility into batch processing.\n */\n onProgress?: (metrics: BatchProgressMetrics) => void;\n}\n\n/**\n * Wrap a KafkaJS eachBatch handler with observability.\n *\n * Preserves the exact KafkaJS signature, passing through all functions unchanged.\n * Per-message spans are never leaked: all are ended on batch success or on handler throw.\n *\n * @param config - Batch consumer configuration\n * @param handler - The eachBatch handler to wrap\n * @returns Wrapped handler with observability\n *\n * @example With progress tracking\n * ```typescript\n * await consumer.run({\n * eachBatch: withBatchConsumer({\n * name: 'orders.batch',\n * consumerGroup: 'processor',\n * perMessageSpans: 'errors',\n * onProgress: (metrics) => {\n * console.log(`Processed ${metrics.processed}, failed ${metrics.failed}`);\n * },\n * }, async ({ batch, resolveOffset, heartbeat }) => {\n * for (const message of batch.messages) {\n * try {\n * await processOrder(message);\n * resolveOffset(message.offset);\n * } catch (error) {\n * // Per-message span created on error when perMessageSpans='errors'\n * }\n * await heartbeat();\n * }\n * }),\n * });\n * ```\n */\nexport function withBatchConsumer(\n config: BatchConsumerConfig,\n handler: EachBatchHandler,\n): EachBatchHandler {\n const { name, consumerGroup, perMessageSpans = 'none', onProgress } = config;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n return async (payload: EachBatchPayload): Promise<void> => {\n const { batch } = payload;\n const startTime = Date.now();\n\n // Metrics tracking\n let processed = 0;\n let failed = 0;\n let skipped = 0;\n\n // Create batch span\n const batchSpan = tracer.startSpan(name, {\n kind: SpanKind.CONSUMER,\n });\n\n // Set batch attributes\n setBatchAttributes(batchSpan, {\n topic: batch.topic,\n partition: batch.partition,\n consumerGroup,\n messageCount: batch.messages.length,\n firstOffset: batch.firstOffset() ?? undefined,\n lastOffset: batch.lastOffset(),\n });\n\n const spanContext = trace.setSpan(context.active(), batchSpan);\n\n // Create wrapped payload with optional per-message tracking\n const {\n wrappedPayload,\n endOpenMessageSpans,\n endRemainingMessageSpansOnSuccess,\n } = createWrappedPayload(\n payload,\n perMessageSpans,\n tracer,\n spanContext,\n (type: 'processed' | 'failed' | 'skipped') => {\n if (type === 'processed') processed++;\n else if (type === 'failed') failed++;\n else skipped++;\n\n if (onProgress) {\n onProgress({\n processed,\n failed,\n skipped,\n batchProcessingTimeMs: Date.now() - startTime,\n });\n }\n },\n );\n\n try {\n await context.with(spanContext, async () => {\n await handler(wrappedPayload);\n });\n\n // End any per-message spans that were never resolved (skipped/unresolved messages)\n endRemainingMessageSpansOnSuccess?.();\n\n // Set final metrics\n const processingTime = Date.now() - startTime;\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,\n processed,\n );\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,\n failed,\n );\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,\n processingTime,\n );\n\n batchSpan.setStatus({ code: SpanStatusCode.OK });\n batchSpan.end();\n } catch (error) {\n // End any open per-message spans (e.g. handler threw after accessing message)\n endOpenMessageSpans?.(error);\n\n // In 'errors' mode, create a per-message error span for the first message when handler throws\n const firstMessage = batch.messages[0];\n if (perMessageSpans === 'errors' && firstMessage !== undefined) {\n createMessageErrorSpan(\n name,\n {\n offset: firstMessage.offset,\n key: firstMessage.key ?? undefined,\n headers: firstMessage.headers,\n },\n error instanceof Error ? error : new Error(String(error)),\n batch.topic,\n batch.partition,\n );\n }\n\n const processingTime = Date.now() - startTime;\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_PROCESSED,\n processed,\n );\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_MESSAGES_FAILED,\n failed + 1, // Count the batch error\n );\n batchSpan.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_PROCESSING_TIME_MS,\n processingTime,\n );\n\n batchSpan.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n batchSpan.recordException(error);\n } else {\n batchSpan.recordException(new Error(String(error)));\n }\n batchSpan.end();\n\n throw error;\n }\n };\n}\n\n/**\n * Set batch-level attributes on the span.\n */\nfunction setBatchAttributes(\n span: Span,\n attrs: {\n topic: string;\n partition: number;\n consumerGroup?: string;\n messageCount: number;\n firstOffset?: string;\n lastOffset: string;\n },\n): void {\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, attrs.topic);\n span.setAttribute(SEMATTRS_MESSAGING_KAFKA_PARTITION, attrs.partition);\n span.setAttribute(SEMATTRS_MESSAGING_BATCH_MESSAGE_COUNT, attrs.messageCount);\n\n if (attrs.consumerGroup) {\n span.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_CONSUMER_GROUP,\n attrs.consumerGroup,\n );\n }\n\n if (attrs.firstOffset) {\n span.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_FIRST_OFFSET,\n attrs.firstOffset,\n );\n }\n\n span.setAttribute(\n SEMATTRS_MESSAGING_KAFKA_BATCH_LAST_OFFSET,\n attrs.lastOffset,\n );\n}\n\n/**\n * Result of createWrappedPayload: wrapped payload and optional cleanup for open spans.\n */\ninterface WrappedPayloadResult {\n wrappedPayload: EachBatchPayload;\n endOpenMessageSpans?: (error: unknown) => void;\n endRemainingMessageSpansOnSuccess?: () => void;\n}\n\n/**\n * Create a wrapped payload that optionally tracks per-message processing.\n */\nfunction createWrappedPayload(\n original: EachBatchPayload,\n perMessageSpans: PerMessageSpanMode,\n tracer: ReturnType<typeof trace.getTracer>,\n parentContext: ReturnType<typeof context.active>,\n onMetric: (type: 'processed' | 'failed' | 'skipped') => void,\n): WrappedPayloadResult {\n if (perMessageSpans === 'none') {\n // Pass through unchanged, just track resolveOffset calls\n return {\n wrappedPayload: {\n ...original,\n resolveOffset: (offset: string) => {\n onMetric('processed');\n original.resolveOffset(offset);\n },\n },\n };\n }\n\n // For 'all' mode, create per-message spans upfront\n const messageSpans = new Map<string, Span>();\n\n // Pre-create spans for 'all' mode so they're created regardless of property access.\n // Use extracted trace context from message headers when valid (trace continuation);\n // otherwise parent to the batch span so message spans are not root spans.\n if (perMessageSpans === 'all') {\n for (const message of original.batch.messages) {\n const normalizedHeaders = normalizeHeaders(message.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const spanContext = trace.getSpanContext(extractedCtx);\n const parentCtx =\n spanContext && trace.isSpanContextValid(spanContext)\n ? extractedCtx\n : parentContext;\n\n const span = tracer.startSpan(\n `${original.batch.topic}.${original.batch.partition}.${message.offset}`,\n {\n kind: SpanKind.CONSUMER,\n },\n parentCtx,\n );\n\n span.setAttributes({\n [SEMATTRS_MESSAGING_SYSTEM]: 'kafka',\n [SEMATTRS_MESSAGING_DESTINATION_NAME]: original.batch.topic,\n [SEMATTRS_MESSAGING_KAFKA_PARTITION]: original.batch.partition,\n [SEMATTRS_MESSAGING_KAFKA_OFFSET]: message.offset,\n ...(message.key && {\n [SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY]: message.key.toString(),\n }),\n });\n\n messageSpans.set(message.offset, span);\n }\n }\n\n const wrappedMessages = original.batch.messages.map((message) => ({\n ...message,\n }));\n\n const wrappedBatch = {\n ...original.batch,\n messages: wrappedMessages,\n };\n\n const wrappedPayload: EachBatchPayload = {\n ...original,\n batch: wrappedBatch,\n resolveOffset: (offset: string) => {\n onMetric('processed');\n // End the per-message span if one was created for this offset\n const span = messageSpans.get(offset);\n if (span) {\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n messageSpans.delete(offset);\n }\n original.resolveOffset(offset);\n },\n };\n\n const endOpenMessageSpans =\n perMessageSpans === 'all'\n ? (error: unknown) => {\n for (const [, span] of messageSpans) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n }\n messageSpans.clear();\n }\n : undefined;\n\n const endRemainingMessageSpansOnSuccess =\n perMessageSpans === 'all'\n ? () => {\n for (const [, span] of messageSpans) {\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n }\n messageSpans.clear();\n }\n : undefined;\n\n return {\n wrappedPayload,\n endOpenMessageSpans,\n endRemainingMessageSpansOnSuccess,\n };\n}\n\n/**\n * Helper to create a per-message span for error cases.\n * Call this in your error handler when using perMessageSpans: 'errors'.\n */\nexport function createMessageErrorSpan(\n name: string,\n message: {\n offset: string;\n key?: Buffer | null;\n headers?: Record<string, Buffer | string | undefined>;\n },\n error: Error,\n topic: string,\n partition: number,\n): void {\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n const normalizedHeaders = normalizeHeaders(message.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n\n const span = tracer.startSpan(\n `${name}.error`,\n {\n kind: SpanKind.CONSUMER,\n },\n extractedCtx,\n );\n\n span.setAttributes({\n [SEMATTRS_MESSAGING_SYSTEM]: 'kafka',\n [SEMATTRS_MESSAGING_DESTINATION_NAME]: topic,\n [SEMATTRS_MESSAGING_KAFKA_PARTITION]: partition,\n [SEMATTRS_MESSAGING_KAFKA_OFFSET]: message.offset,\n ...(message.key && {\n [SEMATTRS_MESSAGING_KAFKA_MESSAGE_KEY]: message.key.toString(),\n }),\n });\n\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.recordException(error);\n span.end();\n}\n","/**\n * Stream processor for Kafka pipeline patterns.\n *\n * Provides a structured way to process messages through stages,\n * with proper span nesting and lineage tracking.\n *\n * Propagation story:\n * - Stage spans are children of the processor span\n * - Produce spans are children of the stage span that calls producer.send\n * - Output messages carry context from produce span (injected headers)\n * - For lineage: SpanLink from produce span to input message's extracted context\n *\n * @example\n * ```typescript\n * import { createStreamProcessor } from 'autotel-plugins/kafka';\n *\n * const processor = createStreamProcessor({\n * name: 'order-enrichment',\n * stages: ['validate', 'enrich', 'publish'],\n * });\n *\n * await consumer.run({\n * eachMessage: async ({ message }) => {\n * await processor.run(message, async (ctx) => {\n * const validated = await ctx.stage('validate', () => validate(message));\n * const enriched = await ctx.stage('enrich', () => enrich(validated));\n * await ctx.stage('publish', () =>\n * ctx.produce('enriched-orders', enriched, { linkToInput: true })\n * );\n * });\n * },\n * });\n * ```\n */\n\nimport {\n otelTrace as trace,\n context,\n SpanKind,\n SpanStatusCode,\n type Span,\n type SpanLink,\n type SpanContext,\n} from 'autotel';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_OPERATION,\n} from '../common/constants';\nimport { normalizeHeaders, extractTraceContext } from './headers';\nimport { injectTraceHeaders } from './correlation';\nimport type { RawKafkaHeaders } from './types';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * Input message type for stream processing.\n */\nexport interface StreamMessage {\n headers?: RawKafkaHeaders;\n key?: Buffer | null;\n value: Buffer | null;\n offset?: string;\n}\n\n/**\n * Configuration for stream processor.\n */\nexport interface StreamProcessorConfig {\n /**\n * Name for the processor (e.g., \"order-enrichment\")\n */\n name: string;\n\n /**\n * Expected stage names (for documentation/validation).\n * Stages can be run in any order.\n */\n stages?: string[];\n}\n\n/**\n * Options for producing output messages.\n */\nexport interface ProduceOptions {\n /**\n * Create a SpanLink to the input message's extracted context.\n * Useful for lineage tracking.\n * @default false\n */\n linkToInput?: boolean;\n\n /**\n * Additional headers to include (merged with trace headers).\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Context passed to the processor callback.\n */\nexport interface ProcessorContext {\n /**\n * The processor-level span.\n */\n span: Span;\n\n /**\n * Execute a named stage with automatic span creation.\n *\n * @param stageName - Name of the stage (e.g., \"validate\", \"enrich\")\n * @param fn - Stage function to execute\n * @returns Result of the stage function\n */\n stage<T>(stageName: string, fn: () => T | Promise<T>): Promise<T>;\n\n /**\n * Produce a message with proper span creation and header injection.\n *\n * The returned headers should be used when actually sending the message.\n *\n * @param topic - Destination topic\n * @param payload - Message payload\n * @param options - Produce options\n * @returns Headers to use when sending (includes trace context)\n */\n produce(\n topic: string,\n payload: unknown,\n options?: ProduceOptions,\n ): Promise<Record<string, string>>;\n\n /**\n * Get the extracted context from the input message.\n * Useful for creating manual links or context propagation.\n */\n inputContext: SpanContext | undefined;\n}\n\n/**\n * Processor callback type.\n */\nexport type ProcessorCallback<T> = (ctx: ProcessorContext) => Promise<T>;\n\n/**\n * Stream processor instance.\n */\nexport interface StreamProcessor {\n /**\n * Run the processor on an input message.\n *\n * @param message - Input Kafka message\n * @param callback - Processor callback with stage/produce helpers\n * @returns Result of the processor callback\n */\n run<T>(message: StreamMessage, callback: ProcessorCallback<T>): Promise<T>;\n}\n\n/**\n * Create a stream processor for pipeline-style message processing.\n *\n * @param config - Processor configuration\n * @returns Stream processor instance\n *\n * @example\n * ```typescript\n * const processor = createStreamProcessor({\n * name: 'order-enrichment',\n * stages: ['validate', 'enrich', 'publish'],\n * });\n *\n * await processor.run(message, async (ctx) => {\n * const validated = await ctx.stage('validate', async () => {\n * return validateOrder(message.value);\n * });\n *\n * const enriched = await ctx.stage('enrich', async () => {\n * return enrichWithCustomerData(validated);\n * });\n *\n * await ctx.stage('publish', async () => {\n * const headers = await ctx.produce('enriched-orders', enriched, {\n * linkToInput: true,\n * });\n * await producer.send({\n * topic: 'enriched-orders',\n * messages: [{ value: JSON.stringify(enriched), headers }],\n * });\n * });\n * });\n * ```\n */\nexport function createStreamProcessor(\n config: StreamProcessorConfig,\n): StreamProcessor {\n const { name } = config;\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n return {\n async run<T>(\n message: StreamMessage,\n callback: ProcessorCallback<T>,\n ): Promise<T> {\n // Extract context from input message\n const normalizedHeaders = normalizeHeaders(message.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const inputSpanContext = trace.getSpanContext(extractedCtx);\n\n // Create processor span (inherits from extracted context if valid)\n const processorSpan = tracer.startSpan(\n name,\n {\n kind: SpanKind.CONSUMER,\n },\n inputSpanContext && trace.isSpanContextValid(inputSpanContext)\n ? extractedCtx\n : undefined,\n );\n\n processorSpan.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');\n processorSpan.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'process');\n\n const processorContext = trace.setSpan(context.active(), processorSpan);\n\n // Create context object with helpers\n const ctx: ProcessorContext = {\n span: processorSpan,\n inputContext: inputSpanContext,\n\n async stage<S>(\n stageName: string,\n fn: () => S | Promise<S>,\n ): Promise<S> {\n return context.with(processorContext, async () => {\n const stageSpan = tracer.startSpan(`${name}.${stageName}`, {\n kind: SpanKind.INTERNAL,\n });\n\n stageSpan.setAttribute('stream.stage', stageName);\n\n const stageContext = trace.setSpan(context.active(), stageSpan);\n\n try {\n const result = await context.with(stageContext, async () => {\n return await fn();\n });\n\n stageSpan.setStatus({ code: SpanStatusCode.OK });\n stageSpan.end();\n\n return result;\n } catch (error) {\n stageSpan.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n stageSpan.recordException(error);\n } else {\n stageSpan.recordException(new Error(String(error)));\n }\n stageSpan.end();\n\n throw error;\n }\n });\n },\n\n async produce(\n topic: string,\n _payload: unknown,\n options?: ProduceOptions,\n ): Promise<Record<string, string>> {\n const { linkToInput = false, headers: extraHeaders = {} } =\n options ?? {};\n\n // Build links\n const links: SpanLink[] = [];\n if (\n linkToInput &&\n inputSpanContext &&\n trace.isSpanContextValid(inputSpanContext)\n ) {\n links.push({ context: inputSpanContext });\n }\n\n // Create produce span as child of current context (the stage span)\n const produceSpan = tracer.startSpan(`${name}.produce`, {\n kind: SpanKind.PRODUCER,\n links,\n });\n\n produceSpan.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'kafka');\n produceSpan.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, topic);\n produceSpan.setAttribute(SEMATTRS_MESSAGING_OPERATION, 'publish');\n\n // Inject trace context from within the produce span\n const produceContext = trace.setSpan(context.active(), produceSpan);\n\n return context.with(produceContext, () => {\n const headers = injectTraceHeaders(extraHeaders, {\n includeCorrelationIdHeader: true,\n });\n\n produceSpan.setStatus({ code: SpanStatusCode.OK });\n produceSpan.end();\n\n return headers;\n });\n },\n };\n\n try {\n const result = await context.with(processorContext, async () => {\n return await callback(ctx);\n });\n\n processorSpan.setStatus({ code: SpanStatusCode.OK });\n processorSpan.end();\n\n return result;\n } catch (error) {\n processorSpan.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n processorSpan.recordException(error);\n } else {\n processorSpan.recordException(new Error(String(error)));\n }\n processorSpan.end();\n\n throw error;\n }\n },\n };\n}\n","/**\n * Consumer metrics for Kafka observability.\n *\n * Provides opt-in metrics collection for Kafka consumers, including\n * consumer lag tracking with configurable strategies.\n *\n * @example\n * ```typescript\n * import { ConsumerMetrics } from 'autotel-plugins/kafka';\n *\n * const metrics = new ConsumerMetrics({\n * consumer,\n * metricsPrefix: 'kafka.consumer',\n * enableLag: true,\n * lagStrategy: 'polling',\n * lagPollIntervalMs: 30000,\n * });\n *\n * // Start metrics collection\n * await metrics.start();\n *\n * // ... consumer runs ...\n *\n * // Stop metrics collection\n * await metrics.stop();\n * ```\n */\n\nimport { metrics as otelMetrics } from '@opentelemetry/api';\n\n/**\n * Lag tracking strategy.\n * - 'polling': Explicit admin calls (accurate, more overhead)\n * - 'event': Consumer events only (less accurate, no admin calls)\n * - 'hybrid': Event-based with periodic validation (default if enabled)\n */\nexport type LagStrategy = 'polling' | 'event' | 'hybrid';\n\n/**\n * Minimal Kafka consumer interface for metrics collection.\n * Matches KafkaJS consumer shape.\n */\nexport interface KafkaConsumer {\n on(event: string, listener: (...args: unknown[]) => void): void;\n describeGroup?(): Promise<{\n members: Array<{\n memberId: string;\n clientId: string;\n memberAssignment: Buffer;\n }>;\n state: string;\n }>;\n}\n\n/**\n * Minimal Kafka admin interface for lag calculation.\n */\nexport interface KafkaAdmin {\n fetchTopicOffsets(\n topic: string,\n ): Promise<\n Array<{ partition: number; offset: string; high: string; low: string }>\n >;\n fetchOffsets(options: { groupId: string; topics: string[] }): Promise<\n Array<{\n topic: string;\n partitions: Array<{ partition: number; offset: string }>;\n }>\n >;\n}\n\n/**\n * Configuration for consumer metrics.\n */\nexport interface ConsumerMetricsConfig {\n /**\n * The Kafka consumer to monitor.\n */\n consumer: KafkaConsumer;\n\n /**\n * Optional Kafka admin client for lag calculation.\n * Required if enableLag is true and lagStrategy is 'polling' or 'hybrid'.\n */\n admin?: KafkaAdmin;\n\n /**\n * Consumer group ID (required for lag calculation).\n */\n groupId?: string;\n\n /**\n * Topics to monitor for lag.\n */\n topics?: string[];\n\n /**\n * Prefix for metric names.\n * @default 'kafka.consumer'\n */\n metricsPrefix?: string;\n\n /**\n * Enable consumer lag tracking.\n * @default false\n */\n enableLag?: boolean;\n\n /**\n * Strategy for lag calculation.\n * @default 'hybrid'\n */\n lagStrategy?: LagStrategy;\n\n /**\n * Interval for lag polling in milliseconds.\n * Required when enableLag is true and lagStrategy is 'polling'.\n * @default 30000\n */\n lagPollIntervalMs?: number;\n}\n\n/**\n * Internal state for tracking offsets.\n */\ninterface PartitionState {\n topic: string;\n partition: number;\n currentOffset: string;\n highWatermark?: string;\n}\n\n/**\n * Consumer metrics collector.\n *\n * Provides:\n * - kafka.consumer.messages_processed (counter)\n * - kafka.consumer.processing_duration (histogram)\n * - kafka.consumer.batch_size (histogram)\n * - kafka.consumer.rebalances (counter)\n * - kafka.consumer.lag (gauge, opt-in)\n */\nexport class ConsumerMetrics {\n private readonly config: Required<\n Pick<\n ConsumerMetricsConfig,\n 'metricsPrefix' | 'enableLag' | 'lagStrategy' | 'lagPollIntervalMs'\n >\n > &\n ConsumerMetricsConfig;\n\n private readonly meter;\n private readonly messagesProcessed;\n private readonly processingDuration;\n private readonly batchSize;\n private readonly rebalances;\n private readonly lag;\n\n private partitionStates: Map<string, PartitionState> = new Map();\n private lagPollInterval?: ReturnType<typeof setInterval>;\n private isRunning = false;\n\n constructor(config: ConsumerMetricsConfig) {\n // Validate config\n if (\n config.enableLag &&\n config.lagStrategy === 'polling' &&\n !config.lagPollIntervalMs\n ) {\n throw new Error('Lag polling requires lagPollIntervalMs');\n }\n\n if (\n config.enableLag &&\n (config.lagStrategy === 'polling' || config.lagStrategy === 'hybrid')\n ) {\n if (!config.admin) {\n throw new Error(\n `Lag strategy '${config.lagStrategy}' requires admin client`,\n );\n }\n if (!config.groupId) {\n throw new Error('Lag tracking requires groupId');\n }\n if (!config.topics || config.topics.length === 0) {\n throw new Error('Lag tracking requires topics');\n }\n }\n\n this.config = {\n ...config,\n metricsPrefix: config.metricsPrefix ?? 'kafka.consumer',\n enableLag: config.enableLag ?? false,\n lagStrategy: config.lagStrategy ?? 'hybrid',\n lagPollIntervalMs: config.lagPollIntervalMs ?? 30_000,\n };\n\n // Initialize meter\n this.meter = otelMetrics.getMeter('autotel-plugins/kafka');\n const prefix = this.config.metricsPrefix;\n\n // Create metric instruments\n this.messagesProcessed = this.meter.createCounter(\n `${prefix}.messages_processed`,\n {\n description: 'Total number of messages processed',\n },\n );\n\n this.processingDuration = this.meter.createHistogram(\n `${prefix}.processing_duration`,\n {\n description: 'Message processing duration in milliseconds',\n unit: 'ms',\n },\n );\n\n this.batchSize = this.meter.createHistogram(`${prefix}.batch_size`, {\n description: 'Number of messages in each batch',\n });\n\n this.rebalances = this.meter.createCounter(`${prefix}.rebalances`, {\n description: 'Number of consumer group rebalances',\n });\n\n this.lag = this.meter.createObservableGauge(`${prefix}.lag`, {\n description: 'Consumer lag per topic-partition',\n });\n\n // Set up lag observation callback\n if (this.config.enableLag) {\n this.lag.addCallback((observableResult) => {\n for (const [, state] of this.partitionStates.entries()) {\n if (state.highWatermark) {\n const lagValue =\n BigInt(state.highWatermark) - BigInt(state.currentOffset);\n observableResult.observe(Number(lagValue), {\n topic: state.topic,\n partition: state.partition,\n });\n }\n }\n });\n }\n }\n\n /**\n * Start metrics collection.\n */\n async start(): Promise<void> {\n if (this.isRunning) return;\n this.isRunning = true;\n\n const { consumer } = this.config;\n\n // Attach event listeners\n consumer.on('consumer.rebalancing', () => {\n this.rebalances.add(1, { event: 'rebalancing' });\n });\n\n consumer.on('consumer.group_join', () => {\n this.rebalances.add(1, { event: 'group_join' });\n });\n\n // Start lag polling if configured\n if (\n this.config.enableLag &&\n (this.config.lagStrategy === 'polling' ||\n this.config.lagStrategy === 'hybrid')\n ) {\n await this.pollLag();\n this.lagPollInterval = setInterval(\n () => this.pollLag().catch(() => {}),\n this.config.lagPollIntervalMs,\n );\n }\n }\n\n /**\n * Stop metrics collection.\n */\n async stop(): Promise<void> {\n if (!this.isRunning) return;\n this.isRunning = false;\n\n if (this.lagPollInterval) {\n clearInterval(this.lagPollInterval);\n this.lagPollInterval = undefined;\n }\n }\n\n /**\n * Record a message being processed.\n *\n * @param topic - Message topic\n * @param partition - Message partition\n * @param durationMs - Processing duration in milliseconds\n */\n recordMessageProcessed(\n topic: string,\n partition: number,\n durationMs?: number,\n ): void {\n this.messagesProcessed.add(1, { topic, partition });\n\n if (durationMs !== undefined) {\n this.processingDuration.record(durationMs, { topic, partition });\n }\n }\n\n /**\n * Record a batch being processed.\n *\n * @param topic - Batch topic\n * @param partition - Batch partition\n * @param size - Number of messages in the batch\n */\n recordBatch(topic: string, partition: number, size: number): void {\n this.batchSize.record(size, { topic, partition });\n }\n\n /**\n * Update offset state for event-based lag tracking.\n *\n * @param topic - Topic name\n * @param partition - Partition number\n * @param offset - Current consumer offset\n * @param highWatermark - Optional high watermark\n */\n updateOffset(\n topic: string,\n partition: number,\n offset: string,\n highWatermark?: string,\n ): void {\n const key = `${topic}-${partition}`;\n const existing = this.partitionStates.get(key);\n\n this.partitionStates.set(key, {\n topic,\n partition,\n currentOffset: offset,\n highWatermark: highWatermark ?? existing?.highWatermark,\n });\n }\n\n /**\n * Poll for lag using admin client.\n */\n private async pollLag(): Promise<void> {\n const { admin, groupId, topics } = this.config;\n if (!admin || !groupId || !topics) return;\n\n try {\n // Fetch committed offsets for the consumer group\n const committedOffsets = await admin.fetchOffsets({\n groupId,\n topics,\n });\n\n // For each topic, fetch the high watermarks\n for (const topicOffsets of committedOffsets) {\n const topicHighWatermarks = await admin.fetchTopicOffsets(\n topicOffsets.topic,\n );\n\n for (const partition of topicOffsets.partitions) {\n const hwm = topicHighWatermarks.find(\n (p) => p.partition === partition.partition,\n );\n if (hwm) {\n const key = `${topicOffsets.topic}-${partition.partition}`;\n this.partitionStates.set(key, {\n topic: topicOffsets.topic,\n partition: partition.partition,\n currentOffset: partition.offset,\n highWatermark: hwm.high,\n });\n }\n }\n }\n } catch {\n // Silently fail - lag metrics are best-effort\n }\n }\n}\n","/**\n * Stream events instrumentation for Kafka consumers.\n *\n * Provides visibility into consumer lifecycle events like rebalances,\n * errors, and heartbeats. Defaults to events mode (not spans) to\n * avoid span explosion.\n *\n * @example\n * ```typescript\n * import { instrumentConsumerEvents } from 'autotel-plugins/kafka';\n *\n * instrumentConsumerEvents(consumer, {\n * mode: 'events',\n * traceRebalances: true,\n * traceErrors: true,\n * traceHeartbeats: false,\n * });\n * ```\n */\n\nimport {\n otelTrace as trace,\n SpanKind,\n SpanStatusCode,\n type Span,\n} from 'autotel';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/kafka';\n\n/**\n * Event mode for consumer events.\n * - 'events': Attach events to existing lifecycle span (lower overhead)\n * - 'spans': Create separate spans for each event (more detail)\n */\nexport type EventMode = 'events' | 'spans';\n\n/**\n * Minimal Kafka consumer interface for event instrumentation.\n */\nexport interface EventConsumer {\n on(event: string, listener: (...args: unknown[]) => void): void;\n off?(event: string, listener: (...args: unknown[]) => void): void;\n}\n\n/**\n * Configuration for consumer event instrumentation.\n */\nexport interface ConsumerEventsConfig {\n /**\n * Event mode: 'events' attaches to spans, 'spans' creates new spans.\n * @default 'events'\n */\n mode?: EventMode;\n\n /**\n * Trace rebalance events (GROUP_JOIN, REBALANCING).\n * @default true\n */\n traceRebalances?: boolean;\n\n /**\n * Trace error events (CRASH, DISCONNECT).\n * @default true\n */\n traceErrors?: boolean;\n\n /**\n * Trace heartbeat events.\n * @default false (too noisy for most use cases)\n */\n traceHeartbeats?: boolean;\n\n /**\n * Optional lifecycle span to attach events to.\n * Only used when mode is 'events'.\n */\n lifecycleSpan?: Span;\n}\n\n/**\n * Cleanup function returned by instrumentConsumerEvents.\n */\nexport type CleanupFunction = () => void;\n\n/**\n * KafkaJS event types we're interested in.\n */\nconst REBALANCE_EVENTS = [\n 'consumer.group_join',\n 'consumer.rebalancing',\n 'consumer.stop',\n] as const;\n\nconst ERROR_EVENTS = [\n 'consumer.crash',\n 'consumer.disconnect',\n 'consumer.network.request_timeout',\n] as const;\n\nconst HEARTBEAT_EVENTS = ['consumer.heartbeat'] as const;\n\n/**\n * Instrument a Kafka consumer's lifecycle events.\n *\n * Returns a cleanup function to remove event listeners.\n *\n * @param consumer - Kafka consumer to instrument\n * @param config - Instrumentation configuration\n * @returns Cleanup function\n *\n * @example\n * ```typescript\n * const cleanup = instrumentConsumerEvents(consumer, {\n * mode: 'events',\n * traceRebalances: true,\n * traceErrors: true,\n * });\n *\n * // Later, to clean up:\n * cleanup();\n * ```\n */\nexport function instrumentConsumerEvents(\n consumer: EventConsumer,\n config: ConsumerEventsConfig = {},\n): CleanupFunction {\n const {\n mode = 'events',\n traceRebalances = true,\n traceErrors = true,\n traceHeartbeats = false,\n lifecycleSpan,\n } = config;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n const listeners: Array<{\n event: string;\n listener: (...args: unknown[]) => void;\n }> = [];\n\n // Helper to add a listener and track it\n const addListener = (\n event: string,\n listener: (...args: unknown[]) => void,\n ) => {\n consumer.on(event, listener);\n listeners.push({ event, listener });\n };\n\n // Rebalance events\n if (traceRebalances) {\n for (const event of REBALANCE_EVENTS) {\n addListener(event, (payload: unknown) => {\n if (mode === 'spans') {\n createEventSpan(tracer, event, payload);\n } else if (lifecycleSpan) {\n lifecycleSpan.addEvent(event, extractEventAttributes(payload));\n }\n });\n }\n }\n\n // Error events\n if (traceErrors) {\n for (const event of ERROR_EVENTS) {\n addListener(event, (payload: unknown) => {\n if (mode === 'spans') {\n createErrorSpan(tracer, event, payload);\n } else if (lifecycleSpan) {\n lifecycleSpan.addEvent(event, {\n ...extractEventAttributes(payload),\n 'event.severity': 'error',\n });\n\n // Also record exception if it's a crash\n if (event === 'consumer.crash' && isErrorPayload(payload)) {\n lifecycleSpan.recordException(payload.error);\n }\n }\n });\n }\n }\n\n // Heartbeat events\n if (traceHeartbeats) {\n for (const event of HEARTBEAT_EVENTS) {\n addListener(event, (payload: unknown) => {\n if (mode === 'spans') {\n createEventSpan(tracer, event, payload);\n } else if (lifecycleSpan) {\n lifecycleSpan.addEvent(event, extractEventAttributes(payload));\n }\n });\n }\n }\n\n // Return cleanup function\n return () => {\n if (consumer.off) {\n for (const { event, listener } of listeners) {\n consumer.off(event, listener);\n }\n }\n listeners.length = 0;\n };\n}\n\n/**\n * Create a span for a consumer event.\n */\nfunction createEventSpan(\n tracer: ReturnType<typeof trace.getTracer>,\n eventName: string,\n payload: unknown,\n): void {\n const span = tracer.startSpan(`kafka.consumer.${eventName}`, {\n kind: SpanKind.INTERNAL,\n });\n\n const attributes = extractEventAttributes(payload);\n for (const [key, value] of Object.entries(attributes)) {\n span.setAttribute(key, value);\n }\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n}\n\n/**\n * Create an error span for a consumer error event.\n */\nfunction createErrorSpan(\n tracer: ReturnType<typeof trace.getTracer>,\n eventName: string,\n payload: unknown,\n): void {\n const span = tracer.startSpan(`kafka.consumer.${eventName}`, {\n kind: SpanKind.INTERNAL,\n });\n\n const attributes = extractEventAttributes(payload);\n for (const [key, value] of Object.entries(attributes)) {\n span.setAttribute(key, value);\n }\n\n span.setStatus({ code: SpanStatusCode.ERROR });\n\n if (isErrorPayload(payload)) {\n span.recordException(payload.error);\n }\n\n span.end();\n}\n\n/**\n * Extract attributes from event payload.\n */\nfunction extractEventAttributes(\n payload: unknown,\n): Record<string, string | number | boolean> {\n const attributes: Record<string, string | number | boolean> = {};\n\n if (!payload || typeof payload !== 'object') {\n return attributes;\n }\n\n const p = payload as Record<string, unknown>;\n\n if (typeof p.groupId === 'string') {\n attributes['messaging.kafka.consumer.group'] = p.groupId;\n }\n\n if (typeof p.memberId === 'string') {\n attributes['messaging.kafka.consumer.member_id'] = p.memberId;\n }\n\n if (typeof p.leaderId === 'string') {\n attributes['messaging.kafka.consumer.leader_id'] = p.leaderId;\n }\n\n if (typeof p.duration === 'number') {\n attributes['event.duration_ms'] = p.duration;\n }\n\n if (typeof p.isLeader === 'boolean') {\n attributes['messaging.kafka.consumer.is_leader'] = p.isLeader;\n }\n\n if (Array.isArray(p.memberAssignment)) {\n attributes['messaging.kafka.consumer.assignment_count'] =\n p.memberAssignment.length;\n }\n\n if (typeof p.type === 'string') {\n attributes['event.type'] = p.type;\n }\n\n return attributes;\n}\n\n/**\n * Type guard for error payloads.\n */\nfunction isErrorPayload(payload: unknown): payload is { error: Error } {\n return (\n payload !== null &&\n typeof payload === 'object' &&\n 'error' in payload &&\n payload.error instanceof Error\n );\n}\n","/**\n * Header utilities for RabbitMQ message processing.\n *\n * Uses OpenTelemetry propagators internally for context extraction,\n * ensuring compatibility with W3C Trace Context, B3, and other formats.\n */\n\nimport { propagation, ROOT_CONTEXT, type Context } from 'autotel';\nimport type { RawAmqpHeaders } from './types';\n\n/**\n * Normalize AMQP headers from raw format to string record.\n *\n * Handles:\n * - undefined/null headers -> empty object\n * - Buffer values -> UTF-8 strings (with base64 fallback for invalid UTF-8)\n * - undefined values -> removed from output\n * - string values -> passed through\n * - number/boolean values -> String() conversion\n * - object values -> JSON.stringify() (dropped if > 1KB)\n *\n * @param headers - Raw AMQP headers (Record or undefined)\n * @returns Normalized headers as string record\n *\n * @example\n * ```typescript\n * const raw = {\n * traceparent: Buffer.from('00-abc...'),\n * 'content-type': 'application/json',\n * optionalHeader: undefined,\n * retryCount: 3,\n * };\n * const normalized = normalizeHeaders(raw);\n * // { traceparent: '00-abc...', 'content-type': 'application/json', retryCount: '3' }\n * ```\n */\nexport function normalizeHeaders(\n headers?: RawAmqpHeaders,\n): Record<string, string> {\n if (!headers) {\n return {};\n }\n\n const normalized: Record<string, string> = {};\n const MAX_OBJECT_SIZE = 1024; // 1KB limit for stringified objects\n\n for (const [key, value] of Object.entries(headers)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (Buffer.isBuffer(value)) {\n // Try UTF-8 decode, fall back to base64 with prefix\n try {\n const decoded = value.toString('utf8');\n // Check if the string is valid UTF-8 by re-encoding and comparing\n normalized[key] = Buffer.from(decoded, 'utf8').equals(value)\n ? decoded\n : `base64:${value.toString('base64')}`;\n } catch {\n normalized[key] = `base64:${value.toString('base64')}`;\n }\n } else if (typeof value === 'string') {\n normalized[key] = value;\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n normalized[key] = String(value);\n } else if (typeof value === 'object') {\n // Stringify objects, drop if too large\n try {\n const json = JSON.stringify(value);\n if (json.length <= MAX_OBJECT_SIZE) {\n normalized[key] = json;\n }\n // Silently drop objects > 1KB\n } catch {\n // Silently drop objects that can't be stringified\n }\n }\n }\n\n return normalized;\n}\n\n/**\n * TextMapGetter for case-insensitive header lookup.\n *\n * AMQP headers can have varying case, but trace context headers\n * (traceparent, tracestate, baggage) should be matched case-insensitively\n * for maximum compatibility.\n */\nconst caseInsensitiveGetter = {\n get(carrier: Record<string, string>, key: string): string | undefined {\n const lowerKey = key.toLowerCase();\n for (const [k, v] of Object.entries(carrier)) {\n if (k.toLowerCase() === lowerKey) {\n return v;\n }\n }\n return undefined;\n },\n keys(carrier: Record<string, string>): string[] {\n return Object.keys(carrier);\n },\n};\n\n/**\n * Extract trace context from normalized headers using OTel propagators.\n *\n * This is a pure function that does not activate any context.\n * The returned Context can be used to:\n * - Start spans as children of the extracted context\n * - Create links to the extracted context\n *\n * Returns ROOT_CONTEXT if no trace context is found in headers.\n *\n * @param headers - Normalized headers (use normalizeHeaders first)\n * @returns OpenTelemetry Context with extracted trace context\n *\n * @example\n * ```typescript\n * import { normalizeHeaders, extractTraceContext } from 'autotel-plugins/rabbitmq';\n * import { trace } from '@opentelemetry/api';\n *\n * const headers = normalizeHeaders(message.properties.headers);\n * const extractedCtx = extractTraceContext(headers);\n *\n * // Get span context from extracted context\n * const spanContext = trace.getSpanContext(extractedCtx);\n * if (spanContext && trace.isSpanContextValid(spanContext)) {\n * // Valid remote context extracted\n * }\n * ```\n */\nexport function extractTraceContext(headers: Record<string, string>): Context {\n return propagation.extract(ROOT_CONTEXT, headers, caseInsensitiveGetter);\n}\n","/**\n * Correlation ID utilities for RabbitMQ message tracing.\n *\n * Provides consistent correlation ID handling across producers and consumers:\n * - Inject trace headers and correlation ID into outgoing messages\n * - Extract correlation ID from incoming messages\n * - Derive correlation ID from current trace context\n */\n\nimport {\n propagation,\n context,\n otelTrace as trace,\n type TextMapSetter,\n} from 'autotel';\nimport type { InjectOptions } from './types';\nimport { CORRELATION_ID_HEADER } from '../common/constants';\n\n/**\n * TextMapSetter for injecting headers.\n */\nconst headerSetter: TextMapSetter<Record<string, string>> = {\n set(carrier: Record<string, string>, key: string, value: string): void {\n carrier[key] = value;\n },\n};\n\n/**\n * Derive correlation ID from current trace context.\n *\n * Priority:\n * 1. Baggage 'correlation-id' if present\n * 2. First 16 characters of trace ID (64-bit for compatibility)\n * 3. Empty string if no active trace\n *\n * Note: Uses first 16 chars of trace ID to be stable per trace, not per attempt.\n *\n * @returns Correlation ID derived from context\n *\n * @example\n * ```typescript\n * import { deriveCorrelationId } from 'autotel-plugins/rabbitmq';\n *\n * // Inside a traced operation\n * const correlationId = deriveCorrelationId();\n * // '4bf92f3577b34da6' (first 16 chars of trace ID)\n * ```\n */\nexport function deriveCorrelationId(): string {\n // Check baggage first\n const activeBaggage = propagation.getActiveBaggage();\n const baggageCorrelationId = activeBaggage?.getEntry('correlation-id');\n if (baggageCorrelationId?.value) {\n return baggageCorrelationId.value;\n }\n\n // Fall back to trace ID (first 16 chars)\n const activeSpan = trace.getActiveSpan();\n if (activeSpan) {\n const spanContext = activeSpan.spanContext();\n // Return first 16 chars (64-bit) for compatibility with systems\n // that don't support full 128-bit trace IDs\n return spanContext.traceId.slice(0, 16);\n }\n\n return '';\n}\n\n/**\n * Extract correlation ID from message headers or AMQP correlationId property.\n *\n * Priority:\n * 1. AMQP correlationId property (if provided)\n * 2. x-correlation-id header (case-insensitive)\n *\n * @param headers - Normalized headers (string values)\n * @param amqpCorrelationId - Optional AMQP correlationId property value\n * @returns Correlation ID if found, undefined otherwise\n *\n * @example\n * ```typescript\n * import { extractCorrelationId, normalizeHeaders } from 'autotel-plugins/rabbitmq';\n *\n * const headers = normalizeHeaders(message.properties.headers);\n * const correlationId = extractCorrelationId(headers, message.properties.correlationId);\n * if (correlationId) {\n * logger.info({ correlationId }, 'Processing message');\n * }\n * ```\n */\nexport function extractCorrelationId(\n headers: Record<string, string>,\n amqpCorrelationId?: string,\n): string | undefined {\n // Priority 1: AMQP correlationId property\n if (amqpCorrelationId) {\n return amqpCorrelationId;\n }\n\n // Priority 2: x-correlation-id header (case-insensitive)\n const lowerKey = CORRELATION_ID_HEADER.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === lowerKey) {\n return value;\n }\n }\n return undefined;\n}\n\n/**\n * Inject trace headers into outgoing message headers.\n *\n * Uses OpenTelemetry propagators to inject W3C Trace Context (traceparent, tracestate)\n * and optionally adds x-correlation-id header (default: true).\n *\n * Note: Baggage is injected automatically when W3CBaggagePropagator is registered.\n *\n * @param base - Base headers to merge with injected headers\n * @param options - Injection options\n * @returns Headers with trace context injected\n *\n * @example\n * ```typescript\n * import { injectTraceHeaders } from 'autotel-plugins/rabbitmq';\n *\n * // Publisher: inject headers with correlation ID\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * channel.publish('exchange', 'routing.key', content, { headers });\n * ```\n *\n * @example With explicit correlation ID\n * ```typescript\n * const headers = injectTraceHeaders({}, {\n * correlationId: 'order-12345',\n * includeCorrelationIdHeader: true,\n * });\n * ```\n */\nexport function injectTraceHeaders(\n base: Record<string, string> = {},\n options: InjectOptions = {},\n): Record<string, string> {\n const { correlationId, includeCorrelationIdHeader = true } = options;\n\n const carrier = { ...base };\n\n // Inject trace context (traceparent, tracestate)\n // Note: If W3CBaggagePropagator is registered, baggage is also injected automatically\n propagation.inject(context.active(), carrier, headerSetter);\n\n // Add correlation ID if requested\n if (includeCorrelationIdHeader) {\n const corrId = correlationId ?? deriveCorrelationId();\n if (corrId) {\n carrier[CORRELATION_ID_HEADER] = corrId;\n }\n }\n\n return carrier;\n}\n","/**\n * Processing span wrapper for RabbitMQ message handling.\n *\n * Creates processing spans with proper context handling, supporting:\n * - Context mode control (inherit/link/none)\n * - Messaging attributes for consistent querying\n * - Integration with official amqplib instrumentation\n * - Deferred ack tracking mode\n */\n\nimport {\n otelTrace as trace,\n context,\n SpanKind,\n SpanStatusCode,\n type Span,\n type SpanContext,\n type SpanLink,\n} from 'autotel';\nimport type {\n ConsumeDescriptor,\n ContextMode,\n ConsumeSpanCallback,\n DeferredConsumeSpanCallback,\n AckControls,\n} from './types';\nimport { normalizeHeaders, extractTraceContext } from './headers';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_OPERATION_NAME,\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_EXCHANGE,\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY,\n SEMATTRS_MESSAGING_MESSAGE_ID,\n SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID,\n SEMATTRS_MESSAGING_CONSUMER_ID,\n SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT,\n SEMATTRS_MESSAGING_RABBITMQ_REQUEUE,\n} from '../common/constants';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/rabbitmq';\n\n/**\n * Check if a span context is valid (has both traceId and spanId).\n */\nfunction isValidSpanContext(\n spanContext: SpanContext | undefined,\n): spanContext is SpanContext {\n return !!(\n spanContext &&\n spanContext.traceId &&\n spanContext.spanId &&\n trace.isSpanContextValid(spanContext)\n );\n}\n\n/**\n * Validate configuration for deferred span mode.\n */\nfunction validateDeferredConfig(descriptor: ConsumeDescriptor): void {\n if (descriptor.deferSpanEnd && !descriptor.ackTimeoutMs) {\n throw new Error('deferSpanEnd requires ackTimeoutMs to be set');\n }\n}\n\n/**\n * Create a consume/processing span for RabbitMQ message handling.\n *\n * **Context Mode Behavior:**\n *\n * | Mode | Behavior |\n * |------|----------|\n * | `inherit` | Extracted remote context becomes the **parent**. If headers contain context, it overrides any active span. |\n * | `link` | Consumer span parents to current active context (or root). Extracted context becomes a **SpanLink**. |\n * | `none` | Ignore extracted context entirely. Consumer span uses current active context (or root). No links created. |\n *\n * @param descriptor - Processing span configuration\n * @param fn - Async callback to execute within the span\n * @returns Promise resolving to callback result\n * @throws Error if span creation fails or callback throws\n *\n * @example Basic usage\n * ```typescript\n * import { withConsumeSpan } from 'autotel-plugins/rabbitmq';\n *\n * channel.consume('queue', async (msg) => {\n * if (!msg) return;\n * try {\n * await withConsumeSpan({\n * name: 'order.process',\n * headers: msg.properties.headers,\n * contextMode: 'inherit',\n * queue: 'orders',\n * exchange: 'orders-exchange',\n * routingKey: msg.fields.routingKey,\n * }, async (span) => {\n * await processOrder(msg);\n * channel.ack(msg);\n * });\n * } catch (error) {\n * channel.nack(msg, false, false);\n * }\n * });\n * ```\n *\n * @example With deferred ack tracking\n * ```typescript\n * await withConsumeSpan({\n * name: 'order.process',\n * headers: msg.properties.headers,\n * deferSpanEnd: true,\n * ackTimeoutMs: 60000,\n * }, async (span, controls) => {\n * await processOrder(msg);\n * controls.ack(); // Ends span with success\n * });\n * ```\n */\nexport function withConsumeSpan<T>(\n descriptor: ConsumeDescriptor & { deferSpanEnd: true; ackTimeoutMs: number },\n fn: DeferredConsumeSpanCallback<T>,\n): Promise<T>;\nexport function withConsumeSpan<T>(\n descriptor: ConsumeDescriptor & { deferSpanEnd?: false },\n fn: ConsumeSpanCallback<T>,\n): Promise<T>;\nexport function withConsumeSpan<T>(\n descriptor: ConsumeDescriptor,\n fn: ConsumeSpanCallback<T> | DeferredConsumeSpanCallback<T>,\n): Promise<T>;\nexport async function withConsumeSpan<T>(\n descriptor: ConsumeDescriptor,\n fn: ConsumeSpanCallback<T> | DeferredConsumeSpanCallback<T>,\n): Promise<T> {\n validateDeferredConfig(descriptor);\n\n const {\n name,\n headers,\n contextMode = 'inherit',\n links = [],\n queue,\n exchange,\n routingKey,\n messageId,\n correlationId,\n consumerTag,\n deferSpanEnd = false,\n ackTimeoutMs,\n } = descriptor;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n const normalizedHeaders = normalizeHeaders(headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const extractedSpanContext = trace.getSpanContext(extractedCtx);\n\n // Determine parent context and links based on context mode\n const { parentContext, spanLinks } = resolveContextAndLinks(\n contextMode,\n extractedSpanContext,\n links,\n );\n\n // Create span with computed parent and links\n const span = tracer.startSpan(\n name,\n {\n kind: SpanKind.CONSUMER,\n links: spanLinks,\n },\n parentContext,\n );\n\n // Set messaging attributes\n setMessagingAttributes(span, {\n queue,\n exchange,\n routingKey,\n messageId,\n correlationId,\n consumerTag,\n });\n\n // Execute callback within span context\n const spanContext = trace.setSpan(context.active(), span);\n\n if (deferSpanEnd) {\n return executeDeferredMode(\n span,\n spanContext,\n fn as DeferredConsumeSpanCallback<T>,\n ackTimeoutMs!,\n );\n }\n\n return executeImmediateMode(span, spanContext, fn as ConsumeSpanCallback<T>);\n}\n\n/**\n * Execute callback in immediate mode - span ends when callback completes.\n */\nasync function executeImmediateMode<T>(\n span: Span,\n spanContext: ReturnType<typeof context.active>,\n fn: ConsumeSpanCallback<T>,\n): Promise<T> {\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span);\n });\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n\n throw error;\n }\n}\n\n/**\n * Execute callback in deferred mode - span ends when ack/nack/reject is called.\n */\nasync function executeDeferredMode<T>(\n span: Span,\n spanContext: ReturnType<typeof context.active>,\n fn: DeferredConsumeSpanCallback<T>,\n ackTimeoutMs: number,\n): Promise<T> {\n let spanEnded = false;\n\n // Create a reference object to hold the timeout ID\n const timeoutRef: { id?: ReturnType<typeof setTimeout> } = {};\n\n const endSpan = (\n status: 'ok' | 'error',\n outcome?: 'ack' | 'nack' | 'reject',\n requeue?: boolean,\n ) => {\n if (spanEnded) return;\n spanEnded = true;\n\n if (timeoutRef.id) {\n clearTimeout(timeoutRef.id);\n }\n\n if (outcome) {\n span.setAttribute(SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT, outcome);\n }\n if (requeue !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_RABBITMQ_REQUEUE, requeue);\n }\n\n span.setStatus({\n code: status === 'ok' ? SpanStatusCode.OK : SpanStatusCode.ERROR,\n });\n span.end();\n };\n\n const controls: AckControls = {\n ack() {\n endSpan('ok', 'ack');\n },\n nack(options?: { requeue?: boolean }) {\n endSpan('ok', 'nack', options?.requeue ?? true);\n },\n reject(options?: { requeue?: boolean }) {\n endSpan('ok', 'reject', options?.requeue ?? false);\n },\n };\n\n // Set up timeout\n timeoutRef.id = setTimeout(() => {\n if (!spanEnded) {\n span.setAttribute('messaging.rabbitmq.ack_timeout', true);\n endSpan('error');\n }\n }, ackTimeoutMs);\n\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span, controls);\n });\n\n // If span wasn't ended by controls, end it now with OK\n if (!spanEnded) {\n endSpan('ok');\n }\n\n return result;\n } catch (error) {\n if (!spanEnded) {\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n endSpan('error');\n }\n\n throw error;\n }\n}\n\n/**\n * Resolve parent context and links based on context mode.\n *\n * RabbitMQ context mode differs from Kafka:\n * - `inherit` mode always uses extracted context as parent (messaging continues producer trace)\n * - This matches the expectation that RabbitMQ messages carry trace context\n */\nfunction resolveContextAndLinks(\n contextMode: ContextMode,\n extractedSpanContext: SpanContext | undefined,\n additionalLinks: SpanLink[],\n): {\n parentContext: ReturnType<typeof context.active>;\n spanLinks: SpanLink[];\n} {\n const activeContext = context.active();\n const hasValidExtracted = isValidSpanContext(extractedSpanContext);\n\n const spanLinks: SpanLink[] = [...additionalLinks];\n\n switch (contextMode) {\n case 'inherit': {\n // In inherit mode, extracted context always wins as parent\n // This is the key difference from Kafka - messaging should continue producer trace\n if (hasValidExtracted) {\n const extractedParentCtx = trace.setSpanContext(\n activeContext,\n extractedSpanContext,\n );\n return { parentContext: extractedParentCtx, spanLinks };\n }\n // No extracted context: use current active context\n return { parentContext: activeContext, spanLinks };\n }\n\n case 'link': {\n // Parent to current context (active span or root)\n // Link to extracted if valid\n if (hasValidExtracted) {\n spanLinks.push({ context: extractedSpanContext });\n }\n return { parentContext: activeContext, spanLinks };\n }\n\n case 'none': {\n // Parent to current context, no links to extracted\n return { parentContext: activeContext, spanLinks };\n }\n\n default: {\n // TypeScript exhaustive check\n const exhaustive: never = contextMode;\n throw new Error(`Unknown context mode: ${exhaustive}`);\n }\n }\n}\n\n/**\n * Set standard RabbitMQ messaging attributes on a span.\n */\nfunction setMessagingAttributes(\n span: Span,\n attrs: {\n queue?: string;\n exchange?: string;\n routingKey?: string;\n messageId?: string;\n correlationId?: string;\n consumerTag?: string;\n },\n): void {\n const { queue, exchange, routingKey, messageId, correlationId, consumerTag } =\n attrs;\n\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, 'rabbitmq');\n span.setAttribute(SEMATTRS_MESSAGING_OPERATION_NAME, 'receive');\n\n if (queue) {\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, queue);\n }\n\n if (exchange) {\n span.setAttribute(\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_EXCHANGE,\n exchange,\n );\n }\n\n if (routingKey) {\n span.setAttribute(\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY,\n routingKey,\n );\n }\n\n if (messageId) {\n span.setAttribute(SEMATTRS_MESSAGING_MESSAGE_ID, messageId);\n }\n\n if (correlationId) {\n span.setAttribute(\n SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID,\n correlationId,\n );\n }\n\n if (consumerTag) {\n span.setAttribute(SEMATTRS_MESSAGING_CONSUMER_ID, consumerTag);\n }\n}\n","/**\n * Publish span wrapper for RabbitMQ message publishing.\n *\n * Creates PRODUCER spans with proper messaging semantics,\n * allowing trace context to be injected inside the span.\n *\n * @example Basic publish span\n * ```typescript\n * import { withPublishSpan, injectTraceHeaders } from 'autotel-plugins/rabbitmq';\n *\n * await withPublishSpan({\n * name: 'order.publish',\n * exchange: 'orders',\n * routingKey: 'order.created',\n * messageId: 'msg-123',\n * }, async (span) => {\n * // Inject headers inside the PRODUCER span context\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * channel.publish('orders', 'order.created', content, { headers });\n * });\n * ```\n */\n\nimport { otelTrace as trace, context, SpanKind, SpanStatusCode } from 'autotel';\nimport type { PublishDescriptor, PublishSpanCallback } from './types';\nimport {\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_DESTINATION_NAME,\n SEMATTRS_MESSAGING_OPERATION_NAME,\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY,\n SEMATTRS_MESSAGING_MESSAGE_ID,\n SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID,\n} from '../common/constants';\n\nconst DEFAULT_TRACER_NAME = 'autotel-plugins/rabbitmq';\n\n/**\n * Create a publish span for RabbitMQ message publishing.\n *\n * This creates a PRODUCER span with proper messaging attributes.\n * The callback runs within the span's context, so you can call\n * `injectTraceHeaders()` inside it to get the correct trace context.\n *\n * @param descriptor - Publish span configuration\n * @param fn - Async callback to execute within the span\n * @returns Promise resolving to callback result\n * @throws Error if span creation fails or callback throws\n *\n * @example\n * ```typescript\n * await withPublishSpan({\n * name: 'payment.publish',\n * exchange: 'payments',\n * routingKey: 'payment.processed',\n * correlationId: paymentId,\n * }, async (span) => {\n * const headers = injectTraceHeaders({}, { includeCorrelationIdHeader: true });\n * channel.publish('payments', 'payment.processed', content, { headers });\n * });\n * ```\n *\n * @example Using default exchange\n * ```typescript\n * await withPublishSpan({\n * name: 'direct.send',\n * routingKey: 'queue-name', // Queue name when using default exchange\n * }, async (span) => {\n * const headers = injectTraceHeaders({});\n * channel.sendToQueue('queue-name', content, { headers });\n * });\n * ```\n */\nexport async function withPublishSpan<T>(\n descriptor: PublishDescriptor,\n fn: PublishSpanCallback<T>,\n): Promise<T> {\n const {\n name,\n exchange = 'amq.default',\n routingKey,\n messageId,\n correlationId,\n system = 'rabbitmq',\n } = descriptor;\n\n const tracer = trace.getTracer(DEFAULT_TRACER_NAME);\n\n // Create PRODUCER span\n const span = tracer.startSpan(name, {\n kind: SpanKind.PRODUCER,\n });\n\n // Set messaging attributes\n span.setAttribute(SEMATTRS_MESSAGING_SYSTEM, system);\n span.setAttribute(SEMATTRS_MESSAGING_DESTINATION_NAME, exchange);\n span.setAttribute(SEMATTRS_MESSAGING_OPERATION_NAME, 'publish');\n span.setAttribute(\n SEMATTRS_MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY,\n routingKey,\n );\n\n if (messageId) {\n span.setAttribute(SEMATTRS_MESSAGING_MESSAGE_ID, messageId);\n }\n\n if (correlationId) {\n span.setAttribute(\n SEMATTRS_MESSAGING_MESSAGE_CONVERSATION_ID,\n correlationId,\n );\n }\n\n // Execute callback within span context\n const spanContext = trace.setSpan(context.active(), span);\n\n try {\n const result = await context.with(spanContext, async () => {\n return await fn(span);\n });\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return result;\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n if (error instanceof Error) {\n span.recordException(error);\n } else {\n span.recordException(new Error(String(error)));\n }\n span.end();\n\n throw error;\n }\n}\n","/**\n * Batch lineage utilities for fan-in trace correlation.\n *\n * When processing batches of messages (e.g., aggregating multiple orders),\n * this utility extracts and correlates trace IDs from all messages\n * to create meaningful span links.\n *\n * This is a minimal implementation focused on SpanLinks only.\n * No body inspection, no complex inference.\n */\n\nimport { otelTrace as trace, type SpanContext, type SpanLink } from 'autotel';\nimport type {\n BatchItem,\n BatchLineageOptions,\n BatchLineageResult,\n ExtractedContext,\n} from './types';\nimport { normalizeHeaders, extractTraceContext } from './headers';\n\nconst DEFAULT_MAX_LINKS = 128;\n\n/**\n * Check if a span context is valid for creating links.\n * Must have both traceId and spanId.\n */\nfunction isValidSpanContext(\n spanContext: SpanContext | undefined,\n): spanContext is SpanContext {\n return !!(\n spanContext &&\n spanContext.traceId &&\n spanContext.spanId &&\n trace.isSpanContextValid(spanContext)\n );\n}\n\n/**\n * Synchronous hash using djb2 algorithm.\n */\nfunction hashTraceIdsSync(traceIds: string[]): string {\n const input = traceIds.join('|');\n\n // Simple djb2-style hash\n let hash = 5381;\n for (let i = 0; i < input.length; i++) {\n // eslint-disable-next-line unicorn/prefer-code-point\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n\n // Convert to unsigned 32-bit, then hex, pad to 16 chars\n return (hash >>> 0).toString(16).padStart(16, '0');\n}\n\n/**\n * Extract batch lineage from a collection of RabbitMQ messages.\n *\n * For each message with headers:\n * 1. Extract SpanContext using OTel propagators\n * 2. Filter to valid SpanContexts (must have traceId + spanId)\n * 3. Deduplicate by traceId\n * 4. Sort trace IDs alphabetically for deterministic hash\n * 5. Create hash of sorted trace IDs\n * 6. Create SpanLinks from valid contexts (capped at maxLinks)\n *\n * @param items - Array of items with optional headers\n * @param options - Extraction options\n * @returns Batch lineage result with links and metadata\n *\n * @example Basic batch lineage\n * ```typescript\n * import { extractBatchLineage, withConsumeSpan } from 'autotel-plugins/rabbitmq';\n *\n * // Aggregate multiple messages\n * const lineage = extractBatchLineage(\n * messages.map(m => ({ headers: m.properties.headers }))\n * );\n *\n * await withConsumeSpan({\n * name: 'batch.aggregate',\n * headers: {},\n * contextMode: 'none',\n * links: lineage.links,\n * queue: 'aggregator',\n * }, async (span) => {\n * span.setAttribute('linked_trace_id_count', lineage.linked_trace_id_count);\n * span.setAttribute('linked_trace_id_hash', lineage.linked_trace_id_hash);\n * await processBatch(messages);\n * });\n * ```\n */\nexport function extractBatchLineage(\n items: BatchItem[],\n options: BatchLineageOptions = {},\n): BatchLineageResult {\n const { includeTraceIds = false, maxLinks = DEFAULT_MAX_LINKS } = options;\n\n // Extract valid span contexts from items\n const extractedContexts: ExtractedContext[] = [];\n const seenTraceIds = new Set<string>();\n\n for (const item of items) {\n const normalizedHeaders = normalizeHeaders(item.headers);\n const extractedCtx = extractTraceContext(normalizedHeaders);\n const spanContext = trace.getSpanContext(extractedCtx);\n\n // Check valid span context and deduplicate by traceId\n if (\n isValidSpanContext(spanContext) &&\n !seenTraceIds.has(spanContext.traceId)\n ) {\n seenTraceIds.add(spanContext.traceId);\n extractedContexts.push({\n traceId: spanContext.traceId,\n spanContext,\n });\n }\n }\n\n // Sort by traceId for deterministic hash\n extractedContexts.sort((a, b) => a.traceId.localeCompare(b.traceId));\n\n const traceIds = extractedContexts.map((ec) => ec.traceId);\n\n // Create links (capped at maxLinks)\n const links: SpanLink[] = extractedContexts\n .slice(0, maxLinks)\n .map((ec) => ({ context: ec.spanContext }));\n\n // Compute hash\n const hash =\n traceIds.length > 0 ? hashTraceIdsSync(traceIds) : '0000000000000000';\n\n return {\n linked_trace_id_count: traceIds.length,\n linked_trace_id_hash: hash,\n links,\n ...(includeTraceIds && { trace_ids: traceIds }),\n };\n}\n","/**\n * Ack tracking utilities for RabbitMQ message processing.\n *\n * Provides helpers to record ack/nack/reject outcomes on spans\n * when not using deferred mode in withConsumeSpan.\n */\n\nimport type { Span } from 'autotel';\nimport {\n SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT,\n SEMATTRS_MESSAGING_RABBITMQ_REQUEUE,\n} from '../common/constants';\n\n/**\n * Ack result type for explicit recording.\n */\nexport type AckResult = 'ack' | 'nack' | 'reject';\n\n/**\n * Options for recording ack results.\n */\nexport interface RecordAckOptions {\n /**\n * Whether the message will be requeued (for nack/reject).\n */\n requeue?: boolean;\n}\n\n/**\n * Record an ack result on a span.\n *\n * Use this when not using deferred mode but still want to track\n * ack/nack/reject outcomes as span attributes.\n *\n * @param span - The span to record on\n * @param result - The ack result ('ack', 'nack', or 'reject')\n * @param options - Additional options\n *\n * @example\n * ```typescript\n * import { withConsumeSpan, recordAckResult } from 'autotel-plugins/rabbitmq';\n *\n * await withConsumeSpan({\n * name: 'order.process',\n * headers: msg.properties.headers,\n * queue: 'orders',\n * }, async (span) => {\n * try {\n * await processOrder(msg);\n * recordAckResult(span, 'ack');\n * channel.ack(msg);\n * } catch (error) {\n * recordAckResult(span, 'nack', { requeue: true });\n * channel.nack(msg, false, true);\n * throw error;\n * }\n * });\n * ```\n */\nexport function recordAckResult(\n span: Span,\n result: AckResult,\n options?: RecordAckOptions,\n): void {\n span.setAttribute(SEMATTRS_MESSAGING_RABBITMQ_ACK_RESULT, result);\n\n if (options?.requeue !== undefined) {\n span.setAttribute(SEMATTRS_MESSAGING_RABBITMQ_REQUEUE, options.requeue);\n }\n}\n"]}
|