@senzops/apm-node 1.3.0 → 1.3.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/internal.ts","../src/core/context.ts","../src/utils/traceContext.ts","../src/utils/ids.ts","../src/core/sanitizer.ts","../src/instrumentation/span.ts","../src/core/normalizer.ts","../src/utils/getClientIp.ts","../src/instrumentation/patch.ts","../src/instrumentation/http.ts","../src/instrumentation/hook.ts","../src/instrumentation/framework.ts","../src/instrumentation/express.ts","../src/instrumentation/fastify.ts","../src/instrumentation/koa.ts","../src/instrumentation/undici.ts","../src/instrumentation/mongo.ts","../src/instrumentation/mongoose.ts","../src/instrumentation/pg.ts","../src/instrumentation/mysql.ts","../src/instrumentation/redis.ts","../src/instrumentation/bullmq.ts","../src/instrumentation/cron.ts","../src/instrumentation/grpc.ts","../src/instrumentation/graphql.ts","../src/instrumentation/dns.ts","../src/instrumentation/net.ts","../src/instrumentation/kafka.ts","../src/instrumentation/amqplib.ts","../src/instrumentation/socketio.ts","../src/instrumentation/nestjs.ts","../src/instrumentation/hapi.ts","../src/instrumentation/pino.ts","../src/instrumentation/winston.ts","../src/instrumentation/bunyan.ts","../src/instrumentation/aws-sdk.ts","../src/instrumentation/knex.ts","../src/instrumentation/tedious.ts","../src/instrumentation/cassandra.ts","../src/instrumentation/memcached.ts","../src/instrumentation/generic-pool.ts","../src/instrumentation/restify.ts","../src/instrumentation/connect.ts","../src/instrumentation/dataloader.ts","../src/instrumentation/lru-memoizer.ts","../src/instrumentation/fs.ts","../src/instrumentation/openai.ts","../src/instrumentation/anthropic.ts","../src/instrumentation/google-genai.ts","../src/instrumentation/azure-openai.ts","../src/instrumentation/cohere.ts","../src/instrumentation/mistral.ts","../src/instrumentation/firebase.ts","../src/lambda-handler.ts","../src/core/transport.ts","../src/core/client.ts","../src/core/runtime.ts","../package.json","../src/utils/sdkMeta.ts","../src/instrumentation/runtime.ts","../src/wrappers/lambda.ts"],"sourcesContent":["export const SENZOR_INTERNAL_HEADER = 'x-senzor-sdk-internal';\n","import { ActiveTrace, Span } from './types';\n\ninterface IStorage<T> {\n run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R;\n getStore(): T | undefined;\n}\n\n/**\n * Async-safe fallback when AsyncLocalStorage is unavailable.\n *\n * Not concurrency-safe across truly parallel requests in a single isolate,\n * but correct for sequential and async/await patterns (e.g. Cloudflare Workers\n * where each request gets its own execution context).\n */\nclass NaiveStorage<T> implements IStorage<T> {\n private store: T | undefined;\n\n run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R {\n const prev = this.store;\n this.store = store;\n\n let result: R;\n try {\n result = callback(...args);\n } catch (err) {\n this.store = prev;\n throw err;\n }\n\n // If the callback returned a thenable (async handler), defer the restore\n // until the promise settles so Context.current() works across awaits.\n if (result != null && typeof (result as any).then === 'function') {\n const promise = (result as any).then(\n (val: any) => { this.store = prev; return val; },\n (err: any) => { this.store = prev; throw err; }\n );\n return promise as R;\n }\n\n // Sync callback — restore immediately.\n this.store = prev;\n return result;\n }\n\n getStore(): T | undefined {\n return this.store;\n }\n}\n\n/**\n * Resolve the best available async context storage.\n *\n * Uses lazy re-resolution: if the initial attempt (at module evaluation time)\n * falls back to NaiveStorage, subsequent calls to resolveStorage() will retry.\n * This handles runtimes where AsyncLocalStorage becomes available after module\n * init (e.g. some Workers configurations).\n */\nconst tryResolveALS = <T>(): IStorage<T> | null => {\n // 1. Check globalThis (Cloudflare Workers nodejs_compat_v2, Bun, Deno)\n if (typeof globalThis !== 'undefined' && (globalThis as any).AsyncLocalStorage) {\n return new (globalThis as any).AsyncLocalStorage();\n }\n\n // 2. Node.js CJS require\n try {\n if (typeof require !== 'undefined') {\n const mod = require('node:async_hooks');\n if (mod?.AsyncLocalStorage) return new mod.AsyncLocalStorage();\n }\n } catch {}\n\n try {\n if (typeof require !== 'undefined') {\n const mod = require('async_hooks');\n if (mod?.AsyncLocalStorage) return new mod.AsyncLocalStorage();\n }\n } catch {}\n\n return null;\n};\n\nclass LazyStorage<T> implements IStorage<T> {\n private inner: IStorage<T>;\n private resolved = false;\n\n constructor() {\n this.inner = tryResolveALS<T>() || new NaiveStorage<T>();\n this.resolved = !(this.inner instanceof NaiveStorage);\n }\n\n private ensureResolved() {\n if (this.resolved) return;\n const als = tryResolveALS<T>();\n if (als) {\n this.inner = als;\n this.resolved = true;\n }\n }\n\n run<R>(store: T, callback: (...args: any[]) => R, ...args: any[]): R {\n this.ensureResolved();\n return this.inner.run(store, callback, ...args);\n }\n\n getStore(): T | undefined {\n return this.inner.getStore();\n }\n}\n\nexport const storage = new LazyStorage<ActiveTrace>();\n\nexport const Context = {\n run: <T>(trace: ActiveTrace, fn: () => T): T => {\n return storage.run(trace, fn);\n },\n\n withActiveSpan: <T>(spanId: string, fn: () => T): T => {\n const store = storage.getStore();\n if (!store) return fn();\n\n return storage.run(\n {\n ...store,\n activeSpanId: spanId,\n data: store.data,\n spans: store.spans\n },\n fn\n );\n },\n\n current: (): ActiveTrace | undefined => {\n return storage.getStore();\n },\n\n addSpan: (span: Span) => {\n const store = storage.getStore();\n if (store) {\n Context.addSpanToTrace(store, span);\n }\n },\n\n addSpanToTrace: (trace: ActiveTrace, span: Span) => {\n if (trace.state.ended) return;\n\n const maxSpans = trace.maxSpans ?? 500;\n if (trace.spans.length >= maxSpans) {\n trace.state.droppedSpans = (trace.state.droppedSpans ?? 0) + 1;\n return;\n }\n\n trace.spans.push(span);\n }\n};\n","/**\r\n * W3C Trace Context Implementation\r\n * Standard: https://www.w3.org/TR/trace-context/\r\n * Format: 00-{traceId}-{spanId}-{traceFlags}\r\n */\r\n\r\nexport interface TraceContext {\r\n traceId: string;\r\n parentSpanId: string;\r\n sampled: boolean;\r\n}\r\n\r\nconst TRACEPARENT_REGEX = /^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;\r\n\r\nexport const parseTraceparent = (header?: string | string[]): TraceContext | null => {\r\n if (!header) return null;\r\n\r\n const traceparent = Array.isArray(header) ? header[0] : header;\r\n if (typeof traceparent !== 'string') return null;\r\n\r\n const match = traceparent.trim().toLowerCase().match(TRACEPARENT_REGEX);\r\n if (!match) return null;\r\n\r\n const traceId = match[1];\r\n const parentSpanId = match[2];\r\n const flags = match[3];\r\n\r\n // Invalid IDs according to W3C specification\r\n if (traceId === '00000000000000000000000000000000') return null;\r\n if (parentSpanId === '0000000000000000') return null;\r\n\r\n // The least significant bit of flags indicates if the trace is sampled\r\n const sampled = (parseInt(flags, 16) & 0x01) === 0x01;\r\n\r\n return { traceId, parentSpanId, sampled };\r\n};\r\n\r\n/**\r\n * Generates a valid W3C traceparent header string for OUTGOING requests.\r\n */\r\nexport const generateTraceparent = (traceId: string, spanId: string, sampled: boolean = true): string => {\r\n const flags = sampled ? '01' : '00';\r\n return `00-${traceId}-${spanId}-${flags}`;\r\n};","const getRandomUUID = (): string => {\n if (typeof globalThis !== 'undefined' && globalThis.crypto && typeof globalThis.crypto.randomUUID === 'function') {\n return globalThis.crypto.randomUUID();\n }\n\n try {\n if (typeof require !== 'undefined') {\n const { randomUUID } = require('node:crypto');\n if (randomUUID) return randomUUID();\n }\n } catch {}\n\n // Fallback: RFC4122 v4 UUID via Math.random (last resort)\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n};\n\nexport const generateTraceId = (): string =>\n getRandomUUID().replace(/-/g, '');\n\nexport const generateSpanId = (): string =>\n getRandomUUID().replace(/-/g, '').slice(0, 16);\n","import { SenzorOptions } from './types';\n\nconst DEFAULT_MAX_ATTRIBUTES = 64;\nconst DEFAULT_MAX_ATTRIBUTE_LENGTH = 2048;\nconst MAX_DEPTH = 4;\nconst MAX_ARRAY_ITEMS = 20;\n\nconst SENSITIVE_KEY_PATTERN =\n /(^|[-_.])(authorization|cookie|set-cookie|password|passwd|pwd|secret|token|api[-_.]?key|x-api-key|access[-_.]?token|refresh[-_.]?token|client[-_.]?secret|private[-_.]?key)([-_.]|$)/i;\n\nexport interface SanitizerOptions {\n maxAttributes?: number;\n maxAttributeLength?: number;\n}\n\nconst getLimits = (options?: SanitizerOptions | SenzorOptions) => ({\n maxAttributes: options?.maxAttributes ?? DEFAULT_MAX_ATTRIBUTES,\n maxAttributeLength:\n options?.maxAttributeLength ?? DEFAULT_MAX_ATTRIBUTE_LENGTH\n});\n\nexport const truncate = (\n value: string,\n maxLength = DEFAULT_MAX_ATTRIBUTE_LENGTH\n): string => {\n if (value.length <= maxLength) return value;\n return `${value.slice(0, Math.max(0, maxLength - 15))}...[truncated]`;\n};\n\nexport const isSensitiveKey = (key: string): boolean =>\n SENSITIVE_KEY_PATTERN.test(key);\n\nconst sanitizePrimitive = (\n value: unknown,\n maxLength: number\n): string | number | boolean | null | undefined => {\n if (value === null || value === undefined) return value;\n\n if (\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return value;\n }\n\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n if (typeof value === 'string') {\n return truncate(value, maxLength);\n }\n\n return undefined;\n};\n\nconst sanitizeValue = (\n key: string,\n value: unknown,\n options: Required<SanitizerOptions>,\n depth: number\n): unknown => {\n if (isSensitiveKey(key)) return '[REDACTED]';\n\n const primitive =\n sanitizePrimitive(value, options.maxAttributeLength);\n\n if (primitive !== undefined || value === undefined) {\n return primitive;\n }\n\n if (value instanceof Error) {\n return {\n name: truncate(value.name, options.maxAttributeLength),\n message: truncate(value.message, options.maxAttributeLength),\n stack: value.stack\n ? truncate(value.stack, options.maxAttributeLength)\n : undefined\n };\n }\n\n if (depth >= MAX_DEPTH) {\n return '[MaxDepth]';\n }\n\n if (Array.isArray(value)) {\n return value\n .slice(0, MAX_ARRAY_ITEMS)\n .map((item) =>\n sanitizeValue(key, item, options, depth + 1)\n );\n }\n\n if (typeof value === 'object') {\n const output: Record<string, unknown> = {};\n let count = 0;\n\n for (const [childKey, childValue] of Object.entries(\n value as Record<string, unknown>\n )) {\n if (count >= options.maxAttributes) {\n output.__truncated = true;\n break;\n }\n\n output[childKey] = sanitizeValue(\n childKey,\n childValue,\n options,\n depth + 1\n );\n count++;\n }\n\n return output;\n }\n\n return truncate(String(value), options.maxAttributeLength);\n};\n\nexport const sanitizeAttributes = (\n attributes: Record<string, unknown> = {},\n options?: SanitizerOptions | SenzorOptions\n): Record<string, unknown> => {\n const limits = getLimits(options);\n const normalizedOptions: Required<SanitizerOptions> = {\n maxAttributes: limits.maxAttributes,\n maxAttributeLength: limits.maxAttributeLength\n };\n\n const output: Record<string, unknown> = {};\n let count = 0;\n\n for (const [key, value] of Object.entries(attributes)) {\n if (count >= normalizedOptions.maxAttributes) {\n output.__truncated = true;\n break;\n }\n\n output[key] = sanitizeValue(\n key,\n value,\n normalizedOptions,\n 0\n );\n count++;\n }\n\n return output;\n};\n\nexport const sanitizeHeaders = (\n headers: unknown,\n options?: SanitizerOptions | SenzorOptions\n): Record<string, unknown> => {\n if (!headers || typeof headers !== 'object') return {};\n\n const plainHeaders: Record<string, unknown> = {};\n\n if (typeof (headers as any).forEach === 'function') {\n (headers as any).forEach((value: unknown, key: string) => {\n plainHeaders[key.toLowerCase()] = value;\n });\n } else {\n for (const [key, value] of Object.entries(\n headers as Record<string, unknown>\n )) {\n plainHeaders[key.toLowerCase()] = Array.isArray(value)\n ? value.join(', ')\n : value;\n }\n }\n\n return sanitizeAttributes(plainHeaders, options);\n};\n\nexport const normalizeSql = (\n sql: unknown,\n options?: SenzorOptions\n): string | undefined => {\n if (typeof sql !== 'string') return undefined;\n\n const collapsed = sql.replace(/\\s+/g, ' ').trim();\n if (!collapsed) return undefined;\n\n const withoutLiterals = collapsed\n .replace(/'(?:''|[^'])*'/g, '?')\n .replace(/\"(?:\\\\\"|[^\"])*\"/g, '?')\n .replace(/\\b\\d+(\\.\\d+)?\\b/g, '?');\n\n return truncate(\n options?.captureDbStatement === false\n ? withoutLiterals.split(' ').slice(0, 6).join(' ')\n : withoutLiterals,\n options?.maxAttributeLength ?? DEFAULT_MAX_ATTRIBUTE_LENGTH\n );\n};\n\nexport const getSqlOperation = (sql: unknown): string | undefined => {\n if (typeof sql !== 'string') return undefined;\n const match = sql.trim().match(/^([a-z]+)/i);\n return match?.[1]?.toUpperCase();\n};\n","import { Context } from '../core/context';\nimport { sanitizeAttributes } from '../core/sanitizer';\nimport { ActiveTrace, SenzorOptions, Span } from '../core/types';\nimport { generateSpanId } from '../utils/ids';\n\ntype SpanType = Span['type'];\n\nexport interface CapturedSpan {\n spanId: string;\n parentSpanId?: string;\n trace?: ActiveTrace;\n end: (\n status?: number,\n meta?: Record<string, unknown>\n ) => void;\n}\n\nexport const startCapturedSpan = (\n name: string,\n type: SpanType,\n meta: Record<string, unknown> = {},\n options?: SenzorOptions\n): CapturedSpan | null => {\n const trace = Context.current();\n if (!trace) return null;\n\n const spanId = generateSpanId();\n const parentSpanId = trace.activeSpanId;\n const startTime = performance.now() - trace.startTime;\n const startedAt = performance.now();\n let ended = false;\n\n return {\n spanId,\n parentSpanId,\n trace,\n end: (\n status?: number,\n extraMeta: Record<string, unknown> = {}\n ) => {\n if (ended) return;\n ended = true;\n\n const mergedMeta = sanitizeAttributes(\n {\n ...meta,\n ...extraMeta,\n parentSpanId\n },\n options\n );\n\n Context.addSpanToTrace(trace, {\n spanId,\n parentSpanId,\n name,\n type,\n startTime,\n duration: performance.now() - startedAt,\n status,\n meta: mergedMeta\n });\n }\n };\n};\n\nexport const runWithCapturedSpan = <T>(\n span: CapturedSpan | null,\n fn: () => T\n): T => {\n if (!span) return fn();\n return Context.withActiveSpan(span.spanId, fn);\n};\n","/**\r\n * Heuristic URL Normalizer\r\n * Converts raw paths with IDs into generic patterns to prevent high cardinality.\r\n * Example: /users/123/orders/abc-def -> /users/:id/orders/:uuid\r\n */\r\nexport const normalizePath = (path: string): string => {\r\n if (!path || path === '/') return '/';\r\n\r\n return path\r\n // Replace UUIDs (long alphanumeric strings)\r\n .replace(\r\n /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/g,\r\n ':uuid'\r\n )\r\n // Replace MongoDB ObjectIds (24 hex chars)\r\n .replace(/[0-9a-fA-F]{24}/g, ':objectId')\r\n // Replace pure numeric IDs (e.g., /123)\r\n .replace(/\\/(\\d+)(?=\\/|$)/g, '/:id')\r\n // Remove query strings\r\n .split('?')[0];\r\n};\r\n\r\n/**\r\n * Tries to extract route from Framework internals, falls back to heuristic\r\n */\r\nexport const getRoute = (req: any, fallbackPath: string): string => {\r\n // Express / Connect\r\n if (req.route && req.route.path) {\r\n return (req.baseUrl || '') + req.route.path;\r\n }\r\n\r\n // H3 / Nitro (Nuxt)\r\n if (req.context && req.context.matchedRoute) {\r\n return req.context.matchedRoute.path;\r\n }\r\n\r\n // Fastify\r\n if (req.routerPath) {\r\n return req.routerPath;\r\n }\r\n\r\n // Fallback: Heuristic Normalization\r\n return normalizePath(fallbackPath);\r\n};","/**\n * getClientIp.ts\n *\n * Robust, proxy-aware client IP extraction.\n *\n * Priority order (mirrors Umami + industry best practice):\n * 1. ENV-configured custom header (CLIENT_IP_HEADER)\n * 2. CF-Connecting-IP (Cloudflare — single trusted IP)\n * 3. True-Client-IP (Cloudflare Enterprise / Akamai)\n * 4. X-Real-IP (Nginx realip module)\n * 5. Forwarded (RFC 7239 — \"for=\" field)\n * 6. X-Forwarded-For (De-facto standard — leftmost public IP)\n * 7. req.socket.remoteAddress (Direct connection fallback)\n *\n * Security note: headers 2-6 can be spoofed by clients when your server is\n * directly internet-facing. If that is a concern, restrict extraction to the\n * header your trusted reverse-proxy injects (CLIENT_IP_HEADER or X-Real-IP).\n */\n\n// ---------------------------------------------------------------------------\n// Inline IP validation (replaces Node's net.isIP to support edge runtimes)\n// ---------------------------------------------------------------------------\n\nconst IPV4_PATTERN = /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/;\nconst IPV6_PATTERN = /^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$|^::(?:[a-fA-F0-9]{1,4}:){0,5}[a-fA-F0-9]{1,4}$|^[a-fA-F0-9]{1,4}::(?:[a-fA-F0-9]{1,4}:){0,4}[a-fA-F0-9]{1,4}$|^(?:[a-fA-F0-9]{1,4}:){1,2}:(?:[a-fA-F0-9]{1,4}:){0,3}[a-fA-F0-9]{1,4}$|^(?:[a-fA-F0-9]{1,4}:){1,3}:(?:[a-fA-F0-9]{1,4}:){0,2}[a-fA-F0-9]{1,4}$|^(?:[a-fA-F0-9]{1,4}:){1,4}:(?:[a-fA-F0-9]{1,4}:)?[a-fA-F0-9]{1,4}$|^(?:[a-fA-F0-9]{1,4}:){1,5}:[a-fA-F0-9]{1,4}$|^(?:[a-fA-F0-9]{1,4}:){1,6}:$|^::$|^::1$|^fe80:.*$/i;\n\n/**\n * Returns 4 for IPv4, 6 for IPv6, 0 for invalid.\n * Drop-in replacement for Node's net.isIP().\n */\nconst isIP = (ip: string): number => {\n if (IPV4_PATTERN.test(ip)) return 4;\n if (IPV6_PATTERN.test(ip)) return 6;\n return 0;\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Strip IPv4-mapped IPv6 prefix (::ffff:1.2.3.4 -> 1.2.3.4) */\nconst stripIPv6Mapped = (ip: string): string =>\n ip.startsWith(\"::ffff:\") ? ip.slice(7) : ip;\n\n/** Strip optional port from an IPv4 address (1.2.3.4:5678 -> 1.2.3.4). */\nconst stripIPv4Port = (ip: string): string => {\n const lastColon = ip.lastIndexOf(\":\");\n if (lastColon === -1) return ip;\n const maybeIP = ip.slice(0, lastColon);\n return isIP(maybeIP) === 4 ? maybeIP : ip;\n};\n\n/** Strip brackets + optional port from an IPv6 address ([::1]:5678 -> ::1). */\nconst stripIPv6Brackets = (ip: string): string => {\n const match = ip.match(/^\\[([^\\]]+)\\](?::\\d+)?$/);\n return match ? match[1] : ip;\n};\n\n/** Normalise raw IP string into a clean, routable address (or null). */\nexport const normaliseIP = (raw: string | undefined | null): string | null => {\n if (!raw) return null;\n let ip = raw.trim();\n if (!ip) return null;\n\n ip = stripIPv6Brackets(ip);\n ip = stripIPv4Port(ip);\n ip = stripIPv6Mapped(ip);\n\n return isIP(ip) !== 0 ? ip : null;\n};\n\n/**\n * Returns true for IPs that will never produce a geo result:\n * loopback, link-local, private ranges, and unspecified addresses.\n */\nexport const isPrivateOrLoopback = (ip: string): boolean => {\n // IPv4 private / loopback / link-local\n if (\n ip === \"127.0.0.1\" ||\n ip.startsWith(\"10.\") ||\n ip.startsWith(\"192.168.\") ||\n ip.startsWith(\"169.254.\") || // link-local\n /^172\\.(1[6-9]|2\\d|3[01])\\./.test(ip) // 172.16-31\n )\n return true;\n\n // IPv6 loopback / unspecified / link-local / unique-local\n if (\n ip === \"::1\" ||\n ip === \"::\" ||\n ip.toLowerCase().startsWith(\"fe80:\") || // link-local\n ip.toLowerCase().startsWith(\"fc\") || // unique-local\n ip.toLowerCase().startsWith(\"fd\") // unique-local\n )\n return true;\n\n return false;\n};\n\n// ---------------------------------------------------------------------------\n// RFC 7239 \"Forwarded\" header parser\n// e.g. Forwarded: for=192.0.2.60;proto=http, for=\"[2001:db8::cafe]\"\n// ---------------------------------------------------------------------------\nconst parseForwardedHeader = (header: string): string | null => {\n const parts = header.split(\",\");\n for (const part of parts) {\n const forMatch = part.match(/for=[\"[]?([^\\]\",;>\\s]+)/i);\n if (forMatch) {\n const ip = normaliseIP(forMatch[1]);\n if (ip && !isPrivateOrLoopback(ip)) return ip;\n }\n }\n return null;\n};\n\n// ---------------------------------------------------------------------------\n// X-Forwarded-For parser — pick the leftmost *public* IP\n// e.g. X-Forwarded-For: client, proxy1, proxy2\n// ---------------------------------------------------------------------------\nconst parseXForwardedFor = (header: string): string | null => {\n const ips = header.split(\",\").map((s) => s.trim());\n for (const raw of ips) {\n const ip = normaliseIP(raw);\n if (ip && !isPrivateOrLoopback(ip)) return ip;\n }\n // If every hop is private (intranet-only setup) fall back to first valid IP\n for (const raw of ips) {\n const ip = normaliseIP(raw);\n if (ip) return ip;\n }\n return null;\n};\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\n/**\n * Extract the best-available client IP from a request.\n *\n * Returns `null` if no valid IP can be determined.\n */\nexport const getClientIp = (req: any): string | null => {\n const h = req.headers;\n\n // 2. Cloudflare single-IP header (most reliable when behind CF)\n {\n const ip = normaliseIP(h[\"cf-connecting-ip\"] as string);\n if (ip) return ip;\n }\n\n // 3. Cloudflare Enterprise / Akamai\n {\n const ip = normaliseIP(h[\"true-client-ip\"] as string);\n if (ip) return ip;\n }\n\n // 4. Nginx realip module (single, already-trusted IP)\n {\n const ip = normaliseIP(h[\"x-real-ip\"] as string);\n if (ip) return ip;\n }\n\n // 5. RFC 7239 Forwarded header\n {\n const fwd = h[\"forwarded\"] as string;\n if (fwd) {\n const ip = parseForwardedHeader(fwd);\n if (ip) return ip;\n }\n }\n\n // 6. De-facto standard XFF\n {\n const xff = h[\"x-forwarded-for\"] as string;\n if (xff) {\n const ip = parseXForwardedFor(xff);\n if (ip) return ip;\n }\n }\n\n // 7. Direct TCP connection (local dev / no proxy)\n {\n const raw = req.socket?.remoteAddress;\n const ip = normaliseIP(raw);\n if (ip) return ip;\n }\n\n return null;\n};\n","const PATCHES = Symbol.for('senzor.patch.keys');\nconst ORIGINAL = Symbol.for('senzor.patch.original');\n\ntype WrappedFunction = Function & {\n [PATCHES]?: Set<string>;\n [ORIGINAL]?: Function;\n};\n\nexport const patchMethod = (\n target: any,\n methodName: string,\n patchKey: string,\n wrapper: (original: Function) => Function\n): boolean => {\n if (!target) return false;\n\n const current = target[methodName] as WrappedFunction | undefined;\n if (typeof current !== 'function') return false;\n\n const existingPatches = current[PATCHES];\n if (existingPatches?.has(patchKey)) return false;\n\n const original = current[ORIGINAL] || current;\n const wrapped = wrapper(current) as WrappedFunction;\n const patches = new Set(existingPatches || []);\n patches.add(patchKey);\n\n try {\n Object.defineProperty(wrapped, PATCHES, {\n value: patches,\n enumerable: false\n });\n Object.defineProperty(wrapped, ORIGINAL, {\n value: original,\n enumerable: false\n });\n } catch {\n return false;\n }\n\n try {\n target[methodName] = wrapped;\n return true;\n } catch {\n return false;\n }\n};\n\nexport const isPatched = (\n target: any,\n methodName: string,\n patchKey: string\n): boolean => {\n const current = target?.[methodName] as WrappedFunction | undefined;\n return Boolean(current?.[PATCHES]?.has(patchKey));\n};\n","import type { SenzorClient } from '../core/client';\nimport { Context } from '../core/context';\nimport { getRoute, normalizePath } from '../core/normalizer';\nimport { sanitizeHeaders } from '../core/sanitizer';\nimport { SenzorOptions } from '../core/types';\nimport { getClientIp } from '../utils/getClientIp';\nimport { SENZOR_INTERNAL_HEADER } from '../utils/internal';\nimport { generateTraceparent } from '../utils/traceContext';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\nconst getDebug = (options?: SenzorOptions): boolean =>\n Boolean(options?.debug);\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' &&\n value !== null &&\n !(value instanceof URL) &&\n !(value instanceof Function) &&\n !Array.isArray(value);\n\nconst headerValue = (\n headers: unknown,\n key: string\n): unknown => {\n if (!headers) return undefined;\n\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n return headers.get(key);\n }\n\n if (Array.isArray(headers)) {\n const found = headers.find(\n ([name]) => String(name).toLowerCase() === key.toLowerCase()\n );\n return found?.[1];\n }\n\n if (typeof headers === 'object') {\n const normalizedKey = key.toLowerCase();\n for (const [name, value] of Object.entries(headers)) {\n if (name.toLowerCase() === normalizedKey) return value;\n }\n }\n\n return undefined;\n};\n\nconst hasInternalHeader = (headers: unknown): boolean =>\n String(headerValue(headers, SENZOR_INTERNAL_HEADER) || '').toLowerCase() ===\n 'true';\n\nconst shouldIgnoreUrl = (\n urlString: string,\n ingestUrl: string,\n headers?: unknown\n): boolean => {\n if (hasInternalHeader(headers)) return true;\n if (!urlString) return false;\n\n try {\n const url = new URL(urlString);\n const ingest = new URL(ingestUrl);\n return (\n url.hostname === ingest.hostname &&\n url.pathname.startsWith('/api/ingest')\n );\n } catch {\n return ingestUrl ? urlString.includes(ingestUrl) : false;\n }\n};\n\nconst cloneHeaders = (headers: unknown): Record<string, unknown> => {\n if (!headers) return {};\n\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n const cloned: Record<string, unknown> = {};\n headers.forEach((value, key) => {\n cloned[key] = value;\n });\n return cloned;\n }\n\n if (Array.isArray(headers)) {\n return headers.reduce<Record<string, unknown>>((acc, [key, value]) => {\n acc[key] = value;\n return acc;\n }, {});\n }\n\n if (typeof headers === 'object') {\n return { ...(headers as Record<string, unknown>) };\n }\n\n return {};\n};\n\nconst setHeader = (\n headers: Record<string, unknown>,\n key: string,\n value: string\n) => {\n const existingKey = Object.keys(headers).find(\n (header) => header.toLowerCase() === key.toLowerCase()\n );\n headers[existingKey || key] = value;\n};\n\ninterface PreparedRequest {\n args: any[];\n options: Record<string, any>;\n url: string;\n method: string;\n hostname: string;\n path: string;\n}\n\nconst prepareRequestArgs = (\n args: any[],\n defaultProtocol: 'http:' | 'https:'\n): PreparedRequest => {\n const nextArgs = [...args];\n let optionsIndex = 0;\n let options: Record<string, any> = {};\n let urlFromArg: URL | null = null;\n\n if (typeof nextArgs[0] === 'string' || nextArgs[0] instanceof URL) {\n try {\n urlFromArg = new URL(nextArgs[0].toString());\n } catch {\n urlFromArg = null;\n }\n\n if (isPlainObject(nextArgs[1])) {\n optionsIndex = 1;\n options = {\n ...nextArgs[1],\n headers: cloneHeaders(nextArgs[1].headers)\n };\n nextArgs[1] = options;\n } else {\n optionsIndex = 1;\n options = { headers: {} };\n nextArgs.splice(1, 0, options);\n }\n } else if (isPlainObject(nextArgs[0])) {\n optionsIndex = 0;\n options = {\n ...nextArgs[0],\n headers: cloneHeaders(nextArgs[0].headers)\n };\n nextArgs[0] = options;\n } else {\n optionsIndex = 0;\n options = { headers: {} };\n nextArgs[0] = options;\n }\n\n if (!options.headers) options.headers = {};\n nextArgs[optionsIndex] = options;\n\n const protocol =\n options.protocol ||\n urlFromArg?.protocol ||\n (options.port === 443 ? 'https:' : defaultProtocol);\n const hostname =\n options.hostname ||\n options.host ||\n urlFromArg?.hostname ||\n 'localhost';\n const path =\n options.path ||\n `${urlFromArg?.pathname || '/'}${urlFromArg?.search || ''}`;\n const url = urlFromArg\n ? urlFromArg.toString()\n : `${protocol}//${hostname}${path}`;\n const method = String(options.method || 'GET').toUpperCase();\n\n return {\n args: nextArgs,\n options,\n url,\n method,\n hostname: String(hostname).replace(/:\\d+$/, ''),\n path\n };\n};\n\nconst resolveIncomingRoute = (\n req: any,\n res: any,\n path: string\n): string => {\n if (res?.statusCode === 404) return 'Not Found';\n\n try {\n return getRoute(req, path);\n } catch {\n return normalizePath(path);\n }\n};\n\nconst patchIncomingServer = (\n proto: any,\n protocol: 'http' | 'https',\n client: SenzorClient,\n options?: SenzorOptions\n) => {\n patchMethod(\n proto,\n 'emit',\n `senzor.${protocol}.server`,\n (original) =>\n function patchedEmit(this: any, event: string, ...args: any[]) {\n if (event !== 'request') {\n return original.call(this, event, ...args);\n }\n\n const req = args[0];\n const res = args[1];\n\n if (!req || !res || Context.current()?.contextType === 'apm') {\n return original.call(this, event, ...args);\n }\n\n const rawPath = req.originalUrl || req.url || '/';\n const path = String(rawPath).split('?')[0] || '/';\n const headers = req.headers || {};\n\n if (hasInternalHeader(headers)) {\n return original.call(this, event, ...args);\n }\n\n return client.startTrace(\n {\n method: req.method || 'GET',\n path: rawPath,\n route: normalizePath(path),\n ip: getClientIp(req),\n userAgent: headers['user-agent'],\n headers,\n meta: {\n protocol,\n httpVersion: req.httpVersion,\n headers: options?.captureHeaders\n ? sanitizeHeaders(headers, options)\n : undefined\n }\n },\n () => {\n const trace = Context.current();\n let finalized = false;\n\n const finalize = (reason: 'finish' | 'close' | 'error') => {\n if (finalized || !trace) return;\n finalized = true;\n\n setImmediate(() => {\n if (trace.state.ended) return;\n\n Context.run(trace, () => {\n client.endTrace(res.statusCode || 0, {\n route: resolveIncomingRoute(req, res, path),\n statusMessage: res.statusMessage,\n meta: {\n ...trace.data.meta,\n endReason: reason\n }\n });\n });\n });\n };\n\n res.once('finish', () => finalize('finish'));\n res.once('close', () => finalize('close'));\n res.once('error', (error: Error) => {\n client.captureError(error, {\n instrumentation: `${protocol}.server`\n });\n finalize('error');\n });\n\n try {\n return original.call(this, event, ...args);\n } catch (error) {\n client.captureError(error, {\n instrumentation: `${protocol}.server`\n });\n finalize('error');\n throw error;\n }\n }\n );\n }\n );\n};\n\nconst patchOutgoing = (\n moduleRef: any,\n protocol: 'http:' | 'https:',\n ingestUrl: string,\n options?: SenzorOptions\n) => {\n const patchKeyPrefix = protocol === 'https:' ? 'senzor.https' : 'senzor.http';\n\n const requestWrapper = (original: Function) =>\n function patchedRequest(this: any, ...args: any[]) {\n const prepared = prepareRequestArgs(args, protocol);\n\n if (\n shouldIgnoreUrl(\n prepared.url,\n ingestUrl,\n prepared.options.headers\n )\n ) {\n return original.apply(this, args);\n }\n\n const trace = Context.current();\n if (!trace) return original.apply(this, args);\n\n const span = startCapturedSpan(\n `${prepared.method} ${prepared.hostname}`,\n 'http',\n {\n url: prepared.url,\n method: prepared.method,\n library: protocol === 'https:' ? 'https' : 'http',\n 'http.request.method': prepared.method,\n 'url.full': prepared.url,\n 'url.path': prepared.path,\n 'server.address': prepared.hostname\n },\n options\n );\n\n if (span) {\n setHeader(\n prepared.options.headers,\n 'traceparent',\n generateTraceparent(trace.id, span.spanId)\n );\n setHeader(prepared.options.headers, 'x-senzor-trace-id', trace.id);\n setHeader(\n prepared.options.headers,\n 'x-senzor-parent-span-id',\n span.spanId\n );\n }\n\n const invoke = () => {\n const req = original.apply(this, prepared.args);\n if (!span || !req || typeof req.once !== 'function') {\n return req;\n }\n\n let completed = false;\n const endSpan = (\n status: number,\n extraMeta: Record<string, unknown> = {}\n ) => {\n if (completed) return;\n completed = true;\n span.end(status, extraMeta);\n };\n\n req.once('response', (res: any) => {\n const statusCode = res?.statusCode || 0;\n const finish = () =>\n endSpan(statusCode, {\n 'http.response.status_code': statusCode\n });\n\n res.once('end', finish);\n res.once('close', finish);\n res.once('error', (error: Error) =>\n endSpan(500, {\n error: error.message,\n 'error.type': error.name\n })\n );\n });\n\n req.once('timeout', () =>\n endSpan(504, {\n error: 'Request timed out',\n 'error.type': 'TimeoutError'\n })\n );\n req.once('error', (error: Error) =>\n endSpan(500, {\n error: error.message,\n 'error.type': error.name\n })\n );\n\n return req;\n };\n\n if (getDebug(options)) {\n console.log(`[Senzor] Injecting trace headers to ${prepared.url}`);\n }\n\n return runWithCapturedSpan(span, invoke);\n };\n\n patchMethod(\n moduleRef,\n 'request',\n `${patchKeyPrefix}.request`,\n requestWrapper\n );\n patchMethod(\n moduleRef,\n 'get',\n `${patchKeyPrefix}.get`,\n requestWrapper\n );\n};\n\nexport const instrumentFetch = (\n ingestUrl: string,\n options?: SenzorOptions\n) => {\n if (!globalThis.fetch) return;\n\n patchMethod(\n globalThis,\n 'fetch',\n 'senzor.fetch',\n (original) =>\n async function patchedFetch(\n this: any,\n input: any,\n init?: any\n ): Promise<Response> {\n const urlString =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.toString()\n : input?.url || '';\n\n const originalHeaders = init?.headers || input?.headers;\n if (shouldIgnoreUrl(urlString, ingestUrl, originalHeaders)) {\n return original.call(this, input, init);\n }\n\n const trace = Context.current();\n if (!trace) return original.call(this, input, init);\n\n let hostname = 'unknown';\n let path = '/';\n try {\n const url = new URL(urlString);\n hostname = url.hostname;\n path = `${url.pathname}${url.search}`;\n } catch { }\n\n const method = String(\n init?.method || input?.method || 'GET'\n ).toUpperCase();\n const span = startCapturedSpan(\n `${method} ${hostname}`,\n 'http',\n {\n url: urlString,\n method,\n library: 'fetch',\n 'http.request.method': method,\n 'url.full': urlString,\n 'url.path': path,\n 'server.address': hostname\n },\n options\n );\n\n if (!span) return original.call(this, input, init);\n\n const nextInit = { ...(init || {}) };\n const headers =\n typeof Headers !== 'undefined'\n ? new Headers(originalHeaders || undefined)\n : cloneHeaders(originalHeaders);\n\n if (typeof Headers !== 'undefined' && headers instanceof Headers) {\n headers.set('traceparent', generateTraceparent(trace.id, span.spanId));\n headers.set('x-senzor-trace-id', trace.id);\n headers.set('x-senzor-parent-span-id', span.spanId);\n } else {\n setHeader(headers as Record<string, unknown>, 'traceparent', generateTraceparent(trace.id, span.spanId));\n setHeader(headers as Record<string, unknown>, 'x-senzor-trace-id', trace.id);\n setHeader(headers as Record<string, unknown>, 'x-senzor-parent-span-id', span.spanId);\n }\n nextInit.headers = headers;\n\n return runWithCapturedSpan(span, async () => {\n try {\n const response = await original.call(this, input, nextInit);\n span.end(response.status, {\n 'http.response.status_code': response.status\n });\n return response;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nexport const instrumentHttp = (\n client: SenzorClient,\n ingestUrl: string,\n options?: SenzorOptions\n) => {\n let httpMod: any;\n let httpsMod: any;\n\n try { httpMod = require('http'); } catch { return; }\n try { httpsMod = require('https'); } catch {}\n\n if (httpMod?.Server?.prototype) {\n patchIncomingServer(httpMod.Server.prototype, 'http', client, options);\n }\n if (httpsMod?.Server?.prototype) {\n patchIncomingServer(httpsMod.Server.prototype, 'https', client, options);\n }\n\n patchOutgoing(httpMod, 'http:', ingestUrl, options);\n if (httpsMod) patchOutgoing(httpsMod, 'https:', ingestUrl, options);\n};\n","type HookFn = (exports: unknown) => unknown | void;\r\ntype HookMap = Map<string, HookFn[]>;\r\n\r\nlet Module: any;\r\nlet safeRequire: NodeRequire;\r\n\r\ntry {\r\n Module = require('module');\r\n safeRequire = Module.createRequire(\r\n typeof __filename !== 'undefined'\r\n ? __filename\r\n : process.cwd() + '/'\r\n );\r\n} catch {}\r\n\r\nconst SENZOR_PATCHED = Symbol.for('senzor.require.patched');\r\nconst SENZOR_HOOKS = Symbol.for('senzor.require.hooks');\r\n\r\nfunction getHookRegistry(): HookMap {\r\n const mod = Module as unknown as Record<symbol, HookMap>;\r\n\r\n if (!mod[SENZOR_HOOKS]) {\r\n Object.defineProperty(mod, SENZOR_HOOKS, {\r\n value: new Map(),\r\n enumerable: false\r\n });\r\n }\r\n\r\n return mod[SENZOR_HOOKS];\r\n}\r\n\r\nfunction runHooks(moduleName: string, exports: unknown) {\r\n const registry = (Module as unknown as Record<symbol, HookMap>)[SENZOR_HOOKS];\r\n if (!registry) return exports;\r\n\r\n const hooks = registry.get(moduleName);\r\n if (!hooks?.length) return exports;\r\n\r\n let currentExports = exports;\r\n\r\n for (const hook of hooks) {\r\n try {\r\n const nextExports = hook(currentExports);\r\n if (nextExports !== undefined) {\r\n currentExports = nextExports;\r\n }\r\n } catch (err) {\r\n console.error(`[Senzor] instrumentation failed for ${moduleName}`, err);\r\n }\r\n }\r\n\r\n return currentExports;\r\n}\r\n\r\nfunction patchLoaderOnce() {\r\n const mod = Module as unknown as any;\r\n\r\n if (mod[SENZOR_PATCHED]) return;\r\n\r\n const previousLoad = mod._load;\r\n\r\n mod._load = function patchedLoad(\r\n request: string,\r\n parent: unknown,\r\n isMain: boolean\r\n ) {\r\n const exports = previousLoad.apply(this, arguments);\r\n return runHooks(request, exports);\r\n };\r\n\r\n Object.defineProperty(mod, SENZOR_PATCHED, {\r\n value: true,\r\n enumerable: false\r\n });\r\n}\r\n\r\nfunction patchCached(moduleName: string, hook: HookFn) {\r\n try {\r\n const resolved = safeRequire.resolve(moduleName);\r\n const cached = safeRequire.cache?.[resolved];\r\n\r\n if (cached?.exports) {\r\n const replacement = hook(cached.exports);\r\n if (replacement !== undefined) {\r\n cached.exports = replacement;\r\n }\r\n }\r\n } catch { }\r\n}\r\n\r\nfunction tryRequire(moduleName: string, hook: HookFn) {\r\n try {\r\n const mod = safeRequire(moduleName);\r\n if (mod) {\r\n hook(mod);\r\n }\r\n } catch { }\r\n}\r\n\r\nfunction retryPatch(moduleName: string, hook: HookFn) {\r\n let attempts = 0;\r\n const max = 5;\r\n\r\n const timer = setInterval(() => {\r\n attempts++;\r\n\r\n try {\r\n const mod = safeRequire(moduleName);\r\n if (mod) {\r\n hook(mod);\r\n clearInterval(timer);\r\n }\r\n } catch { }\r\n\r\n if (attempts >= max) {\r\n clearInterval(timer);\r\n }\r\n }, 200);\r\n\r\n if (typeof timer.unref === 'function') timer.unref();\r\n}\r\n\r\nexport const hookRequire = (moduleName: string, onRequire: HookFn) => {\r\n if (!Module || !safeRequire) return;\r\n\r\n const registry = getHookRegistry();\r\n\r\n if (!registry.has(moduleName)) {\r\n registry.set(moduleName, []);\r\n }\r\n\r\n registry.get(moduleName)!.push(onRequire);\r\n\r\n patchLoaderOnce();\r\n patchCached(moduleName, onRequire);\r\n tryRequire(moduleName, onRequire);\r\n retryPatch(moduleName, onRequire);\r\n};\r\n","import { Context } from '../core/context';\nimport { SenzorOptions } from '../core/types';\nimport { CapturedSpan, runWithCapturedSpan, startCapturedSpan } from './span';\n\nexport type FrameworkSpanType =\n | 'middleware'\n | 'router'\n | 'request_handler'\n | 'route_handler'\n | 'controller_handler'\n | 'lifecycle_hook'\n | 'error_handler'\n | 'event_handler';\n\nexport interface FrameworkSpanInfo {\n framework: string;\n type: FrameworkSpanType;\n name: string;\n route?: string;\n method?: string;\n layerPath?: string;\n handlerName?: string;\n request?: any;\n response?: any;\n attributes?: Record<string, unknown>;\n}\n\ninterface InvokeOptions {\n callbackIndex?: number;\n callbackCompletesSpan?: boolean;\n responseEndsSpan?: boolean;\n}\n\nconst ignoredNextValues = new Set([undefined, null, 'route', 'router']);\n\nexport const shouldCaptureFrameworkSpan = (\n type: FrameworkSpanType,\n options?: SenzorOptions\n): boolean => {\n if (options?.frameworkSpans === false) return false;\n if (type === 'middleware' && options?.captureMiddlewareSpans === false) return false;\n if (type === 'router' && options?.captureRouterSpans === false) return false;\n if (type === 'lifecycle_hook' && options?.captureLifecycleHookSpans === false) return false;\n if (options?.ignoreFrameworkSpanTypes?.includes(type)) return false;\n return true;\n};\n\nconst statusFrom = (\n info: FrameworkSpanInfo,\n fallback = 0\n): number => {\n const res = info.response;\n return (\n res?.statusCode ||\n res?.status ||\n res?.raw?.statusCode ||\n res?.status_code ||\n fallback\n );\n};\n\nconst isPromiseLike = (value: unknown): value is Promise<unknown> =>\n Boolean(value && typeof (value as any).then === 'function');\n\nconst runWithParentOf = <T>(\n span: CapturedSpan,\n fn: () => T\n): T => {\n if (!span.parentSpanId) return fn();\n return Context.withActiveSpan(span.parentSpanId, fn);\n};\n\nconst copyFunctionProperties = (\n source: Function,\n target: Function\n) => {\n for (const key in source as any) {\n try {\n Object.defineProperty(target, key, {\n configurable: true,\n enumerable: true,\n get() {\n return (source as any)[key];\n },\n set(value) {\n (source as any)[key] = value;\n }\n });\n } catch { }\n }\n};\n\nexport const invokeWithFrameworkSpan = (\n handler: Function,\n thisArg: unknown,\n args: any[],\n info: FrameworkSpanInfo,\n options?: SenzorOptions,\n invokeOptions: InvokeOptions = {}\n) => {\n if (!shouldCaptureFrameworkSpan(info.type, options) || !Context.current()) {\n return handler.apply(thisArg, args);\n }\n\n const span = startCapturedSpan(\n info.name,\n 'function',\n {\n framework: info.framework,\n 'senzor.framework': info.framework,\n 'senzor.framework.type': info.type,\n 'http.route': info.route,\n route: info.route,\n method: info.method,\n layerPath: info.layerPath,\n handlerName: info.handlerName,\n ...info.attributes\n },\n options\n );\n\n if (!span) return handler.apply(thisArg, args);\n\n let ended = false;\n const cleanup: Array<() => void> = [];\n\n const endSpan = (\n status = statusFrom(info),\n meta: Record<string, unknown> = {}\n ) => {\n if (ended) return;\n ended = true;\n\n for (const clean of cleanup) {\n try { clean(); } catch { }\n }\n\n span.end(status, meta);\n };\n\n const res = info.response;\n if (invokeOptions.responseEndsSpan !== false && res?.once) {\n const onFinish = () =>\n endSpan(statusFrom(info), { completion: 'response.finish' });\n const onClose = () =>\n endSpan(statusFrom(info), { completion: 'response.close' });\n\n res.once('finish', onFinish);\n res.once('close', onClose);\n\n cleanup.push(() => {\n try { res.removeListener?.('finish', onFinish); } catch { }\n try { res.removeListener?.('close', onClose); } catch { }\n });\n }\n\n const callbackIndex =\n invokeOptions.callbackIndex ??\n args.findIndex((arg) => typeof arg === 'function');\n\n if (\n invokeOptions.callbackCompletesSpan !== false &&\n callbackIndex >= 0 &&\n typeof args[callbackIndex] === 'function'\n ) {\n const originalCallback = args[callbackIndex];\n args[callbackIndex] = function wrappedFrameworkCallback(\n this: unknown,\n ...callbackArgs: any[]\n ) {\n const maybeError = callbackArgs[0];\n const hasError = !ignoredNextValues.has(maybeError);\n\n endSpan(hasError ? 500 : statusFrom(info), {\n completion: 'callback',\n error: hasError ? String(maybeError?.message || maybeError) : undefined,\n 'error.type': hasError\n ? maybeError?.name || typeof maybeError\n : undefined\n });\n\n return runWithParentOf(span, () =>\n originalCallback.apply(this, callbackArgs)\n );\n };\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = handler.apply(thisArg, args);\n\n if (isPromiseLike(result)) {\n return result.then(\n (value) => {\n endSpan(statusFrom(info), { completion: 'promise.resolve' });\n return value;\n },\n (error) => {\n endSpan(500, {\n completion: 'promise.reject',\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n if (callbackIndex < 0 && invokeOptions.responseEndsSpan === false) {\n endSpan(statusFrom(info), { completion: 'sync.return' });\n }\n\n return result;\n } catch (error: any) {\n endSpan(500, {\n completion: 'throw',\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n};\n\nexport const wrapFrameworkHandler = <T extends Function>(\n handler: T,\n getInfo: (thisArg: unknown, args: any[]) => FrameworkSpanInfo,\n options?: SenzorOptions,\n invokeOptions: InvokeOptions = {}\n): T => {\n if (typeof handler !== 'function') return handler;\n\n const wrapped = function wrappedFrameworkHandler(\n this: unknown,\n ...args: any[]\n ) {\n return invokeWithFrameworkSpan(\n handler,\n this,\n args,\n getInfo(this, args),\n options,\n invokeOptions\n );\n };\n\n copyFunctionProperties(handler, wrapped);\n return wrapped as unknown as T;\n};\n\nexport const wrapFrameworkHandlerWithArity = <T extends Function>(\n handler: T,\n getInfo: (thisArg: unknown, args: any[]) => FrameworkSpanInfo,\n options?: SenzorOptions,\n invokeOptions: InvokeOptions = {}\n): T => {\n if (typeof handler !== 'function') return handler;\n\n const invoke = (thisArg: unknown, args: any[]) =>\n invokeWithFrameworkSpan(\n handler,\n thisArg,\n args,\n getInfo(thisArg, args),\n options,\n invokeOptions\n );\n\n let wrapped: Function;\n\n switch (handler.length) {\n case 4:\n wrapped = function wrapped4(this: unknown, a: any, b: any, c: any, d: any) {\n return invoke(this, [a, b, c, d]);\n };\n break;\n case 3:\n wrapped = function wrapped3(this: unknown, a: any, b: any, c: any) {\n return invoke(this, [a, b, c]);\n };\n break;\n case 2:\n wrapped = function wrapped2(this: unknown, a: any, b: any) {\n return invoke(this, [a, b]);\n };\n break;\n case 1:\n wrapped = function wrapped1(this: unknown, a: any) {\n return invoke(this, [a]);\n };\n break;\n default:\n wrapped = function wrapped0(this: unknown) {\n return invoke(this, Array.from(arguments));\n };\n break;\n }\n\n copyFunctionProperties(handler, wrapped);\n return wrapped as unknown as T;\n};\n","import { normalizePath } from '../core/normalizer';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { invokeWithFrameworkSpan } from './framework';\n\nconst LAYER_PATCHED = Symbol.for('senzor.express.layer.patched');\n\nconst routeMethods = new Set([\n 'checkout',\n 'copy',\n 'delete',\n 'get',\n 'head',\n 'lock',\n 'merge',\n 'mkactivity',\n 'mkcol',\n 'move',\n 'm-search',\n 'notify',\n 'options',\n 'patch',\n 'post',\n 'purge',\n 'put',\n 'report',\n 'search',\n 'subscribe',\n 'trace',\n 'unlock',\n 'unsubscribe'\n]);\n\nconst stringifyPath = (value: unknown): string | undefined => {\n if (typeof value === 'string') return value;\n if (value instanceof RegExp) return value.toString();\n if (Array.isArray(value)) {\n return value.map(stringifyPath).filter(Boolean).join(',');\n }\n if (typeof value === 'number') return String(value);\n return undefined;\n};\n\nconst getLayerPath = (args: any[]): string | undefined => {\n for (const arg of args) {\n if (typeof arg === 'function') return undefined;\n const path = stringifyPath(arg);\n if (path) return path;\n }\n\n return undefined;\n};\n\nconst getRequestRoute = (\n req: any,\n layer: any,\n layerPath?: string\n): string | undefined => {\n if (layer?.route?.path) {\n const routePath = stringifyPath(layer.route.path);\n const baseUrl = req?.baseUrl || '';\n // If baseUrl already ends with or contains the routePath, be careful\n return `${baseUrl}${routePath}` || routePath;\n }\n\n if (req?.route?.path) {\n const baseUrl = req?.baseUrl || '';\n return `${baseUrl}${req.route.path}`;\n }\n\n if (layerPath) {\n const baseUrl = req?.baseUrl || '';\n // If baseUrl already contains layerPath, don't double it\n if (baseUrl === layerPath || baseUrl.endsWith(layerPath)) {\n return baseUrl;\n }\n return `${baseUrl}${layerPath}` || layerPath;\n }\n\n const path = req?.originalUrl || req?.url || req?.path;\n return path ? normalizePath(String(path).split('?')[0]) : undefined;\n};\n\nconst getLayerType = (\n layer: any,\n original: Function,\n forcedType?: 'middleware' | 'router' | 'request_handler' | 'error_handler'\n) => {\n if (forcedType) return forcedType;\n if (original.length === 4) return 'error_handler' as const;\n if (layer?.route) return 'request_handler' as const;\n\n const isRouter =\n layer?.name === 'router' ||\n layer?.handle?.name === 'router' ||\n typeof layer?.handle?.stack !== 'undefined' ||\n typeof layer?.handle?.route === 'function';\n\n if (isRouter) return 'router' as const;\n return 'middleware' as const;\n};\n\nconst getRouteMethod = (layer: any, req: any): string | undefined => {\n if (layer?.route?.methods) {\n const method = Object.keys(layer.route.methods).find(\n (candidate) => layer.route.methods[candidate]\n );\n if (method) return method.toUpperCase();\n }\n\n return req?.method;\n};\n\nconst copyEnumerableProperties = (\n source: Function,\n target: Function\n) => {\n // Copy enumerable properties\n for (const key in source as any) {\n try {\n Object.defineProperty(target, key, {\n configurable: true,\n enumerable: true,\n get() {\n return (source as any)[key];\n },\n set(value) {\n (source as any)[key] = value;\n }\n });\n } catch { }\n }\n\n // Ensure 'stack' is copied even if not enumerable (though it usually is)\n if ((source as any).stack && !(target as any).stack) {\n try {\n (target as any).stack = (source as any).stack;\n } catch { }\n }\n};\n\nconst patchLayer = (\n layer: any,\n layerPath: string | undefined,\n options?: SenzorOptions,\n forcedType?: 'middleware' | 'router' | 'request_handler' | 'error_handler'\n) => {\n if (!layer || layer[LAYER_PATCHED] || typeof layer.handle !== 'function') {\n return;\n }\n\n Object.defineProperty(layer, LAYER_PATCHED, {\n value: true,\n enumerable: false\n });\n\n patchMethod(\n layer,\n 'handle',\n 'senzor.express.layer.handle',\n (original) => {\n const layerType = getLayerType(layer, original, forcedType);\n const handlerName =\n original.name ||\n layer.name ||\n (layerType === 'request_handler' ? 'handler' : layerType);\n\n if (original.length === 4) {\n const wrapped = function senzorExpressErrorHandler(\n this: unknown,\n err: any,\n req: any,\n res: any,\n next: Function\n ) {\n const route = getRequestRoute(req, layer, layerPath);\n return invokeWithFrameworkSpan(\n original,\n this,\n [err, req, res, next],\n {\n framework: 'express',\n type: 'error_handler',\n name: `express.error_handler ${route || handlerName}`,\n route,\n method: getRouteMethod(layer, req),\n layerPath,\n handlerName,\n request: req,\n response: res,\n attributes: {\n 'express.type': 'error_handler',\n 'express.layer.name': layer.name,\n error: err?.message,\n 'error.type': err?.name || typeof err\n }\n },\n options,\n {\n callbackIndex: 3,\n callbackCompletesSpan: true,\n responseEndsSpan: true\n }\n );\n };\n\n copyEnumerableProperties(original, wrapped);\n return wrapped;\n }\n\n const wrapped = function senzorExpressLayer(\n this: unknown,\n req: any,\n res: any,\n next: Function\n ) {\n const route = getRequestRoute(req, layer, layerPath);\n const method = getRouteMethod(layer, req);\n const displayRoute = route || layerPath || handlerName;\n const name =\n layerType === 'request_handler'\n ? `express.request_handler ${method || ''} ${displayRoute}`.trim()\n : `express.${layerType} ${displayRoute}`;\n\n return invokeWithFrameworkSpan(\n original,\n this,\n [req, res, next],\n {\n framework: 'express',\n type: layerType,\n name,\n route,\n method,\n layerPath,\n handlerName,\n request: req,\n response: res,\n attributes: {\n 'express.type': layerType,\n 'express.layer.name': layer.name,\n 'http.route': route\n }\n },\n options,\n {\n callbackIndex: 2,\n callbackCompletesSpan: true,\n responseEndsSpan: true\n }\n );\n };\n\n copyEnumerableProperties(original, wrapped);\n return wrapped;\n }\n );\n};\n\nconst patchRouteMethodHandlers = (\n route: any,\n routePath: string | undefined,\n options?: SenzorOptions\n) => {\n if (!route || route.__senzorRouteMethodsPatched) return;\n\n Object.defineProperty(route, '__senzorRouteMethodsPatched', {\n value: true,\n enumerable: false\n });\n\n for (const method of routeMethods) {\n if (typeof route[method] !== 'function') continue;\n\n patchMethod(\n route,\n method,\n `senzor.express.route.${method}`,\n (original) =>\n function patchedExpressRouteMethod(this: any, ...args: any[]) {\n const result = original.apply(this, args);\n const stack = this?.stack || [];\n\n for (const layer of stack) {\n patchLayer(layer, routePath, options, 'request_handler');\n }\n\n return result;\n }\n );\n }\n};\n\nconst getSafeRouter = (app: any) => {\n if (!app) return undefined;\n if (app._router) return app._router;\n try {\n // In Express 4, app.router is a getter that throws.\n // We only want it if it's not a throwing getter (Express 3)\n // or if it actually has a stack.\n const r = app.router;\n if (r && (r.stack || typeof r === 'function')) return r;\n } catch { }\n return undefined;\n};\n\nconst patchExpress = (\n expressModule: any,\n options?: SenzorOptions\n) => {\n if (!expressModule) return;\n\n const routerProto =\n typeof expressModule?.Router?.prototype?.use === 'function'\n ? expressModule.Router.prototype\n : expressModule.Router;\n\n patchMethod(\n routerProto,\n 'route',\n 'senzor.express.router.route',\n (original) =>\n function patchedExpressRoute(this: any, ...args: any[]) {\n const route = original.apply(this, args);\n const routePath = getLayerPath(args);\n const stack = this?.stack || [];\n\n const layer = stack[stack.length - 1];\n patchLayer(layer, routePath, options, 'router');\n patchRouteMethodHandlers(route, routePath, options);\n\n return route;\n }\n );\n\n patchMethod(\n routerProto,\n 'use',\n 'senzor.express.router.use',\n (original) =>\n function patchedExpressRouterUse(this: any, ...args: any[]) {\n const prevStackLength = this?.stack?.length || 0;\n const result = original.apply(this, args);\n const stack = this?.stack || [];\n\n for (let i = prevStackLength; i < stack.length; i++) {\n patchLayer(stack[i], getLayerPath(args), options);\n }\n return result;\n }\n );\n\n patchMethod(\n expressModule.application,\n 'use',\n 'senzor.express.application.use',\n (original) =>\n function patchedExpressApplicationUse(this: any, ...args: any[]) {\n const routerBefore = getSafeRouter(this);\n const prevStackLength = routerBefore?.stack?.length || 0;\n\n const result = original.apply(this, args);\n\n const routerAfter = getSafeRouter(this);\n const stack = routerAfter?.stack || [];\n\n for (let i = prevStackLength; i < stack.length; i++) {\n patchLayer(stack[i], getLayerPath(args), options);\n }\n return result;\n }\n );\n};\n\nexport const instrumentExpress = (options?: SenzorOptions) => {\n hookRequire('express', (exports: any) => {\n patchExpress(exports, options);\n if (exports?.default) patchExpress(exports.default, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { wrapFrameworkHandlerWithArity } from './framework';\n\nconst FACTORY_PATCHED = Symbol.for('senzor.fastify.factory.patched');\nconst INSTANCE_PATCHED = Symbol.for('senzor.fastify.instance.patched');\n\nconst lifecycleHookNames = new Set([\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preHandler',\n 'preSerialization',\n 'onSend',\n 'onResponse',\n 'onError',\n 'onTimeout',\n 'onRequestAbort'\n]);\n\nconst routeLifecycleKeys = [\n 'onRequest',\n 'preParsing',\n 'preValidation',\n 'preHandler',\n 'preSerialization',\n 'onSend',\n 'onResponse',\n 'onError'\n];\n\nconst getRoute = (request: any, fallback?: string): string | undefined =>\n request?.routeOptions?.url ||\n request?.routerPath ||\n request?.context?.config?.url ||\n fallback;\n\nconst wrapHook = (\n hookName: string,\n handler: any,\n options?: SenzorOptions,\n route?: string\n) => {\n if (typeof handler !== 'function') return handler;\n\n return wrapFrameworkHandlerWithArity(\n handler,\n (_thisArg, args) => {\n const request = args[0];\n const reply = args[1];\n const currentRoute = getRoute(request, route);\n\n return {\n framework: 'fastify',\n type: hookName === 'onError' ? 'error_handler' : 'lifecycle_hook',\n name: `fastify.${hookName} ${currentRoute || request?.url || ''}`.trim(),\n route: currentRoute,\n method: request?.method,\n handlerName: handler.name || hookName,\n request,\n response: reply?.raw || reply,\n attributes: {\n 'fastify.hook': hookName,\n 'fastify.type': hookName === 'onError' ? 'error_handler' : 'lifecycle_hook',\n 'http.route': currentRoute,\n url: request?.url\n }\n };\n },\n options,\n {\n callbackCompletesSpan: true,\n responseEndsSpan: false\n }\n );\n};\n\nconst wrapRouteHandler = (\n handler: any,\n options?: SenzorOptions,\n route?: string\n) => {\n if (typeof handler !== 'function') return handler;\n\n return wrapFrameworkHandlerWithArity(\n handler,\n (_thisArg, args) => {\n const request = args[0];\n const reply = args[1];\n const currentRoute = getRoute(request, route);\n\n return {\n framework: 'fastify',\n type: 'route_handler',\n name: `fastify.route_handler ${request?.method || ''} ${currentRoute || request?.url || ''}`.trim(),\n route: currentRoute,\n method: request?.method,\n handlerName: handler.name || 'handler',\n request,\n response: reply?.raw || reply,\n attributes: {\n 'fastify.type': 'route_handler',\n 'http.route': currentRoute,\n url: request?.url\n }\n };\n },\n options,\n {\n callbackCompletesSpan: true,\n responseEndsSpan: true\n }\n );\n};\n\nconst wrapMaybeArray = (\n value: any,\n wrap: (handler: any) => any\n) => {\n if (Array.isArray(value)) return value.map(wrap);\n return wrap(value);\n};\n\nconst patchFastifyInstance = (\n instance: any,\n options?: SenzorOptions\n) => {\n if (!instance || instance[INSTANCE_PATCHED]) return instance;\n\n Object.defineProperty(instance, INSTANCE_PATCHED, {\n value: true,\n enumerable: false\n });\n\n patchMethod(\n instance,\n 'addHook',\n 'senzor.fastify.addHook',\n (original) =>\n function patchedFastifyAddHook(this: any, hookName: string, handler: any) {\n if (lifecycleHookNames.has(hookName)) {\n return original.call(this, hookName, wrapHook(hookName, handler, options));\n }\n\n return original.apply(this, arguments as any);\n }\n );\n\n patchMethod(\n instance,\n 'route',\n 'senzor.fastify.route',\n (original) =>\n function patchedFastifyRoute(this: any, routeOptions: any) {\n if (!routeOptions || typeof routeOptions !== 'object') {\n return original.apply(this, arguments as any);\n }\n\n const nextRouteOptions = { ...routeOptions };\n const route =\n nextRouteOptions.url ||\n nextRouteOptions.path ||\n nextRouteOptions.routePath;\n\n if (nextRouteOptions.handler) {\n nextRouteOptions.handler = wrapRouteHandler(\n nextRouteOptions.handler,\n options,\n route\n );\n }\n\n for (const key of routeLifecycleKeys) {\n if (nextRouteOptions[key]) {\n nextRouteOptions[key] = wrapMaybeArray(\n nextRouteOptions[key],\n (handler) => wrapHook(key, handler, options, route)\n );\n }\n }\n\n return original.call(this, nextRouteOptions);\n }\n );\n\n patchMethod(\n instance,\n 'setErrorHandler',\n 'senzor.fastify.setErrorHandler',\n (original) =>\n function patchedFastifySetErrorHandler(this: any, handler: any) {\n return original.call(\n this,\n wrapFrameworkHandlerWithArity(\n handler,\n (_thisArg, args) => {\n const request = args[1];\n const reply = args[2];\n const route = getRoute(request);\n\n return {\n framework: 'fastify',\n type: 'error_handler',\n name: `fastify.error_handler ${route || request?.url || ''}`.trim(),\n route,\n method: request?.method,\n handlerName: handler?.name || 'errorHandler',\n request,\n response: reply?.raw || reply,\n attributes: {\n 'fastify.type': 'error_handler',\n error: args[0]?.message,\n 'error.type': args[0]?.name || typeof args[0]\n }\n };\n },\n options,\n {\n callbackCompletesSpan: true,\n responseEndsSpan: true\n }\n )\n );\n }\n );\n\n return instance;\n};\n\nconst copyFactoryProperties = (\n source: any,\n target: any\n) => {\n for (const key of Reflect.ownKeys(source)) {\n if (['length', 'name', 'prototype'].includes(String(key))) continue;\n\n try {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)!);\n } catch { }\n }\n};\n\nconst wrapFastifyFactory = (\n factory: any,\n options?: SenzorOptions\n) => {\n if (typeof factory !== 'function' || factory[FACTORY_PATCHED]) {\n return factory;\n }\n\n const wrapped = function senzorFastifyFactory(this: unknown, ...args: any[]) {\n const instance = factory.apply(this, args);\n return patchFastifyInstance(instance, options);\n };\n\n copyFactoryProperties(factory, wrapped);\n\n Object.defineProperty(wrapped, FACTORY_PATCHED, {\n value: true,\n enumerable: false\n });\n\n const mutableWrapped = wrapped as any;\n\n if (mutableWrapped.fastify === factory) {\n mutableWrapped.fastify = mutableWrapped;\n }\n if (mutableWrapped.default === factory) {\n mutableWrapped.default = mutableWrapped;\n }\n\n return mutableWrapped;\n};\n\nexport const instrumentFastify = (options?: SenzorOptions) => {\n hookRequire('fastify', (exports: any) => {\n if (typeof exports === 'function') {\n return wrapFastifyFactory(exports, options);\n }\n\n if (exports?.fastify) {\n exports.fastify = wrapFastifyFactory(exports.fastify, options);\n }\n if (exports?.default) {\n exports.default = wrapFastifyFactory(exports.default, options);\n }\n\n return exports;\n });\n};\n\nexport const instrumentFastifyInstance = (\n instance: any,\n options?: SenzorOptions\n) => patchFastifyInstance(instance, options);\n","import { normalizePath } from '../core/normalizer';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { wrapFrameworkHandlerWithArity } from './framework';\n\nconst routerMethods = [\n 'all',\n 'del',\n 'delete',\n 'get',\n 'head',\n 'options',\n 'patch',\n 'post',\n 'put'\n];\n\nconst stringifyPath = (value: unknown): string | undefined => {\n if (typeof value === 'string') return value;\n if (value instanceof RegExp) return value.toString();\n if (Array.isArray(value)) {\n return value.map(stringifyPath).filter(Boolean).join(',');\n }\n return undefined;\n};\n\nconst getPathFromArgs = (args: any[]): string | undefined => {\n for (const arg of args) {\n if (typeof arg === 'function') return undefined;\n const path = stringifyPath(arg);\n if (path) return path;\n }\n\n return undefined;\n};\n\nconst wrapKoaMiddleware = (\n middleware: any,\n options?: SenzorOptions,\n layerPath?: string,\n layerType: 'middleware' | 'router' | 'route_handler' = 'middleware',\n method?: string\n) => {\n if (typeof middleware !== 'function') return middleware;\n\n return wrapFrameworkHandlerWithArity(\n middleware,\n (_thisArg, args) => {\n const ctx = args[0];\n const route =\n ctx?._matchedRoute ||\n ctx?.matched?.[0]?.path ||\n layerPath ||\n normalizePath(ctx?.path || ctx?.request?.path || '/');\n const actualMethod = method || ctx?.method || ctx?.request?.method;\n const handlerName = middleware.name || layerType;\n\n return {\n framework: 'koa',\n type: layerType,\n name:\n layerType === 'route_handler'\n ? `koa.request_handler ${actualMethod || ''} ${route}`.trim()\n : `koa.${layerType} ${route || handlerName}`,\n route,\n method: actualMethod,\n layerPath,\n handlerName,\n request: ctx?.req || ctx?.request,\n response: ctx?.res || ctx?.response,\n attributes: {\n 'koa.type': layerType,\n 'http.route': route,\n path: ctx?.path || ctx?.request?.path\n }\n };\n },\n options,\n {\n callbackCompletesSpan: false,\n responseEndsSpan: false\n }\n );\n};\n\nconst patchKoaApplication = (\n koa: any,\n options?: SenzorOptions\n) => {\n const proto = koa?.prototype || koa?.default?.prototype;\n if (!proto) return;\n\n patchMethod(\n proto,\n 'use',\n 'senzor.koa.application.use',\n (original) =>\n function patchedKoaUse(this: any, middleware: any) {\n return original.call(\n this,\n wrapKoaMiddleware(middleware, options, undefined, 'middleware')\n );\n }\n );\n};\n\nconst patchKoaRouter = (\n routerModule: any,\n options?: SenzorOptions\n) => {\n const Router =\n routerModule?.Router ||\n routerModule?.default ||\n routerModule;\n const proto = Router?.prototype;\n if (!proto) return;\n\n patchMethod(\n proto,\n 'use',\n 'senzor.koa.router.use',\n (original) =>\n function patchedKoaRouterUse(this: any, ...args: any[]) {\n const layerPath = getPathFromArgs(args);\n const nextArgs = args.map((arg) =>\n typeof arg === 'function'\n ? wrapKoaMiddleware(arg, options, layerPath, 'router')\n : arg\n );\n return original.apply(this, nextArgs);\n }\n );\n\n for (const method of routerMethods) {\n patchMethod(\n proto,\n method,\n `senzor.koa.router.${method}`,\n (original) =>\n function patchedKoaRouterMethod(this: any, ...args: any[]) {\n const layerPath = getPathFromArgs(args);\n const nextArgs = args.map((arg) =>\n typeof arg === 'function'\n ? wrapKoaMiddleware(\n arg,\n options,\n layerPath,\n 'route_handler',\n method.toUpperCase()\n )\n : arg\n );\n\n return original.apply(this, nextArgs);\n }\n );\n }\n};\n\nexport const instrumentKoa = (options?: SenzorOptions) => {\n hookRequire('koa', (exports: any) => {\n patchKoaApplication(exports, options);\n });\n\n hookRequire('@koa/router', (exports: any) => {\n patchKoaRouter(exports, options);\n });\n\n hookRequire('koa-router', (exports: any) => {\n patchKoaRouter(exports, options);\n });\n};\n","import { normalizePath } from '../core/normalizer';\nimport { SenzorOptions } from '../core/types';\nimport { SENZOR_INTERNAL_HEADER } from '../utils/internal';\nimport { generateTraceparent } from '../utils/traceContext';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\nconst hasInternalHeader = (headers: any): boolean => {\n if (!headers) return false;\n if (Array.isArray(headers)) {\n return headers.some(\n ([key, value]) =>\n String(key).toLowerCase() === SENZOR_INTERNAL_HEADER &&\n String(value).toLowerCase() === 'true'\n );\n }\n\n return Object.entries(headers).some(\n ([key, value]) =>\n key.toLowerCase() === SENZOR_INTERNAL_HEADER &&\n String(value).toLowerCase() === 'true'\n );\n};\n\nconst setHeader = (headers: any, key: string, value: string) => {\n if (Array.isArray(headers)) {\n headers.push([key, value]);\n return headers;\n }\n\n const nextHeaders = { ...(headers || {}) };\n const existingKey = Object.keys(nextHeaders).find(\n (header) => header.toLowerCase() === key.toLowerCase()\n );\n nextHeaders[existingKey || key] = value;\n return nextHeaders;\n};\n\nconst getUrlDetails = (input: any) => {\n try {\n const url = new URL(String(input));\n return {\n url: url.toString(),\n hostname: url.hostname,\n path: `${url.pathname}${url.search}`\n };\n } catch {\n return {\n url: String(input || ''),\n hostname: 'unknown',\n path: '/'\n };\n }\n};\n\nconst patchRequestLike = (\n target: any,\n methodName: string,\n patchKey: string,\n options?: SenzorOptions\n) => {\n patchMethod(\n target,\n methodName,\n patchKey,\n (original) =>\n function patchedUndiciRequest(this: any, input: any, opts?: any, cb?: any) {\n if (hasInternalHeader(opts?.headers)) {\n return original.apply(this, arguments as any);\n }\n\n const details = getUrlDetails(input?.origin ? input.origin : input);\n const method = String(opts?.method || 'GET').toUpperCase();\n const span = startCapturedSpan(\n `${method} ${details.hostname}`,\n 'http',\n {\n url: details.url,\n method,\n route: normalizePath(details.path),\n library: 'undici',\n 'http.request.method': method,\n 'url.full': details.url,\n 'url.path': details.path,\n 'server.address': details.hostname\n },\n options\n );\n\n if (!span) return original.apply(this, arguments as any);\n\n const nextOptions = { ...(opts || {}) };\n nextOptions.headers = setHeader(\n nextOptions.headers,\n 'traceparent',\n generateTraceparent(span.trace!.id, span.spanId)\n );\n nextOptions.headers = setHeader(\n nextOptions.headers,\n 'x-senzor-trace-id',\n span.trace!.id\n );\n nextOptions.headers = setHeader(\n nextOptions.headers,\n 'x-senzor-parent-span-id',\n span.spanId\n );\n\n const wrappedCallback =\n typeof cb === 'function'\n ? function wrappedUndiciCallback(this: unknown, err: any, data: any) {\n span.end(err ? 500 : data?.statusCode || 0, {\n error: err?.message,\n 'error.type': err?.name,\n 'http.response.status_code': data?.statusCode\n });\n return cb.apply(this, arguments as any);\n }\n : cb;\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(\n this,\n input,\n nextOptions,\n wrappedCallback\n );\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(value?.statusCode || value?.status || 0, {\n 'http.response.status_code':\n value?.statusCode || value?.status\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n if (typeof wrappedCallback !== 'function') {\n span.end(0);\n }\n\n return result;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nconst patchUndici = (undici: any, options?: SenzorOptions) => {\n patchRequestLike(undici, 'request', 'senzor.undici.request', options);\n patchRequestLike(undici, 'stream', 'senzor.undici.stream', options);\n patchRequestLike(undici, 'pipeline', 'senzor.undici.pipeline', options);\n\n [\n undici?.Client?.prototype,\n undici?.Pool?.prototype,\n undici?.Agent?.prototype,\n undici?.ProxyAgent?.prototype\n ].forEach((proto, index) => {\n patchRequestLike(\n proto,\n 'request',\n `senzor.undici.dispatcher.${index}.request`,\n options\n );\n });\n};\n\nexport const instrumentUndici = (options?: SenzorOptions) => {\n hookRequire('undici', (exports: any) => patchUndici(exports, options));\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\nconst collectionName = (collection: any): string =>\n collection?.collectionName ||\n collection?.s?.namespace?.collection ||\n collection?.namespace?.collection ||\n 'unknown';\n\nconst databaseName = (collection: any): string | undefined =>\n collection?.dbName ||\n collection?.s?.namespace?.db ||\n collection?.namespace?.db;\n\nconst cursorCollectionName = (cursor: any): string =>\n cursor?.namespace?.collection ||\n cursor?.ns?.collection ||\n cursor?.cursorNamespace?.collection ||\n 'unknown';\n\nconst patchCollectionMethod = (\n proto: any,\n method: string,\n options?: SenzorOptions\n) => {\n patchMethod(\n proto,\n method,\n `senzor.mongodb.collection.${method}`,\n (original) =>\n function patchedMongoCollection(this: any, ...args: any[]) {\n const collection = collectionName(this);\n const span = startCapturedSpan(\n `MongoDB ${method}`,\n 'db',\n {\n collection,\n operation: method,\n 'db.system.name': 'mongodb',\n 'db.collection.name': collection,\n 'db.namespace': databaseName(this)\n ? `${databaseName(this)}.${collection}`\n : collection,\n 'db.operation.name': method,\n library: 'mongodb'\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, {\n matchedCount: value?.matchedCount,\n modifiedCount: value?.modifiedCount,\n deletedCount: value?.deletedCount,\n insertedCount: value?.insertedCount\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nconst patchCursorMethod = (\n proto: any,\n method: string,\n operation: string,\n options?: SenzorOptions\n) => {\n patchMethod(\n proto,\n method,\n `senzor.mongodb.cursor.${operation}.${method}`,\n (original) =>\n function patchedMongoCursor(this: any, ...args: any[]) {\n const collection = cursorCollectionName(this);\n const span = startCapturedSpan(\n `MongoDB ${operation}`,\n 'db',\n {\n collection,\n operation,\n 'db.system.name': 'mongodb',\n 'db.collection.name': collection,\n 'db.operation.name': operation,\n library: 'mongodb'\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, {\n resultCount: Array.isArray(value) ? value.length : undefined\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nconst patchMongo = (mongodb: any, options?: SenzorOptions) => {\n const Collection = mongodb?.Collection || mongodb?.default?.Collection;\n const collectionProto = Collection?.prototype;\n\n [\n 'insertOne',\n 'insertMany',\n 'updateOne',\n 'updateMany',\n 'replaceOne',\n 'deleteOne',\n 'deleteMany',\n 'findOne',\n 'findOneAndUpdate',\n 'findOneAndDelete',\n 'findOneAndReplace',\n 'countDocuments',\n 'estimatedDocumentCount',\n 'distinct',\n 'bulkWrite',\n 'createIndex',\n 'dropIndex'\n ].forEach((method) =>\n patchCollectionMethod(collectionProto, method, options)\n );\n\n const FindCursor =\n mongodb?.FindCursor || mongodb?.default?.FindCursor;\n const AggregationCursor =\n mongodb?.AggregationCursor || mongodb?.default?.AggregationCursor;\n\n ['toArray', 'next', 'forEach'].forEach((method) =>\n patchCursorMethod(FindCursor?.prototype, method, 'find', options)\n );\n ['toArray', 'next', 'forEach'].forEach((method) =>\n patchCursorMethod(\n AggregationCursor?.prototype,\n method,\n 'aggregate',\n options\n )\n );\n};\n\nexport const instrumentMongo = (options?: SenzorOptions) => {\n hookRequire('mongodb', (exports: any) => patchMongo(exports, options));\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\nconst modelName = (target: any): string =>\n target?.model?.modelName ||\n target?.constructor?.modelName ||\n target?.modelName ||\n 'unknown';\n\nconst collectionName = (target: any): string =>\n target?.mongooseCollection?.name ||\n target?.collection?.name ||\n target?.model?.collection?.name ||\n 'unknown';\n\nconst patchExec = (\n proto: any,\n label: 'query' | 'aggregate',\n options?: SenzorOptions\n) => {\n patchMethod(\n proto,\n 'exec',\n `senzor.mongoose.${label}.exec`,\n (original) =>\n function patchedMongooseExec(this: any, ...args: any[]) {\n const operation =\n String(this?.op || this?._op || label).toUpperCase();\n const collection = collectionName(this);\n const span = startCapturedSpan(\n `Mongoose ${operation}`,\n 'db',\n {\n collection,\n model: modelName(this),\n operation,\n 'db.system.name': 'mongodb',\n 'db.collection.name': collection,\n 'db.operation.name': operation,\n library: 'mongoose'\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, {\n resultCount: Array.isArray(value) ? value.length : undefined\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nconst patchSave = (modelProto: any, options?: SenzorOptions) => {\n patchMethod(\n modelProto,\n 'save',\n 'senzor.mongoose.model.save',\n (original) =>\n function patchedMongooseSave(this: any, ...args: any[]) {\n const collection = collectionName(this);\n const span = startCapturedSpan(\n 'Mongoose SAVE',\n 'db',\n {\n collection,\n model: modelName(this),\n operation: 'SAVE',\n 'db.system.name': 'mongodb',\n 'db.collection.name': collection,\n 'db.operation.name': 'SAVE',\n library: 'mongoose'\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0);\n return value;\n },\n (error: any) => {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nconst patchMongoose = (mongoose: any, options?: SenzorOptions) => {\n patchExec(mongoose?.Query?.prototype, 'query', options);\n patchExec(mongoose?.Aggregate?.prototype, 'aggregate', options);\n patchSave(mongoose?.Model?.prototype, options);\n\n if (mongoose?.default) {\n patchExec(mongoose.default?.Query?.prototype, 'query', options);\n patchExec(mongoose.default?.Aggregate?.prototype, 'aggregate', options);\n patchSave(mongoose.default?.Model?.prototype, options);\n }\n};\n\nexport const instrumentMongoose = (options?: SenzorOptions) => {\n hookRequire('mongoose', (exports: any) => patchMongoose(exports, options));\n};\n","import { getSqlOperation, normalizeSql } from '../core/sanitizer';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\nconst extractSql = (args: any[]): string | undefined => {\n const first = args[0];\n if (typeof first === 'string') return first;\n if (first && typeof first.text === 'string') return first.text;\n return undefined;\n};\n\nconst wrapQueryMethod = (\n proto: any,\n label: string,\n options?: SenzorOptions\n) => {\n patchMethod(\n proto,\n 'query',\n `senzor.pg.${label}.query`,\n (original) =>\n function patchedPgQuery(this: any, ...args: any[]) {\n const sql = extractSql(args);\n const operation = getSqlOperation(sql) || 'QUERY';\n const span = startCapturedSpan(\n `Postgres ${operation}`,\n 'db',\n {\n query: normalizeSql(sql, options),\n operation,\n 'db.system.name': 'postgresql',\n 'db.operation.name': operation,\n 'db.query.text': normalizeSql(sql, options),\n library: 'pg'\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n const callbackIndex = args.findIndex(\n (arg) => typeof arg === 'function'\n );\n\n if (callbackIndex >= 0) {\n const originalCallback = args[callbackIndex];\n args[callbackIndex] = function wrappedPgCallback(\n this: unknown,\n err: Error | null,\n result: any\n ) {\n span.end(err ? 500 : 0, {\n error: err?.message,\n 'error.type': err?.name,\n rowCount: result?.rowCount,\n 'db.response.row_count': result?.rowCount\n });\n\n return originalCallback.apply(this, arguments as any);\n };\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, {\n rowCount: value?.rowCount,\n 'db.response.row_count': value?.rowCount\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n if (\n callbackIndex < 0 &&\n result &&\n typeof result.once === 'function'\n ) {\n result.once('end', () => span.end(0));\n result.once('error', (error: Error) =>\n span.end(500, {\n error: error.message,\n 'error.type': error.name\n })\n );\n } else if (callbackIndex < 0) {\n span.end(0);\n }\n\n return result;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nconst patchPg = (pg: any, options?: SenzorOptions) => {\n if (!pg) return;\n\n wrapQueryMethod(pg.Client?.prototype, 'client', options);\n wrapQueryMethod(pg.Pool?.prototype, 'pool', options);\n\n if (pg.default) {\n wrapQueryMethod(pg.default.Client?.prototype, 'default.client', options);\n wrapQueryMethod(pg.default.Pool?.prototype, 'default.pool', options);\n }\n};\n\nexport const instrumentPg = (options?: SenzorOptions) => {\n hookRequire('pg', (exports: any) => patchPg(exports, options));\n};\n","import { getSqlOperation, normalizeSql } from '../core/sanitizer';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\nconst extractSql = (args: any[]): string | undefined => {\n const first = args[0];\n if (typeof first === 'string') return first;\n if (first && typeof first.sql === 'string') return first.sql;\n return undefined;\n};\n\nconst patchSqlMethod = (\n proto: any,\n method: 'query' | 'execute',\n library: string,\n options?: SenzorOptions\n) => {\n patchMethod(\n proto,\n method,\n `senzor.${library}.${method}`,\n (original) =>\n function patchedMysqlMethod(this: any, ...args: any[]) {\n const sql = extractSql(args);\n const operation = getSqlOperation(sql) || method.toUpperCase();\n const span = startCapturedSpan(\n `MySQL ${operation}`,\n 'db',\n {\n query: normalizeSql(sql, options),\n operation,\n 'db.system.name': 'mysql',\n 'db.operation.name': operation,\n 'db.query.text': normalizeSql(sql, options),\n library\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n const callbackIndex = args.findIndex(\n (arg) => typeof arg === 'function'\n );\n if (callbackIndex >= 0) {\n const originalCallback = args[callbackIndex];\n args[callbackIndex] = function wrappedMysqlCallback(\n this: unknown,\n err: any,\n rows: any\n ) {\n span.end(err ? 500 : 0, {\n error: err?.message,\n 'error.type': err?.name,\n rowCount: Array.isArray(rows) ? rows.length : undefined\n });\n return originalCallback.apply(this, arguments as any);\n };\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n const rows = Array.isArray(value) ? value[0] : value;\n span.end(0, {\n rowCount: Array.isArray(rows) ? rows.length : undefined\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n if (\n callbackIndex < 0 &&\n result &&\n typeof result.once === 'function'\n ) {\n result.once('end', () => span.end(0));\n result.once('error', (error: Error) =>\n span.end(500, {\n error: error.message,\n 'error.type': error.name\n })\n );\n } else if (callbackIndex < 0) {\n span.end(0);\n }\n\n return result;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nconst patchKnownPrototypes = (\n mysql: any,\n library: string,\n options?: SenzorOptions\n) => {\n [\n mysql?.Connection?.prototype,\n mysql?.Pool?.prototype,\n mysql?.PoolConnection?.prototype,\n mysql?.PromiseConnection?.prototype,\n mysql?.PromisePool?.prototype,\n mysql?.default?.Connection?.prototype,\n mysql?.default?.Pool?.prototype\n ].forEach((proto) => {\n patchSqlMethod(proto, 'query', library, options);\n patchSqlMethod(proto, 'execute', library, options);\n });\n};\n\nconst patchFactories = (\n mysql: any,\n library: string,\n options?: SenzorOptions\n) => {\n ['createConnection', 'createPool'].forEach((factory) => {\n patchMethod(\n mysql,\n factory,\n `senzor.${library}.${factory}`,\n (original) =>\n function patchedMysqlFactory(this: any, ...args: any[]) {\n const client = original.apply(this, args);\n patchSqlMethod(client, 'query', library, options);\n patchSqlMethod(client, 'execute', library, options);\n patchSqlMethod(Object.getPrototypeOf(client), 'query', library, options);\n patchSqlMethod(Object.getPrototypeOf(client), 'execute', library, options);\n return client;\n }\n );\n });\n};\n\nconst patchMysql = (\n mysql: any,\n library: string,\n options?: SenzorOptions\n) => {\n patchKnownPrototypes(mysql, library, options);\n patchFactories(mysql, library, options);\n};\n\nexport const instrumentMysql = (options?: SenzorOptions) => {\n hookRequire('mysql', (exports: any) => patchMysql(exports, 'mysql', options));\n hookRequire('mysql2', (exports: any) => patchMysql(exports, 'mysql2', options));\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\nconst getCommandName = (command: any): string => {\n if (typeof command === 'string') return command.toUpperCase();\n if (Array.isArray(command)) return String(command[0] || 'COMMAND').toUpperCase();\n if (command?.name) return String(command.name).toUpperCase();\n if (Array.isArray(command?.args)) return String(command.args[0] || 'COMMAND').toUpperCase();\n return 'COMMAND';\n};\n\nconst patchSendCommand = (\n target: any,\n label: string,\n options?: SenzorOptions\n) => {\n patchMethod(\n target,\n 'sendCommand',\n `senzor.redis.${label}.sendCommand`,\n (original) =>\n function patchedRedisSendCommand(this: any, command: any, ...args: any[]) {\n const commandName = getCommandName(command);\n const span = startCapturedSpan(\n `Redis ${commandName}`,\n 'db',\n {\n command: commandName,\n operation: commandName,\n 'db.system.name': label === 'ioredis' ? 'redis' : 'redis',\n 'db.operation.name': commandName,\n library: label\n },\n options\n );\n\n if (!span) return original.apply(this, arguments as any);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, command, ...args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0);\n return value;\n },\n (error: any) => {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n error: error?.message,\n 'error.type': error?.name || 'Error'\n });\n throw error;\n }\n });\n }\n );\n};\n\nconst patchCreatedClient = (\n client: any,\n label: string,\n options?: SenzorOptions\n) => {\n patchSendCommand(client, label, options);\n patchSendCommand(Object.getPrototypeOf(client), label, options);\n return client;\n};\n\nconst patchRedisPackage = (redis: any, options?: SenzorOptions) => {\n ['createClient', 'createCluster'].forEach((factory) => {\n patchMethod(\n redis,\n factory,\n `senzor.redis.${factory}`,\n (original) =>\n function patchedRedisFactory(this: any, ...args: any[]) {\n const client = original.apply(this, args);\n return patchCreatedClient(client, 'redis', options);\n }\n );\n });\n};\n\nconst patchIORedisPackage = (ioredis: any, options?: SenzorOptions) => {\n patchSendCommand(ioredis?.prototype, 'ioredis', options);\n patchSendCommand(ioredis?.Redis?.prototype, 'ioredis', options);\n patchSendCommand(ioredis?.Cluster?.prototype, 'ioredis-cluster', options);\n patchSendCommand(ioredis?.default?.prototype, 'ioredis', options);\n};\n\nexport const instrumentRedis = (options?: SenzorOptions) => {\n hookRequire('redis', (exports: any) => patchRedisPackage(exports, options));\n hookRequire('ioredis', (exports: any) => patchIORedisPackage(exports, options));\n};\n","import type { SenzorClient } from '../core/client';\r\nimport { hookRequire } from './hook';\r\nimport { Context } from '../core/context';\r\n\r\nconst PATCHED =\r\n Symbol.for(\r\n 'senzor.bullmq.patched'\r\n );\r\n\r\nfunction patchWorker(\r\n target: any,\r\n client: SenzorClient,\r\n debug: boolean\r\n) {\r\n\r\n if (\r\n !target?.Worker?.prototype\r\n ) {\r\n return;\r\n }\r\n\r\n const proto =\r\n target.Worker.prototype;\r\n\r\n const original =\r\n proto.processJob;\r\n\r\n if (\r\n typeof original !==\r\n 'function' ||\r\n original[PATCHED]\r\n ) {\r\n return;\r\n }\r\n\r\n proto.processJob =\r\n async function (\r\n job: any\r\n ) {\r\n\r\n const queueDelay =\r\n job.timestamp\r\n ? Date.now() -\r\n job.timestamp\r\n : 0;\r\n\r\n const currentAttempt =\r\n (job.attemptsMade || 0)\r\n + 1;\r\n\r\n const maxAttempts =\r\n job.opts?.attempts\r\n ?? 1;\r\n\r\n const isFinal =\r\n currentAttempt >=\r\n maxAttempts;\r\n\r\n const taskName =\r\n job.name ===\r\n '__default__'\r\n ? job.queueName\r\n : `${job.queueName}:${job.name}`;\r\n\r\n return client.startTask(\r\n\r\n taskName,\r\n\r\n 'queue',\r\n\r\n {\r\n queueDelay,\r\n attempts:\r\n currentAttempt,\r\n isDeadLetter: false,\r\n metadata: {\r\n jobId: job.id,\r\n queueName:\r\n job.queueName,\r\n maxAttempts\r\n }\r\n },\r\n\r\n async () => {\r\n\r\n try {\r\n\r\n const result =\r\n await original.call(\r\n this,\r\n job\r\n );\r\n\r\n client.endTask(\r\n 'success'\r\n );\r\n\r\n return result;\r\n\r\n }\r\n catch (error) {\r\n\r\n try {\r\n\r\n const ctx =\r\n Context.current();\r\n\r\n if (\r\n ctx &&\r\n ctx.contextType === 'task' &&\r\n isFinal\r\n ) {\r\n\r\n ctx.data\r\n .isDeadLetter =\r\n true;\r\n\r\n }\r\n\r\n }\r\n catch { }\r\n\r\n client.captureError(\r\n error,\r\n {\r\n queueName:\r\n job.queueName,\r\n jobId: job.id,\r\n isDeadLetter:\r\n isFinal\r\n }\r\n );\r\n\r\n client.endTask(\r\n 'failed'\r\n );\r\n\r\n throw error;\r\n\r\n }\r\n\r\n }\r\n\r\n );\r\n\r\n };\r\n\r\n Object.defineProperty(\r\n proto.processJob,\r\n PATCHED,\r\n {\r\n value: true\r\n }\r\n );\r\n\r\n if (debug) {\r\n\r\n console.log(\r\n '[Senzor] BullMQ instrumented'\r\n );\r\n\r\n }\r\n\r\n}\r\n\r\nexport const instrumentBullMQ =\r\n (\r\n client: SenzorClient,\r\n debug: boolean\r\n ) => {\r\n\r\n hookRequire(\r\n 'bullmq',\r\n (exports: any) => {\r\n\r\n patchWorker(\r\n exports,\r\n client,\r\n debug\r\n );\r\n\r\n if (exports?.default) {\r\n\r\n patchWorker(\r\n exports.default,\r\n client,\r\n debug\r\n );\r\n\r\n }\r\n\r\n }\r\n );\r\n\r\n };","import type { SenzorClient } from '../core/client';\r\nimport { hookRequire } from './hook';\r\n\r\nconst PATCHED =\r\n Symbol.for('senzor.cron.patched');\r\n\r\ntype CronHandler =\r\n (...args: unknown[]) => unknown;\r\n\r\ntype CronSchedule =\r\n (\r\n expression: string,\r\n handler: CronHandler,\r\n options?: unknown\r\n ) => unknown;\r\n\r\nfunction normalizeOptions(\r\n options: unknown\r\n): Record<string, unknown> {\r\n\r\n if (\r\n typeof options === 'object' &&\r\n options !== null\r\n ) {\r\n return options as Record<\r\n string,\r\n unknown\r\n >;\r\n }\r\n\r\n // backward compatibility with:\r\n // cron.schedule(expr, fn, \"UTC\")\r\n if (options) {\r\n return { timezone: options };\r\n }\r\n\r\n return {};\r\n\r\n}\r\n\r\nfunction patchTarget(\r\n target: Record<string, unknown>,\r\n client: SenzorClient,\r\n debug: boolean\r\n): void {\r\n\r\n const schedule =\r\n target.schedule as\r\n CronSchedule | undefined;\r\n\r\n if (\r\n typeof schedule !== 'function' ||\r\n (schedule as any)[PATCHED]\r\n ) {\r\n return;\r\n }\r\n\r\n const original =\r\n schedule;\r\n\r\n const wrapped: CronSchedule =\r\n function (\r\n this: unknown,\r\n expression,\r\n handler,\r\n options\r\n ) {\r\n\r\n if (\r\n typeof handler !==\r\n 'function'\r\n ) {\r\n\r\n return original.call(\r\n this,\r\n expression,\r\n handler,\r\n options\r\n );\r\n\r\n }\r\n\r\n try {\r\n\r\n const opts =\r\n normalizeOptions(\r\n options\r\n );\r\n\r\n const taskName =\r\n (opts as any)?.name ??\r\n `cron: ${expression}`;\r\n\r\n const wrappedHandler =\r\n client.wrapTask(\r\n taskName,\r\n 'cron',\r\n {\r\n expression,\r\n metadata: opts\r\n },\r\n handler\r\n );\r\n\r\n return original.call(\r\n this,\r\n expression,\r\n wrappedHandler,\r\n options\r\n );\r\n\r\n }\r\n catch (err) {\r\n\r\n if (debug) {\r\n\r\n console.error(\r\n '[Senzor] cron wrap failed',\r\n err\r\n );\r\n\r\n }\r\n\r\n return original.call(\r\n this,\r\n expression,\r\n handler,\r\n options\r\n );\r\n\r\n }\r\n\r\n };\r\n\r\n Object.defineProperty(\r\n wrapped,\r\n PATCHED,\r\n {\r\n value: true,\r\n enumerable: false\r\n }\r\n );\r\n\r\n // Some ESM namespace exports are frozen\r\n try {\r\n\r\n target.schedule =\r\n wrapped;\r\n\r\n }\r\n catch {\r\n\r\n if (debug) {\r\n\r\n console.warn(\r\n '[Senzor] unable to patch cron schedule (readonly export)'\r\n );\r\n\r\n }\r\n\r\n }\r\n\r\n if (debug) {\r\n\r\n console.log(\r\n '[Senzor] node-cron instrumented'\r\n );\r\n\r\n }\r\n\r\n}\r\n\r\nexport const instrumentNodeCron =\r\n (\r\n client: SenzorClient,\r\n debug: boolean\r\n ): void => {\r\n\r\n hookRequire(\r\n 'node-cron',\r\n (exports: any) => {\r\n\r\n if (!exports) return;\r\n\r\n patchTarget(\r\n exports,\r\n client,\r\n debug\r\n );\r\n\r\n if (exports.default) {\r\n\r\n patchTarget(\r\n exports.default,\r\n client,\r\n debug\r\n );\r\n\r\n }\r\n\r\n }\r\n );\r\n\r\n };","import { SenzorOptions } from '../core/types';\nimport { Context } from '../core/context';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\nimport { generateTraceparent, parseTraceparent } from '../utils/traceContext';\n\n// ---------------------------------------------------------------------------\n// gRPC Instrumentation\n//\n// Instruments @grpc/grpc-js for both client (unary + streaming) and server\n// (unary + streaming) calls. Follows OTel RPC semantic conventions.\n//\n// Client spans: rpc.system=grpc, rpc.service, rpc.method, rpc.grpc.status_code\n// Server spans: Creates a root trace per incoming RPC call\n// ---------------------------------------------------------------------------\n\n/** gRPC status code to human-readable name (subset for common codes). */\nconst GRPC_STATUS_NAMES: Record<number, string> = {\n 0: 'OK',\n 1: 'CANCELLED',\n 2: 'UNKNOWN',\n 3: 'INVALID_ARGUMENT',\n 4: 'DEADLINE_EXCEEDED',\n 5: 'NOT_FOUND',\n 6: 'ALREADY_EXISTS',\n 7: 'PERMISSION_DENIED',\n 8: 'RESOURCE_EXHAUSTED',\n 9: 'FAILED_PRECONDITION',\n 10: 'ABORTED',\n 11: 'OUT_OF_RANGE',\n 12: 'UNIMPLEMENTED',\n 13: 'INTERNAL',\n 14: 'UNAVAILABLE',\n 15: 'DATA_LOSS',\n 16: 'UNAUTHENTICATED',\n};\n\n/** Map gRPC status code → HTTP-equivalent status for span.status. */\nconst grpcStatusToHttp = (code: number): number => {\n if (code === 0) return 0; // OK\n if (code === 1) return 499; // CANCELLED → Client Closed Request\n if (code === 3 || code === 9 || code === 11) return 400; // INVALID_ARGUMENT, FAILED_PRECONDITION, OUT_OF_RANGE\n if (code === 4) return 504; // DEADLINE_EXCEEDED\n if (code === 5) return 404; // NOT_FOUND\n if (code === 6) return 409; // ALREADY_EXISTS\n if (code === 7) return 403; // PERMISSION_DENIED\n if (code === 8) return 429; // RESOURCE_EXHAUSTED\n if (code === 10) return 409; // ABORTED\n if (code === 12) return 501; // UNIMPLEMENTED\n if (code === 16) return 401; // UNAUTHENTICATED\n return 500; // UNKNOWN, INTERNAL, UNAVAILABLE, DATA_LOSS, etc.\n};\n\n/** Parse a gRPC full method path like /package.ServiceName/MethodName */\nconst parseGrpcMethod = (fullPath: string): { service: string; method: string } => {\n const parts = fullPath.replace(/^\\//, '').split('/');\n return {\n service: parts[0] || 'unknown',\n method: parts[1] || 'unknown',\n };\n};\n\n// ---------------------------------------------------------------------------\n// Metadata propagation helpers\n// ---------------------------------------------------------------------------\n\nconst TRACEPARENT_KEY = 'traceparent';\nconst SENZOR_TRACE_KEY = 'x-senzor-trace-id';\nconst SENZOR_SPAN_KEY = 'x-senzor-parent-span-id';\n\n/** Inject trace context into gRPC metadata (client-side). */\nconst injectMetadata = (metadata: any, traceId: string, spanId: string) => {\n try {\n if (metadata && typeof metadata.set === 'function') {\n metadata.set(TRACEPARENT_KEY, generateTraceparent(traceId, spanId));\n metadata.set(SENZOR_TRACE_KEY, traceId);\n metadata.set(SENZOR_SPAN_KEY, spanId);\n }\n } catch { /* metadata immutable — skip silently */ }\n};\n\n/** Extract trace context from incoming gRPC metadata (server-side). */\nconst extractFromMetadata = (\n metadata: any\n): { traceId?: string; parentSpanId?: string } => {\n try {\n if (!metadata || typeof metadata.get !== 'function') return {};\n\n const traceparent = metadata.get(TRACEPARENT_KEY);\n const tp = Array.isArray(traceparent) ? traceparent[0] : traceparent;\n if (tp) {\n const parsed = parseTraceparent(String(tp));\n if (parsed) return parsed;\n }\n\n const traceId = metadata.get(SENZOR_TRACE_KEY);\n const parentSpanId = metadata.get(SENZOR_SPAN_KEY);\n return {\n traceId: Array.isArray(traceId) ? traceId[0] : traceId || undefined,\n parentSpanId: Array.isArray(parentSpanId) ? parentSpanId[0] : parentSpanId || undefined,\n };\n } catch {\n return {};\n }\n};\n\n// ---------------------------------------------------------------------------\n// Client interceptor\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a gRPC client interceptor that wraps each outbound RPC call in a\n * child span and propagates trace context via metadata.\n */\nconst createClientInterceptor = (options?: SenzorOptions) => {\n return (methodOptions: any, nextCall: any) => {\n const trace = Context.current();\n if (!trace) return nextCall(methodOptions);\n\n const { service, method } = parseGrpcMethod(methodOptions.method_definition?.path || '');\n const fullMethod = methodOptions.method_definition?.path || `/${service}/${method}`;\n\n const span = startCapturedSpan(\n `gRPC ${service}/${method}`,\n 'http',\n {\n 'rpc.system': 'grpc',\n 'rpc.service': service,\n 'rpc.method': method,\n 'rpc.grpc.full_method': fullMethod,\n 'network.transport': 'tcp',\n },\n options\n );\n\n if (!span) return nextCall(methodOptions);\n\n // Clone method options to inject metadata\n const newMethodOptions = { ...methodOptions };\n\n return runWithCapturedSpan(span, () => {\n const interceptingCall = new (getInterceptingCall())(nextCall(newMethodOptions));\n\n // We need a requester that injects metadata on start and captures status on close\n const requester = {\n start: (metadata: any, listener: any, next: (metadata: any, listener: any) => void) => {\n injectMetadata(metadata, trace.id, span.spanId);\n\n const wrappedListener = {\n onReceiveMetadata: (metadata: any, next: (metadata: any) => void) => {\n next(metadata);\n },\n onReceiveMessage: (message: any, next: (message: any) => void) => {\n next(message);\n },\n onReceiveStatus: (status: any, next: (status: any) => void) => {\n const grpcCode = status?.code ?? 0;\n span.end(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n 'rpc.grpc.status_text': GRPC_STATUS_NAMES[grpcCode] || 'UNKNOWN',\n ...(status?.details ? { 'error.message': status.details } : {}),\n });\n next(status);\n },\n };\n\n next(metadata, wrappedListener);\n },\n sendMessage: (message: any, next: (message: any) => void) => {\n next(message);\n },\n halfClose: (next: () => void) => {\n next();\n },\n cancel: (message: string, next: () => void) => {\n span.end(grpcStatusToHttp(1), {\n 'rpc.grpc.status_code': 1,\n 'rpc.grpc.status_text': 'CANCELLED',\n 'error.message': message || 'Call cancelled',\n });\n next();\n },\n };\n\n return interceptingCall;\n });\n };\n};\n\n// Cache the InterceptingCall class\nlet _InterceptingCall: any = null;\nconst getInterceptingCall = (): any => {\n if (_InterceptingCall) return _InterceptingCall;\n try {\n const grpc = require('@grpc/grpc-js');\n _InterceptingCall = grpc.InterceptingCall;\n } catch { }\n return _InterceptingCall;\n};\n\n// ---------------------------------------------------------------------------\n// Client-side patching (simpler approach: patch makeUnaryRequest etc.)\n// ---------------------------------------------------------------------------\n\nconst patchClientMethods = (grpc: any, options?: SenzorOptions) => {\n const clientProto = grpc?.Client?.prototype;\n if (!clientProto) return;\n\n // Patch makeUnaryRequest — the core method all unary stubs resolve to\n patchMethod(\n clientProto,\n 'makeUnaryRequest',\n 'senzor.grpc.client.makeUnaryRequest',\n (original) =>\n function patchedMakeUnaryRequest(this: any, method: string, ...args: any[]) {\n const trace = Context.current();\n if (!trace) return original.call(this, method, ...args);\n\n const { service, method: rpcMethod } = parseGrpcMethod(method);\n\n const span = startCapturedSpan(\n `gRPC ${service}/${rpcMethod}`,\n 'http',\n {\n 'rpc.system': 'grpc',\n 'rpc.service': service,\n 'rpc.method': rpcMethod,\n 'rpc.grpc.full_method': method,\n 'network.transport': 'tcp',\n },\n options\n );\n\n if (!span) return original.call(this, method, ...args);\n\n // args: [serialize, deserialize, argument, metadata, options, callback]\n // Inject trace context into metadata\n let metadataIdx = -1;\n let callbackIdx = -1;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] && typeof args[i] === 'object' && typeof args[i].set === 'function' && typeof args[i].get === 'function') {\n metadataIdx = i;\n }\n if (typeof args[i] === 'function' && i === args.length - 1) {\n callbackIdx = i;\n }\n }\n\n // Inject into metadata if found\n if (metadataIdx >= 0) {\n injectMetadata(args[metadataIdx], trace.id, span.spanId);\n }\n\n // Wrap callback to capture status\n if (callbackIdx >= 0) {\n const originalCallback = args[callbackIdx];\n args[callbackIdx] = function wrappedGrpcCallback(err: any, response: any) {\n if (err) {\n const grpcCode = err.code ?? 2;\n span.end(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n 'rpc.grpc.status_text': GRPC_STATUS_NAMES[grpcCode] || 'UNKNOWN',\n 'error.message': err.details || err.message,\n 'error.type': err.name || 'GrpcError',\n });\n } else {\n span.end(0, {\n 'rpc.grpc.status_code': 0,\n 'rpc.grpc.status_text': 'OK',\n });\n }\n return originalCallback.call(this, err, response);\n };\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const call = original.call(this, method, ...args);\n\n // If no callback was provided, the call returns a ClientUnaryCall\n // which emits 'status' and 'error' events\n if (callbackIdx < 0 && call && typeof call.on === 'function') {\n let ended = false;\n call.on('status', (status: any) => {\n if (ended) return;\n ended = true;\n const grpcCode = status?.code ?? 0;\n span.end(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n 'rpc.grpc.status_text': GRPC_STATUS_NAMES[grpcCode] || 'UNKNOWN',\n });\n });\n call.on('error', (err: any) => {\n if (ended) return;\n ended = true;\n const grpcCode = err?.code ?? 2;\n span.end(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n 'error.message': err?.details || err?.message,\n 'error.type': err?.name || 'GrpcError',\n });\n });\n }\n\n return call;\n } catch (error: any) {\n span.end(500, {\n 'rpc.grpc.status_code': 13,\n 'rpc.grpc.status_text': 'INTERNAL',\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n );\n\n // Patch makeClientStreamRequest\n patchMethod(\n clientProto,\n 'makeClientStreamRequest',\n 'senzor.grpc.client.makeClientStreamRequest',\n (original) =>\n function patchedMakeClientStreamRequest(this: any, method: string, ...args: any[]) {\n const trace = Context.current();\n if (!trace) return original.call(this, method, ...args);\n\n const { service, method: rpcMethod } = parseGrpcMethod(method);\n const span = startCapturedSpan(\n `gRPC ${service}/${rpcMethod} (client-stream)`,\n 'http',\n {\n 'rpc.system': 'grpc',\n 'rpc.service': service,\n 'rpc.method': rpcMethod,\n 'rpc.grpc.full_method': method,\n 'rpc.grpc.call_type': 'client_stream',\n 'network.transport': 'tcp',\n },\n options\n );\n\n if (!span) return original.call(this, method, ...args);\n\n // Inject metadata\n for (let i = 0; i < args.length; i++) {\n if (args[i] && typeof args[i] === 'object' && typeof args[i].set === 'function' && typeof args[i].get === 'function') {\n injectMetadata(args[i], trace.id, span.spanId);\n break;\n }\n }\n\n // Wrap callback\n for (let i = args.length - 1; i >= 0; i--) {\n if (typeof args[i] === 'function') {\n const originalCallback = args[i];\n args[i] = function wrappedCallback(err: any, response: any) {\n if (err) {\n const grpcCode = err.code ?? 2;\n span.end(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n 'error.message': err.details || err.message,\n });\n } else {\n span.end(0, { 'rpc.grpc.status_code': 0 });\n }\n return originalCallback.call(this, err, response);\n };\n break;\n }\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n return original.call(this, method, ...args);\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message, 'error.type': error?.name });\n throw error;\n }\n });\n }\n );\n\n // Patch makeServerStreamRequest\n patchMethod(\n clientProto,\n 'makeServerStreamRequest',\n 'senzor.grpc.client.makeServerStreamRequest',\n (original) =>\n function patchedMakeServerStreamRequest(this: any, method: string, ...args: any[]) {\n const trace = Context.current();\n if (!trace) return original.call(this, method, ...args);\n\n const { service, method: rpcMethod } = parseGrpcMethod(method);\n const span = startCapturedSpan(\n `gRPC ${service}/${rpcMethod} (server-stream)`,\n 'http',\n {\n 'rpc.system': 'grpc',\n 'rpc.service': service,\n 'rpc.method': rpcMethod,\n 'rpc.grpc.full_method': method,\n 'rpc.grpc.call_type': 'server_stream',\n 'network.transport': 'tcp',\n },\n options\n );\n\n if (!span) return original.call(this, method, ...args);\n\n // Inject metadata\n for (let i = 0; i < args.length; i++) {\n if (args[i] && typeof args[i] === 'object' && typeof args[i].set === 'function') {\n injectMetadata(args[i], trace.id, span.spanId);\n break;\n }\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const call = original.call(this, method, ...args);\n\n if (call && typeof call.on === 'function') {\n let ended = false;\n call.on('status', (status: any) => {\n if (ended) return;\n ended = true;\n const grpcCode = status?.code ?? 0;\n span.end(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n 'rpc.grpc.status_text': GRPC_STATUS_NAMES[grpcCode] || 'UNKNOWN',\n });\n });\n call.on('error', (err: any) => {\n if (ended) return;\n ended = true;\n span.end(grpcStatusToHttp(err?.code ?? 2), {\n 'rpc.grpc.status_code': err?.code ?? 2,\n 'error.message': err?.details || err?.message,\n });\n });\n }\n\n return call;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message, 'error.type': error?.name });\n throw error;\n }\n });\n }\n );\n\n // Patch makeBidiStreamRequest\n patchMethod(\n clientProto,\n 'makeBidiStreamRequest',\n 'senzor.grpc.client.makeBidiStreamRequest',\n (original) =>\n function patchedMakeBidiStreamRequest(this: any, method: string, ...args: any[]) {\n const trace = Context.current();\n if (!trace) return original.call(this, method, ...args);\n\n const { service, method: rpcMethod } = parseGrpcMethod(method);\n const span = startCapturedSpan(\n `gRPC ${service}/${rpcMethod} (bidi-stream)`,\n 'http',\n {\n 'rpc.system': 'grpc',\n 'rpc.service': service,\n 'rpc.method': rpcMethod,\n 'rpc.grpc.full_method': method,\n 'rpc.grpc.call_type': 'bidi_stream',\n 'network.transport': 'tcp',\n },\n options\n );\n\n if (!span) return original.call(this, method, ...args);\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] && typeof args[i] === 'object' && typeof args[i].set === 'function') {\n injectMetadata(args[i], trace.id, span.spanId);\n break;\n }\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const call = original.call(this, method, ...args);\n\n if (call && typeof call.on === 'function') {\n let ended = false;\n call.on('status', (status: any) => {\n if (ended) return;\n ended = true;\n const grpcCode = status?.code ?? 0;\n span.end(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n });\n });\n call.on('error', (err: any) => {\n if (ended) return;\n ended = true;\n span.end(grpcStatusToHttp(err?.code ?? 2), {\n 'rpc.grpc.status_code': err?.code ?? 2,\n 'error.message': err?.details || err?.message,\n });\n });\n }\n\n return call;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message, 'error.type': error?.name });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Server-side patching\n// ---------------------------------------------------------------------------\n\nconst patchServerRegister = (grpc: any, client: any, options?: SenzorOptions) => {\n const serverProto = grpc?.Server?.prototype;\n if (!serverProto) return;\n\n patchMethod(\n serverProto,\n 'register',\n 'senzor.grpc.server.register',\n (original) =>\n function patchedRegister(\n this: any,\n name: string,\n handler: any,\n serialize: any,\n deserialize: any,\n type: any\n ) {\n if (typeof handler !== 'function') {\n return original.call(this, name, handler, serialize, deserialize, type);\n }\n\n const wrappedHandler = function (this: any, call: any, callback?: any) {\n const { service, method } = parseGrpcMethod(name);\n const metadata = call?.metadata;\n const parentCtx = extractFromMetadata(metadata);\n\n const span = startCapturedSpan(\n `gRPC ${service}/${method}`,\n 'http',\n {\n 'rpc.system': 'grpc',\n 'rpc.service': service,\n 'rpc.method': method,\n 'rpc.grpc.full_method': name,\n 'rpc.grpc.call_type': type || 'unary',\n 'server.type': 'grpc',\n ...(parentCtx.traceId ? { 'parent.trace_id': parentCtx.traceId } : {}),\n },\n options\n );\n\n if (!span) {\n return handler.call(this, call, callback);\n }\n\n // Wrap callback for unary/client-streaming handlers\n if (typeof callback === 'function') {\n const wrappedCallback = function (err: any, response: any, trailer?: any, flags?: any) {\n if (err) {\n const grpcCode = err.code ?? 2;\n span.end(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n 'rpc.grpc.status_text': GRPC_STATUS_NAMES[grpcCode] || 'UNKNOWN',\n 'error.message': err.details || err.message,\n 'error.type': err.name || 'GrpcError',\n });\n } else {\n span.end(0, {\n 'rpc.grpc.status_code': 0,\n 'rpc.grpc.status_text': 'OK',\n });\n }\n return callback(err, response, trailer, flags);\n };\n\n return runWithCapturedSpan(span, () => {\n try {\n return handler.call(this, call, wrappedCallback);\n } catch (error: any) {\n span.end(500, {\n 'rpc.grpc.status_code': 13,\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n\n // Server-streaming / bidi-streaming: listen to call events\n return runWithCapturedSpan(span, () => {\n try {\n const result = handler.call(this, call);\n\n if (call && typeof call.on === 'function') {\n let ended = false;\n const endOnce = (status: number, meta: Record<string, any>) => {\n if (ended) return;\n ended = true;\n span.end(status, meta);\n };\n\n call.on('error', (err: any) => {\n const grpcCode = err?.code ?? 2;\n endOnce(grpcStatusToHttp(grpcCode), {\n 'rpc.grpc.status_code': grpcCode,\n 'error.message': err?.details || err?.message,\n });\n });\n\n call.on('end', () => {\n endOnce(0, { 'rpc.grpc.status_code': 0 });\n });\n\n call.on('cancelled', () => {\n endOnce(grpcStatusToHttp(1), {\n 'rpc.grpc.status_code': 1,\n 'rpc.grpc.status_text': 'CANCELLED',\n });\n });\n }\n\n return result;\n } catch (error: any) {\n span.end(500, {\n 'rpc.grpc.status_code': 13,\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n };\n\n return original.call(this, name, wrappedHandler, serialize, deserialize, type);\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentGrpc = (client: any, options?: SenzorOptions) => {\n hookRequire('@grpc/grpc-js', (exports: any) => {\n patchClientMethods(exports, options);\n patchServerRegister(exports, client, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// GraphQL Instrumentation\n//\n// Instruments the `graphql` package at the execution layer, covering:\n// - graphql() — top-level convenience function\n// - execute() — execution engine\n// - parse() — query parsing\n// - validate() — schema validation\n//\n// Follows OTel semantic conventions: graphql.operation.name,\n// graphql.operation.type, graphql.document, graphql.source\n// ---------------------------------------------------------------------------\n\n/** Maximum length of captured GraphQL document to avoid oversized spans. */\nconst MAX_DOCUMENT_LENGTH = 4096;\n\n/** Safely truncate a GraphQL source document. */\nconst truncateDocument = (source: string): string => {\n if (!source || typeof source !== 'string') return '';\n if (source.length <= MAX_DOCUMENT_LENGTH) return source;\n return source.slice(0, MAX_DOCUMENT_LENGTH) + '...[truncated]';\n};\n\n/**\n * Extract operation metadata (name, type) from a parsed DocumentNode.\n *\n * Handles queries with multiple operation definitions by finding the one\n * matching `operationName`, or falling back to the first definition.\n */\nconst extractOperationInfo = (\n document: any,\n operationName?: string | null\n): { operationType: string; name: string } => {\n const defaultResult = { operationType: 'query', name: operationName || 'anonymous' };\n\n if (!document || !document.definitions || !Array.isArray(document.definitions)) {\n return defaultResult;\n }\n\n // Filter to operation definitions\n const operationDefs = document.definitions.filter(\n (def: any) => def.kind === 'OperationDefinition'\n );\n\n if (operationDefs.length === 0) return defaultResult;\n\n // Find the matching operation\n let target = operationDefs[0];\n if (operationName) {\n const named = operationDefs.find(\n (def: any) => def.name?.value === operationName\n );\n if (named) target = named;\n }\n\n return {\n operationType: target.operation || 'query',\n name: target.name?.value || operationName || 'anonymous',\n };\n};\n\n/**\n * Extract the source text from a DocumentNode or Source object.\n */\nconst getSourceText = (document: any): string => {\n if (!document) return '';\n if (typeof document === 'string') return document;\n if (document.loc?.source?.body) return document.loc.source.body;\n if (document.source?.body) return document.source.body;\n return '';\n};\n\n/**\n * Check if GraphQL result contains errors.\n */\nconst hasErrors = (result: any): boolean => {\n return result && Array.isArray(result.errors) && result.errors.length > 0;\n};\n\n/**\n * Extract error summary from GraphQL errors array.\n */\nconst extractErrorSummary = (errors: any[]): string => {\n if (!errors || errors.length === 0) return '';\n const messages = errors\n .slice(0, 5) // Limit to first 5 errors\n .map((e: any) => e.message || String(e))\n .join('; ');\n return messages.length > 1024 ? messages.slice(0, 1024) + '...' : messages;\n};\n\n// ---------------------------------------------------------------------------\n// Patching\n// ---------------------------------------------------------------------------\n\nconst patchGraphQL = (graphql: any, options?: SenzorOptions) => {\n if (!graphql) return;\n\n // Patch the top-level graphql() convenience function\n patchMethod(\n graphql,\n 'graphql',\n 'senzor.graphql.graphql',\n (original) =>\n function patchedGraphqlFn(this: any, ...args: any[]) {\n // graphql(schema, source, rootValue, contextValue, variableValues, operationName)\n // or graphql({ schema, source, rootValue, ... })\n let source: string | undefined;\n let operationName: string | undefined;\n let document: any;\n\n if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null) {\n // Object form\n source = args[0].source;\n operationName = args[0].operationName;\n } else {\n source = args[1];\n operationName = args[5];\n }\n\n const span = startCapturedSpan(\n `GraphQL ${operationName || 'query'}`,\n 'custom',\n {\n 'graphql.operation.name': operationName || 'anonymous',\n 'graphql.source': source ? truncateDocument(source) : undefined,\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (res: any) => {\n if (hasErrors(res)) {\n span.end(500, {\n 'graphql.error_count': res.errors.length,\n 'error.message': extractErrorSummary(res.errors),\n });\n } else {\n span.end(0);\n }\n return res;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'GraphQLError',\n });\n throw error;\n }\n );\n }\n\n if (hasErrors(result)) {\n span.end(500, {\n 'graphql.error_count': result.errors.length,\n 'error.message': extractErrorSummary(result.errors),\n });\n } else {\n span.end(0);\n }\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n );\n\n // Patch execute()\n patchMethod(\n graphql,\n 'execute',\n 'senzor.graphql.execute',\n (original) =>\n function patchedExecute(this: any, ...args: any[]) {\n // execute(schema, document, rootValue, contextValue, variableValues, operationName)\n // or execute({ schema, document, ... })\n let document: any;\n let operationName: string | undefined;\n\n if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null && !Array.isArray(args[0])) {\n document = args[0].document;\n operationName = args[0].operationName;\n } else {\n document = args[1];\n operationName = args[5];\n }\n\n const opInfo = extractOperationInfo(document, operationName);\n const sourceText = getSourceText(document);\n\n const span = startCapturedSpan(\n `GraphQL execute ${opInfo.operationType} ${opInfo.name}`,\n 'custom',\n {\n 'graphql.operation.name': opInfo.name,\n 'graphql.operation.type': opInfo.operationType,\n 'graphql.document': truncateDocument(sourceText),\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (res: any) => {\n if (hasErrors(res)) {\n span.end(500, {\n 'graphql.error_count': res.errors.length,\n 'error.message': extractErrorSummary(res.errors),\n });\n } else {\n span.end(0);\n }\n return res;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'GraphQLError',\n });\n throw error;\n }\n );\n }\n\n if (hasErrors(result)) {\n span.end(500, {\n 'graphql.error_count': result.errors.length,\n 'error.message': extractErrorSummary(result.errors),\n });\n } else {\n span.end(0);\n }\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n );\n\n // Patch parse()\n patchMethod(\n graphql,\n 'parse',\n 'senzor.graphql.parse',\n (original) =>\n function patchedParse(this: any, source: any, ...args: any[]) {\n const sourceText = typeof source === 'string'\n ? source\n : source?.body || '';\n\n const span = startCapturedSpan(\n 'GraphQL parse',\n 'custom',\n {\n 'graphql.operation': 'parse',\n 'graphql.source': truncateDocument(sourceText),\n },\n options\n );\n\n if (!span) return original.call(this, source, ...args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, source, ...args);\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'GraphQLError',\n 'graphql.error_count': 1,\n });\n throw error;\n }\n });\n }\n );\n\n // Patch validate()\n patchMethod(\n graphql,\n 'validate',\n 'senzor.graphql.validate',\n (original) =>\n function patchedValidate(this: any, schema: any, documentAST: any, ...args: any[]) {\n const span = startCapturedSpan(\n 'GraphQL validate',\n 'custom',\n {\n 'graphql.operation': 'validate',\n },\n options\n );\n\n if (!span) return original.call(this, schema, documentAST, ...args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const errors = original.call(this, schema, documentAST, ...args);\n\n if (Array.isArray(errors) && errors.length > 0) {\n span.end(500, {\n 'graphql.error_count': errors.length,\n 'error.message': extractErrorSummary(errors),\n });\n } else {\n span.end(0);\n }\n\n return errors;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentGraphQL = (options?: SenzorOptions) => {\n hookRequire('graphql', (exports: any) => patchGraphQL(exports, options));\n\n // Also try graphql/execution for cases where execute is imported directly\n hookRequire('graphql/execution', (exports: any) => {\n if (exports?.execute) {\n patchMethod(\n exports,\n 'execute',\n 'senzor.graphql.execution.execute',\n (original) => {\n // Reuse the same logic\n return function patchedDirectExecute(this: any, ...args: any[]) {\n let document: any;\n let operationName: string | undefined;\n\n if (args.length === 1 && typeof args[0] === 'object' && args[0] !== null) {\n document = args[0].document;\n operationName = args[0].operationName;\n } else {\n document = args[1];\n operationName = args[5];\n }\n\n const opInfo = extractOperationInfo(document, operationName);\n const sourceText = getSourceText(document);\n\n const span = startCapturedSpan(\n `GraphQL execute ${opInfo.operationType} ${opInfo.name}`,\n 'custom',\n {\n 'graphql.operation.name': opInfo.name,\n 'graphql.operation.type': opInfo.operationType,\n 'graphql.document': truncateDocument(sourceText),\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (res: any) => {\n if (hasErrors(res)) {\n span.end(500, {\n 'graphql.error_count': res.errors.length,\n 'error.message': extractErrorSummary(res.errors),\n });\n } else {\n span.end(0);\n }\n return res;\n },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n if (hasErrors(result)) {\n span.end(500, { 'graphql.error_count': result.errors.length });\n } else {\n span.end(0);\n }\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n };\n }\n );\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// DNS Instrumentation\n//\n// Instruments Node.js core `dns` module:\n// - dns.lookup() — resolves a hostname to an address (uses OS resolver)\n// - dns.resolve() — resolves using DNS protocol (network call)\n// - dns.resolve4() — A records\n// - dns.resolve6() — AAAA records\n// - dns.resolveMx() — MX records\n// - dns.resolveTxt() — TXT records\n// - dns.resolveSrv() — SRV records\n// - dns.resolveCname() — CNAME records\n// - dns.resolveNs() — NS records\n// - dns.reverse() — reverse DNS lookup\n//\n// Follows OTel semantic conventions: dns.hostname, network.peer.address\n// ---------------------------------------------------------------------------\n\n/**\n * Patch a single DNS method that accepts (hostname, [options], callback).\n */\nconst patchDnsMethod = (\n dnsModule: any,\n methodName: string,\n options?: SenzorOptions\n) => {\n patchMethod(\n dnsModule,\n methodName,\n `senzor.dns.${methodName}`,\n (original) =>\n function patchedDnsMethod(this: any, ...args: any[]) {\n // Extract hostname (always the first argument)\n const hostname = typeof args[0] === 'string' ? args[0] : 'unknown';\n\n const span = startCapturedSpan(\n `DNS ${methodName}`,\n 'custom',\n {\n 'dns.hostname': hostname,\n 'dns.operation': methodName,\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n // Find and wrap the callback (always the last argument)\n const callbackIdx = args.findIndex(\n (arg: any, idx: number) => typeof arg === 'function' && idx === args.length - 1\n );\n\n if (callbackIdx >= 0) {\n const originalCallback = args[callbackIdx];\n args[callbackIdx] = function wrappedDnsCallback(\n err: NodeJS.ErrnoException | null,\n ...results: any[]\n ) {\n if (err) {\n span.end(500, {\n 'error.message': err.message,\n 'error.type': err.code || err.name || 'DnsError',\n 'dns.error_code': err.code,\n });\n } else {\n // For lookup, first result is address, second is family\n const meta: Record<string, any> = {};\n if (methodName === 'lookup' && results[0]) {\n meta['network.peer.address'] = results[0];\n meta['dns.address_family'] = results[1] === 6 ? 'IPv6' : 'IPv4';\n } else if (methodName === 'resolve4' || methodName === 'resolve6') {\n meta['dns.result_count'] = Array.isArray(results[0]) ? results[0].length : 0;\n } else if (methodName === 'resolve') {\n meta['dns.result_count'] = Array.isArray(results[0]) ? results[0].length : 0;\n }\n span.end(0, meta);\n }\n return originalCallback.call(this, err, ...results);\n };\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n return original.apply(this, args);\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n );\n};\n\n/**\n * Patch dns.promises methods (returns promises instead of using callbacks).\n */\nconst patchDnsPromisesMethod = (\n promises: any,\n methodName: string,\n options?: SenzorOptions\n) => {\n patchMethod(\n promises,\n methodName,\n `senzor.dns.promises.${methodName}`,\n (original) =>\n function patchedDnsPromiseMethod(this: any, ...args: any[]) {\n const hostname = typeof args[0] === 'string' ? args[0] : 'unknown';\n\n const span = startCapturedSpan(\n `DNS ${methodName}`,\n 'custom',\n {\n 'dns.hostname': hostname,\n 'dns.operation': methodName,\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, async () => {\n try {\n const result = await original.apply(this, args);\n\n const meta: Record<string, any> = {};\n if (methodName === 'lookup' && result) {\n meta['network.peer.address'] = result.address;\n meta['dns.address_family'] = result.family === 6 ? 'IPv6' : 'IPv4';\n } else if (Array.isArray(result)) {\n meta['dns.result_count'] = result.length;\n }\n\n span.end(0, meta);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.code || error?.name || 'DnsError',\n 'dns.error_code': error?.code,\n });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentDns = (options?: SenzorOptions) => {\n let dns: any;\n try {\n dns = require('dns');\n } catch {\n return;\n }\n\n if (!dns) return;\n\n // Callback-based methods\n const callbackMethods = [\n 'lookup',\n 'resolve',\n 'resolve4',\n 'resolve6',\n 'resolveMx',\n 'resolveTxt',\n 'resolveSrv',\n 'resolveCname',\n 'resolveNs',\n 'resolvePtr',\n 'resolveSoa',\n 'resolveNaptr',\n 'resolveCaa',\n 'reverse',\n ];\n\n for (const method of callbackMethods) {\n if (typeof dns[method] === 'function') {\n patchDnsMethod(dns, method, options);\n }\n }\n\n // Promise-based methods (dns.promises / dns/promises)\n const promises = dns.promises;\n if (promises) {\n const promiseMethods = [\n 'lookup',\n 'resolve',\n 'resolve4',\n 'resolve6',\n 'resolveMx',\n 'resolveTxt',\n 'resolveSrv',\n 'resolveCname',\n 'resolveNs',\n 'resolvePtr',\n 'resolveSoa',\n 'resolveNaptr',\n 'resolveCaa',\n 'reverse',\n ];\n\n for (const method of promiseMethods) {\n if (typeof promises[method] === 'function') {\n patchDnsPromisesMethod(promises, method, options);\n }\n }\n }\n};\n","import { SenzorOptions } from '../core/types';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Net (TCP) Instrumentation\n//\n// Instruments Node.js core `net` module:\n// - net.connect() / net.createConnection() — TCP connection spans\n// - net.Socket.prototype.connect() — socket-level connection\n//\n// Captures TCP connection establishment latency and peer information.\n// Follows OTel semantic conventions: net.peer.name, net.peer.port, net.transport\n//\n// NOTE: This instrumentation only captures connection establishment, not\n// data transfer. This prevents excessive span noise while still providing\n// visibility into network bottlenecks (slow connects, timeouts, refused).\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize connection options from the various net.connect() signatures:\n * - connect(port, host, cb)\n * - connect({ port, host }, cb)\n * - connect(path, cb) — IPC / Unix domain socket\n * - connect({ path }, cb) — IPC / Unix domain socket\n */\nconst normalizeConnectArgs = (\n args: any[]\n): { host: string; port: number | string; isIPC: boolean } => {\n const first = args[0];\n\n // Object form: { port, host } or { path }\n if (typeof first === 'object' && first !== null && !Array.isArray(first)) {\n if (first.path) {\n return { host: first.path, port: 'ipc', isIPC: true };\n }\n return {\n host: first.host || 'localhost',\n port: first.port || 0,\n isIPC: false,\n };\n }\n\n // String form: path (IPC)\n if (typeof first === 'string' && !Number.isFinite(Number(first))) {\n return { host: first, port: 'ipc', isIPC: true };\n }\n\n // Numeric form: port, [host]\n const port = Number(first) || 0;\n const host = typeof args[1] === 'string' ? args[1] : 'localhost';\n return { host, port, isIPC: false };\n};\n\n// ---------------------------------------------------------------------------\n// Patching\n// ---------------------------------------------------------------------------\n\nconst patchSocketConnect = (netModule: any, options?: SenzorOptions) => {\n const socketProto = netModule?.Socket?.prototype;\n if (!socketProto) return;\n\n patchMethod(\n socketProto,\n 'connect',\n 'senzor.net.socket.connect',\n (original) =>\n function patchedSocketConnect(this: any, ...args: any[]) {\n const { host, port, isIPC } = normalizeConnectArgs(args);\n\n const spanName = isIPC\n ? `TCP connect ${host}`\n : `TCP connect ${host}:${port}`;\n\n const span = startCapturedSpan(\n spanName,\n 'custom',\n {\n 'net.peer.name': host,\n 'net.peer.port': isIPC ? undefined : port,\n 'net.transport': isIPC ? 'unix' : 'tcp',\n 'network.transport': isIPC ? 'unix' : 'tcp',\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n const socket = original.apply(this, args);\n\n let ended = false;\n const endOnce = (status: number, meta: Record<string, any> = {}) => {\n if (ended) return;\n ended = true;\n span.end(status, meta);\n };\n\n // Connection established successfully\n socket.once('connect', () => {\n endOnce(0, {\n 'net.peer.address': socket.remoteAddress,\n 'net.peer.port': socket.remotePort,\n 'net.local.address': socket.localAddress,\n 'net.local.port': socket.localPort,\n });\n });\n\n // Connection failed\n socket.once('error', (err: any) => {\n endOnce(500, {\n 'error.message': err?.message,\n 'error.type': err?.code || err?.name || 'NetError',\n 'net.error_code': err?.code,\n });\n });\n\n // Connection timed out\n socket.once('timeout', () => {\n endOnce(504, {\n 'error.message': 'Connection timed out',\n 'error.type': 'TimeoutError',\n });\n });\n\n // Connection closed before establishing\n socket.once('close', (hadError: boolean) => {\n if (hadError) {\n endOnce(500, {\n 'error.message': 'Connection closed with error',\n });\n } else {\n endOnce(0);\n }\n });\n\n return socket;\n });\n }\n );\n};\n\n/**\n * Patch net.connect() and net.createConnection() factory functions.\n * These create a new Socket and immediately call socket.connect().\n * Since we patch Socket.prototype.connect, these are automatically covered.\n * However, we add a thin wrapper for consistency in span naming.\n */\nconst patchNetFactories = (netModule: any, options?: SenzorOptions) => {\n // net.connect and net.createConnection are usually the same function\n // Since we patch Socket.prototype.connect, the factory functions are\n // automatically instrumented. No additional patching needed.\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentNet = (options?: SenzorOptions) => {\n let net: any;\n try {\n net = require('net');\n } catch {\n return;\n }\n\n if (!net) return;\n\n patchSocketConnect(net, options);\n patchNetFactories(net, options);\n};\n","import { Context } from '../core/context';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\nimport { generateTraceparent, parseTraceparent } from '../utils/traceContext';\n\n// ---------------------------------------------------------------------------\n// Kafka (kafkajs) Instrumentation\n//\n// Instruments the kafkajs library:\n// - Producer: send(), sendBatch() — outbound publish spans\n// - Consumer: run() — wraps eachMessage/eachBatch callbacks with spans\n// - Context propagation via message headers (traceparent, x-senzor-*)\n//\n// Follows OTel messaging semantic conventions:\n// messaging.system = kafka\n// messaging.destination.name = topic\n// messaging.operation.name = publish | receive\n// messaging.kafka.consumer.group\n// messaging.kafka.message.offset\n// messaging.batch.message_count\n// ---------------------------------------------------------------------------\n\nconst TRACEPARENT_KEY = 'traceparent';\nconst SENZOR_TRACE_KEY = 'x-senzor-trace-id';\nconst SENZOR_SPAN_KEY = 'x-senzor-parent-span-id';\n\n/** Inject trace context into Kafka message headers. */\nconst injectHeaders = (\n headers: Record<string, any> | undefined,\n traceId: string,\n spanId: string\n): Record<string, any> => {\n const h = headers ? { ...headers } : {};\n h[TRACEPARENT_KEY] = Buffer.from(generateTraceparent(traceId, spanId));\n h[SENZOR_TRACE_KEY] = Buffer.from(traceId);\n h[SENZOR_SPAN_KEY] = Buffer.from(spanId);\n return h;\n};\n\n/** Extract trace context from incoming Kafka message headers. */\nconst extractHeaders = (\n headers: Record<string, any> | undefined\n): { traceId?: string; parentSpanId?: string } => {\n if (!headers) return {};\n\n try {\n const tp = headers[TRACEPARENT_KEY];\n if (tp) {\n const tpStr = Buffer.isBuffer(tp) ? tp.toString() : String(tp);\n const parsed = parseTraceparent(tpStr);\n if (parsed) return parsed;\n }\n\n const traceId = headers[SENZOR_TRACE_KEY];\n const spanId = headers[SENZOR_SPAN_KEY];\n return {\n traceId: traceId ? (Buffer.isBuffer(traceId) ? traceId.toString() : String(traceId)) : undefined,\n parentSpanId: spanId ? (Buffer.isBuffer(spanId) ? spanId.toString() : String(spanId)) : undefined,\n };\n } catch {\n return {};\n }\n};\n\n// ---------------------------------------------------------------------------\n// Producer patching\n// ---------------------------------------------------------------------------\n\nconst patchProducer = (producer: any, options?: SenzorOptions) => {\n // send({ topic, messages, ... })\n patchMethod(\n producer,\n 'send',\n 'senzor.kafka.producer.send',\n (original) =>\n function patchedSend(this: any, payload: any) {\n const trace = Context.current();\n if (!trace) return original.call(this, payload);\n\n const topic = payload?.topic || 'unknown';\n const messageCount = payload?.messages?.length || 0;\n\n const span = startCapturedSpan(\n `Kafka publish ${topic}`,\n 'messaging',\n {\n 'messaging.system': 'kafka',\n 'messaging.destination.name': topic,\n 'messaging.operation.name': 'publish',\n 'messaging.batch.message_count': messageCount,\n },\n options\n );\n\n if (!span) return original.call(this, payload);\n\n // Inject trace context into each message's headers\n if (payload?.messages && Array.isArray(payload.messages)) {\n payload = {\n ...payload,\n messages: payload.messages.map((msg: any) => ({\n ...msg,\n headers: injectHeaders(msg.headers, trace.id, span.spanId),\n })),\n };\n }\n\n return runWithCapturedSpan(span, () => {\n const result = original.call(this, payload);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (res: any) => {\n span.end(0, {\n 'messaging.kafka.partitions': Array.isArray(res)\n ? res.map((r: any) => r.partition).join(',')\n : undefined,\n });\n return res;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'KafkaError',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n });\n }\n );\n\n // sendBatch({ topicMessages: [{ topic, messages }], ... })\n patchMethod(\n producer,\n 'sendBatch',\n 'senzor.kafka.producer.sendBatch',\n (original) =>\n function patchedSendBatch(this: any, payload: any) {\n const trace = Context.current();\n if (!trace) return original.call(this, payload);\n\n const topicMessages = payload?.topicMessages || [];\n const topics = topicMessages.map((tm: any) => tm.topic).join(',');\n const totalMessages = topicMessages.reduce(\n (sum: number, tm: any) => sum + (tm.messages?.length || 0),\n 0\n );\n\n const span = startCapturedSpan(\n `Kafka publishBatch ${topics}`,\n 'messaging',\n {\n 'messaging.system': 'kafka',\n 'messaging.destination.name': topics,\n 'messaging.operation.name': 'publish',\n 'messaging.batch.message_count': totalMessages,\n 'messaging.kafka.batch_topic_count': topicMessages.length,\n },\n options\n );\n\n if (!span) return original.call(this, payload);\n\n // Inject trace context into all messages\n if (topicMessages.length > 0) {\n payload = {\n ...payload,\n topicMessages: topicMessages.map((tm: any) => ({\n ...tm,\n messages: (tm.messages || []).map((msg: any) => ({\n ...msg,\n headers: injectHeaders(msg.headers, trace.id, span.spanId),\n })),\n })),\n };\n }\n\n return runWithCapturedSpan(span, () => {\n const result = original.call(this, payload);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (res: any) => {\n span.end(0);\n return res;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'KafkaError',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Consumer patching\n// ---------------------------------------------------------------------------\n\nconst patchConsumer = (consumer: any, options?: SenzorOptions) => {\n patchMethod(\n consumer,\n 'run',\n 'senzor.kafka.consumer.run',\n (original) =>\n function patchedRun(this: any, config: any) {\n if (!config) return original.call(this, config);\n\n const wrappedConfig = { ...config };\n\n // Wrap eachMessage\n if (typeof config.eachMessage === 'function') {\n const originalHandler = config.eachMessage;\n wrappedConfig.eachMessage = async (payload: any) => {\n const { topic, partition, message } = payload;\n const parentCtx = extractHeaders(message?.headers);\n\n const span = startCapturedSpan(\n `Kafka receive ${topic}`,\n 'messaging',\n {\n 'messaging.system': 'kafka',\n 'messaging.destination.name': topic,\n 'messaging.operation.name': 'receive',\n 'messaging.kafka.partition': partition,\n 'messaging.kafka.message.offset': message?.offset,\n 'messaging.kafka.message.key': message?.key?.toString(),\n ...(parentCtx.traceId ? { 'messaging.parent_trace_id': parentCtx.traceId } : {}),\n },\n options\n );\n\n if (!span) return originalHandler(payload);\n\n return runWithCapturedSpan(span, async () => {\n try {\n const result = await originalHandler(payload);\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n };\n }\n\n // Wrap eachBatch\n if (typeof config.eachBatch === 'function') {\n const originalBatchHandler = config.eachBatch;\n wrappedConfig.eachBatch = async (payload: any) => {\n const { batch } = payload;\n const topic = batch?.topic || 'unknown';\n const messageCount = batch?.messages?.length || 0;\n\n const span = startCapturedSpan(\n `Kafka receiveBatch ${topic}`,\n 'messaging',\n {\n 'messaging.system': 'kafka',\n 'messaging.destination.name': topic,\n 'messaging.operation.name': 'receive',\n 'messaging.kafka.partition': batch?.partition,\n 'messaging.batch.message_count': messageCount,\n 'messaging.kafka.first_offset': batch?.messages?.[0]?.offset,\n 'messaging.kafka.last_offset': batch?.messages?.[messageCount - 1]?.offset,\n },\n options\n );\n\n if (!span) return originalBatchHandler(payload);\n\n return runWithCapturedSpan(span, async () => {\n try {\n const result = await originalBatchHandler(payload);\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n };\n }\n\n return original.call(this, wrappedConfig);\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Kafka class patching (wraps factory methods)\n// ---------------------------------------------------------------------------\n\nconst patchKafkaClass = (kafkaModule: any, options?: SenzorOptions) => {\n const KafkaClass = kafkaModule?.Kafka;\n if (!KafkaClass?.prototype) return;\n\n // Wrap producer() factory\n patchMethod(\n KafkaClass.prototype,\n 'producer',\n 'senzor.kafka.producer',\n (original) =>\n function patchedProducerFactory(this: any, ...args: any[]) {\n const producer = original.apply(this, args);\n if (producer) patchProducer(producer, options);\n return producer;\n }\n );\n\n // Wrap consumer() factory\n patchMethod(\n KafkaClass.prototype,\n 'consumer',\n 'senzor.kafka.consumer',\n (original) =>\n function patchedConsumerFactory(this: any, ...args: any[]) {\n const consumer = original.apply(this, args);\n if (consumer) patchConsumer(consumer, options);\n return consumer;\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentKafka = (options?: SenzorOptions) => {\n hookRequire('kafkajs', (exports: any) => {\n patchKafkaClass(exports, options);\n\n // Also handle default export\n if (exports?.default?.Kafka) {\n patchKafkaClass(exports.default, options);\n }\n });\n};\n","import { Context } from '../core/context';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\nimport { generateTraceparent, parseTraceparent } from '../utils/traceContext';\n\n// ---------------------------------------------------------------------------\n// RabbitMQ (amqplib) Instrumentation\n//\n// Instruments the amqplib library:\n// - Channel.publish() — outbound publish spans\n// - Channel.sendToQueue() — outbound send spans (shorthand for publish)\n// - Channel.consume() — wraps consumer callback with receive spans\n//\n// Context propagation via message headers (msg.properties.headers).\n//\n// ConfirmChannel inherits from Channel, so patches propagate automatically.\n//\n// Follows OTel messaging semantic conventions:\n// messaging.system = rabbitmq\n// messaging.destination.name = exchange or queue\n// messaging.operation.name = publish | receive\n// messaging.rabbitmq.routing_key\n// messaging.rabbitmq.delivery_tag\n// ---------------------------------------------------------------------------\n\nconst TRACEPARENT_KEY = 'traceparent';\nconst SENZOR_TRACE_KEY = 'x-senzor-trace-id';\nconst SENZOR_SPAN_KEY = 'x-senzor-parent-span-id';\n\n/** Inject trace context into AMQP message headers. */\nconst injectHeaders = (\n options: any,\n traceId: string,\n spanId: string\n): any => {\n const opts = options ? { ...options } : {};\n const headers = opts.headers ? { ...opts.headers } : {};\n headers[TRACEPARENT_KEY] = generateTraceparent(traceId, spanId);\n headers[SENZOR_TRACE_KEY] = traceId;\n headers[SENZOR_SPAN_KEY] = spanId;\n opts.headers = headers;\n return opts;\n};\n\n/** Extract trace context from incoming AMQP message properties. */\nconst extractHeaders = (\n msg: any\n): { traceId?: string; parentSpanId?: string } => {\n const headers = msg?.properties?.headers;\n if (!headers) return {};\n\n try {\n const tp = headers[TRACEPARENT_KEY];\n if (tp) {\n const tpStr = Buffer.isBuffer(tp) ? tp.toString() : String(tp);\n const parsed = parseTraceparent(tpStr);\n if (parsed) return parsed;\n }\n\n const traceId = headers[SENZOR_TRACE_KEY];\n const spanId = headers[SENZOR_SPAN_KEY];\n return {\n traceId: traceId ? (Buffer.isBuffer(traceId) ? traceId.toString() : String(traceId)) : undefined,\n parentSpanId: spanId ? (Buffer.isBuffer(spanId) ? spanId.toString() : String(spanId)) : undefined,\n };\n } catch {\n return {};\n }\n};\n\n// ---------------------------------------------------------------------------\n// Channel patching\n// ---------------------------------------------------------------------------\n\nconst patchChannel = (channelProto: any, options?: SenzorOptions) => {\n if (!channelProto) return;\n\n // --- publish(exchange, routingKey, content, options?) ---\n patchMethod(\n channelProto,\n 'publish',\n 'senzor.amqplib.channel.publish',\n (original) =>\n function patchedPublish(\n this: any,\n exchange: string,\n routingKey: string,\n content: Buffer,\n publishOptions?: any\n ) {\n const trace = Context.current();\n if (!trace) return original.call(this, exchange, routingKey, content, publishOptions);\n\n const destination = exchange || routingKey || 'default';\n\n const span = startCapturedSpan(\n `RabbitMQ publish ${destination}`,\n 'messaging',\n {\n 'messaging.system': 'rabbitmq',\n 'messaging.destination.name': destination,\n 'messaging.operation.name': 'publish',\n 'messaging.rabbitmq.exchange': exchange || '(default)',\n 'messaging.rabbitmq.routing_key': routingKey,\n 'messaging.message.body_size': content?.length || 0,\n },\n options\n );\n\n if (!span) return original.call(this, exchange, routingKey, content, publishOptions);\n\n // Inject trace context into headers\n const enrichedOptions = injectHeaders(publishOptions, trace.id, span.spanId);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, exchange, routingKey, content, enrichedOptions);\n\n // publish returns boolean (backpressure signal), not a promise\n span.end(0, {\n 'messaging.rabbitmq.backpressure': result === false,\n });\n\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'AmqpError',\n });\n throw error;\n }\n });\n }\n );\n\n // --- sendToQueue(queue, content, options?) ---\n patchMethod(\n channelProto,\n 'sendToQueue',\n 'senzor.amqplib.channel.sendToQueue',\n (original) =>\n function patchedSendToQueue(\n this: any,\n queue: string,\n content: Buffer,\n sendOptions?: any\n ) {\n const trace = Context.current();\n if (!trace) return original.call(this, queue, content, sendOptions);\n\n const span = startCapturedSpan(\n `RabbitMQ send ${queue}`,\n 'messaging',\n {\n 'messaging.system': 'rabbitmq',\n 'messaging.destination.name': queue,\n 'messaging.operation.name': 'publish',\n 'messaging.rabbitmq.routing_key': queue,\n 'messaging.message.body_size': content?.length || 0,\n },\n options\n );\n\n if (!span) return original.call(this, queue, content, sendOptions);\n\n const enrichedOptions = injectHeaders(sendOptions, trace.id, span.spanId);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, queue, content, enrichedOptions);\n span.end(0, {\n 'messaging.rabbitmq.backpressure': result === false,\n });\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'AmqpError',\n });\n throw error;\n }\n });\n }\n );\n\n // --- consume(queue, callback, options?) ---\n patchMethod(\n channelProto,\n 'consume',\n 'senzor.amqplib.channel.consume',\n (original) =>\n function patchedConsume(\n this: any,\n queue: string,\n callback: (msg: any) => void,\n consumeOptions?: any\n ) {\n if (typeof callback !== 'function') {\n return original.call(this, queue, callback, consumeOptions);\n }\n\n const wrappedCallback = function (msg: any) {\n // Null msg means consumer was cancelled\n if (!msg) return callback(msg);\n\n const parentCtx = extractHeaders(msg);\n const exchange = msg.fields?.exchange || '';\n const routingKey = msg.fields?.routingKey || queue;\n const destination = exchange || routingKey || queue;\n\n const span = startCapturedSpan(\n `RabbitMQ receive ${destination}`,\n 'messaging',\n {\n 'messaging.system': 'rabbitmq',\n 'messaging.destination.name': destination,\n 'messaging.operation.name': 'receive',\n 'messaging.rabbitmq.exchange': exchange || '(default)',\n 'messaging.rabbitmq.routing_key': routingKey,\n 'messaging.rabbitmq.delivery_tag': msg.fields?.deliveryTag,\n 'messaging.rabbitmq.redelivered': msg.fields?.redelivered,\n 'messaging.rabbitmq.consumer_tag': msg.fields?.consumerTag,\n 'messaging.message.body_size': msg.content?.length || 0,\n ...(parentCtx.traceId ? { 'messaging.parent_trace_id': parentCtx.traceId } : {}),\n },\n options\n );\n\n if (!span) return callback(msg);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = callback(msg);\n\n // Handle async consumers (returning promises)\n if (result && typeof (result as any).then === 'function') {\n return (result as any).then(\n (val: any) => {\n span.end(0);\n return val;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n };\n\n return original.call(this, queue, wrappedCallback, consumeOptions);\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Module patching strategies\n// ---------------------------------------------------------------------------\n\n/**\n * Strategy 1: Patch Channel prototypes from the internal module structure.\n * amqplib/lib/channel_model exports Channel and ConfirmChannel.\n */\nconst patchFromInternals = (amqplib: any, options?: SenzorOptions) => {\n // Try to reach Channel prototype via internal module\n try {\n const channelModel = require('amqplib/lib/channel_model');\n if (channelModel?.Channel?.prototype) {\n patchChannel(channelModel.Channel.prototype, options);\n }\n if (channelModel?.ConfirmChannel?.prototype) {\n patchChannel(channelModel.ConfirmChannel.prototype, options);\n }\n } catch { }\n};\n\n/**\n * Strategy 2: Wrap createChannel/createConfirmChannel to patch returned instances.\n * Works even if internal structure changes between versions.\n */\nconst patchConnectionFactory = (amqplib: any, options?: SenzorOptions) => {\n // Wrap amqplib.connect to intercept the connection object\n patchMethod(\n amqplib,\n 'connect',\n 'senzor.amqplib.connect',\n (original) =>\n function patchedConnect(this: any, ...args: any[]) {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then((connection: any) => {\n if (!connection) return connection;\n\n // Wrap createChannel\n patchMethod(\n connection,\n 'createChannel',\n 'senzor.amqplib.createChannel',\n (origCreate) =>\n function patchedCreateChannel(this: any, ...createArgs: any[]) {\n const chResult = origCreate.apply(this, createArgs);\n if (chResult && typeof chResult.then === 'function') {\n return chResult.then((channel: any) => {\n if (channel) patchChannel(channel, options);\n return channel;\n });\n }\n if (chResult) patchChannel(chResult, options);\n return chResult;\n }\n );\n\n // Wrap createConfirmChannel\n patchMethod(\n connection,\n 'createConfirmChannel',\n 'senzor.amqplib.createConfirmChannel',\n (origCreate) =>\n function patchedCreateConfirmChannel(this: any, ...createArgs: any[]) {\n const chResult = origCreate.apply(this, createArgs);\n if (chResult && typeof chResult.then === 'function') {\n return chResult.then((channel: any) => {\n if (channel) patchChannel(channel, options);\n return channel;\n });\n }\n if (chResult) patchChannel(chResult, options);\n return chResult;\n }\n );\n\n return connection;\n });\n }\n\n return result;\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentAmqplib = (options?: SenzorOptions) => {\n hookRequire('amqplib', (exports: any) => {\n patchFromInternals(exports, options);\n patchConnectionFactory(exports, options);\n });\n\n // Also hook the callback API variant\n hookRequire('amqplib/callback_api', (exports: any) => {\n patchConnectionFactory(exports, options);\n });\n};\n","import { Context } from '../core/context';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod, isPatched } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Socket.IO Instrumentation\n//\n// Instruments socket.io (server-side):\n// - Socket.prototype.emit() — outbound event spans (server → client)\n// - Socket.prototype.on() — wraps event handlers with receive spans\n// - Namespace.prototype.emit() — broadcast event spans\n//\n// Instruments socket.io-client (client-side):\n// - Socket.prototype.emit() — outbound event spans (client → server)\n// - Socket.prototype.on() — wraps event handlers with receive spans\n//\n// Follows OTel messaging semantic conventions:\n// messaging.system = socket.io\n// messaging.destination.name = event name\n// messaging.operation.name = send | receive\n// ---------------------------------------------------------------------------\n\n/** Events to never instrument (internal socket.io events). */\nconst IGNORED_EVENTS = new Set([\n 'connect',\n 'connect_error',\n 'disconnect',\n 'disconnecting',\n 'newListener',\n 'removeListener',\n 'error',\n 'ping',\n 'pong',\n 'connection',\n]);\n\n/** Check if an event should be instrumented. */\nconst shouldInstrument = (event: string): boolean => {\n if (typeof event !== 'string') return false;\n return !IGNORED_EVENTS.has(event);\n};\n\n// ---------------------------------------------------------------------------\n// Emit patching (outbound events)\n// ---------------------------------------------------------------------------\n\nconst patchEmit = (\n proto: any,\n patchKey: string,\n side: 'server' | 'client',\n options?: SenzorOptions\n) => {\n patchMethod(\n proto,\n 'emit',\n patchKey,\n (original) =>\n function patchedEmit(this: any, event: string, ...args: any[]) {\n if (!shouldInstrument(event)) {\n return original.call(this, event, ...args);\n }\n\n const trace = Context.current();\n if (!trace) return original.call(this, event, ...args);\n\n const namespace = this.nsp?.name || this.name || '/';\n\n const span = startCapturedSpan(\n `Socket.IO ${side} emit ${event}`,\n 'messaging',\n {\n 'messaging.system': 'socket.io',\n 'messaging.destination.name': event,\n 'messaging.operation.name': 'send',\n 'messaging.socketio.namespace': namespace,\n 'messaging.socketio.side': side,\n 'messaging.socketio.event': event,\n },\n options\n );\n\n if (!span) return original.call(this, event, ...args);\n\n // Check if last arg is an acknowledgement callback\n const lastArg = args[args.length - 1];\n const hasAck = typeof lastArg === 'function';\n\n if (hasAck) {\n const originalAck = lastArg;\n args[args.length - 1] = function wrappedAck(...ackArgs: any[]) {\n span.end(0, { 'messaging.socketio.acknowledged': true });\n return originalAck.apply(this, ackArgs);\n };\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, event, ...args);\n\n if (!hasAck) {\n // Fire-and-forget emit — end span immediately\n span.end(0);\n }\n\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'SocketIOError',\n });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// On patching (inbound event handlers)\n// ---------------------------------------------------------------------------\n\nconst patchOn = (\n proto: any,\n patchKey: string,\n side: 'server' | 'client',\n options?: SenzorOptions\n) => {\n patchMethod(\n proto,\n 'on',\n patchKey,\n (original) =>\n function patchedOn(this: any, event: string, listener: any) {\n if (!shouldInstrument(event) || typeof listener !== 'function') {\n return original.call(this, event, listener);\n }\n\n const namespace = this.nsp?.name || this.name || '/';\n\n const wrappedListener = function (this: any, ...args: any[]) {\n const span = startCapturedSpan(\n `Socket.IO ${side} receive ${event}`,\n 'messaging',\n {\n 'messaging.system': 'socket.io',\n 'messaging.destination.name': event,\n 'messaging.operation.name': 'receive',\n 'messaging.socketio.namespace': namespace,\n 'messaging.socketio.side': side,\n 'messaging.socketio.event': event,\n },\n options\n );\n\n if (!span) return listener.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = listener.apply(this, args);\n\n // Handle async handlers\n if (result && typeof result.then === 'function') {\n return result.then(\n (val: any) => {\n span.end(0);\n return val;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n };\n\n // Preserve the original listener reference for removeListener support\n (wrappedListener as any).__senzorOriginal = listener;\n\n return original.call(this, event, wrappedListener);\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Server-side patching\n// ---------------------------------------------------------------------------\n\nconst patchServerSocket = (socketio: any, options?: SenzorOptions) => {\n // Socket.prototype (individual socket)\n const SocketClass = socketio?.Socket;\n if (SocketClass?.prototype) {\n patchEmit(SocketClass.prototype, 'senzor.socketio.server.socket.emit', 'server', options);\n patchOn(SocketClass.prototype, 'senzor.socketio.server.socket.on', 'server', options);\n }\n\n // Namespace.prototype (broadcast to namespace/room)\n const NamespaceClass = socketio?.Namespace;\n if (NamespaceClass?.prototype) {\n patchEmit(NamespaceClass.prototype, 'senzor.socketio.server.namespace.emit', 'server', options);\n }\n};\n\n// ---------------------------------------------------------------------------\n// Client-side patching\n// ---------------------------------------------------------------------------\n\nconst patchClientSocket = (clientModule: any, options?: SenzorOptions) => {\n // socket.io-client exports a Socket class or io function\n const SocketClass = clientModule?.Socket || clientModule?.io?.Socket;\n if (SocketClass?.prototype) {\n patchEmit(SocketClass.prototype, 'senzor.socketio.client.emit', 'client', options);\n patchOn(SocketClass.prototype, 'senzor.socketio.client.on', 'client', options);\n }\n\n // Some versions export Manager too\n if (clientModule?.Manager?.prototype) {\n // Manager handles reconnection events, but we don't need to patch those\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentSocketIO = (options?: SenzorOptions) => {\n // Server-side socket.io\n hookRequire('socket.io', (exports: any) => {\n // socket.io exports a Server class. Socket and Namespace are properties of the module\n patchServerSocket(exports, options);\n\n // In some versions, Socket is exported from a sub-module\n if (!exports.Socket) {\n try {\n const socketModule = require('socket.io/dist/socket');\n if (socketModule?.Socket?.prototype) {\n patchEmit(socketModule.Socket.prototype, 'senzor.socketio.server.socket.emit', 'server', options);\n patchOn(socketModule.Socket.prototype, 'senzor.socketio.server.socket.on', 'server', options);\n }\n } catch { }\n }\n\n if (!exports.Namespace) {\n try {\n const nsModule = require('socket.io/dist/namespace');\n if (nsModule?.Namespace?.prototype) {\n patchEmit(nsModule.Namespace.prototype, 'senzor.socketio.server.namespace.emit', 'server', options);\n }\n } catch { }\n }\n });\n\n // Client-side socket.io-client\n hookRequire('socket.io-client', (exports: any) => {\n patchClientSocket(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// NestJS Instrumentation\n//\n// Instruments @nestjs/core at the router execution layer:\n// - RouterExecutionContext.prototype.create() — wraps the handler factory\n// so every controller method invocation generates a span with:\n// nestjs.controller, nestjs.method, nestjs.route, http.route\n//\n// This captures the full NestJS request lifecycle including guards,\n// interceptors, pipes, and the controller method execution.\n//\n// Works with both Express and Fastify adapters since we patch at the\n// NestJS layer above the HTTP adapter.\n// ---------------------------------------------------------------------------\n\n/** Extract a human-readable name from a NestJS controller class. */\nconst getControllerName = (instance: any): string => {\n if (!instance) return 'UnknownController';\n return instance.constructor?.name || 'UnknownController';\n};\n\n// ---------------------------------------------------------------------------\n// RouterExecutionContext patching\n// ---------------------------------------------------------------------------\n\nconst patchRouterExecutionContext = (nestCore: any, options?: SenzorOptions) => {\n // Try to access RouterExecutionContext from the module\n let RouterExecutionContext: any;\n\n try {\n RouterExecutionContext = require('@nestjs/core/router/router-execution-context')?.RouterExecutionContext;\n } catch { }\n\n // Fallback: search in exports\n if (!RouterExecutionContext) {\n RouterExecutionContext = nestCore?.RouterExecutionContext;\n }\n\n if (!RouterExecutionContext?.prototype?.create) return;\n\n patchMethod(\n RouterExecutionContext.prototype,\n 'create',\n 'senzor.nestjs.routerExecutionContext.create',\n (original) =>\n function patchedCreate(\n this: any,\n instance: any,\n callback: Function,\n methodName: string,\n moduleKey: string,\n requestMethod: number,\n ...rest: any[]\n ) {\n const handler = original.call(this, instance, callback, methodName, moduleKey, requestMethod, ...rest);\n\n if (typeof handler !== 'function') return handler;\n\n const controllerName = getControllerName(instance);\n\n return function wrappedNestHandler(this: any, req: any, res: any, next: any) {\n // Extract route from request\n const route = req?.route?.path || req?.url?.split('?')[0] || '/';\n\n const span = startCapturedSpan(\n `NestJS ${controllerName}.${methodName}`,\n 'function',\n {\n 'nestjs.controller': controllerName,\n 'nestjs.method': methodName,\n 'nestjs.module': moduleKey,\n 'nestjs.type': 'request_handler',\n 'http.route': route,\n },\n options\n );\n\n if (!span) return handler.call(this, req, res, next);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = handler.call(this, req, res, next);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (val: any) => {\n span.end(0);\n return val;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n };\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// RouterExplorer patching (alternative / complementary)\n// ---------------------------------------------------------------------------\n\nconst patchRouterExplorer = (nestCore: any, options?: SenzorOptions) => {\n let RouterExplorer: any;\n\n try {\n RouterExplorer = require('@nestjs/core/router/router-explorer')?.RouterExplorer;\n } catch { }\n\n if (!RouterExplorer) {\n RouterExplorer = nestCore?.RouterExplorer;\n }\n\n if (!RouterExplorer?.prototype?.applyCallbackToRouter) return;\n\n patchMethod(\n RouterExplorer.prototype,\n 'applyCallbackToRouter',\n 'senzor.nestjs.routerExplorer.applyCallbackToRouter',\n (original) =>\n function patchedApplyCallback(\n this: any,\n router: any,\n routeDefinition: any,\n instanceWrapper: any,\n moduleKey: string,\n ...rest: any[]\n ) {\n // Extract metadata before registration\n const methodName = routeDefinition?.methodName || 'unknown';\n const path = routeDefinition?.path || '/';\n const requestMethod = routeDefinition?.requestMethod;\n\n const controllerName = instanceWrapper?.metatype?.name\n || instanceWrapper?.name\n || 'UnknownController';\n\n // Let NestJS register the route normally\n const result = original.call(this, router, routeDefinition, instanceWrapper, moduleKey, ...rest);\n\n // Log registration for debug\n if (options?.debug) {\n console.log(`[Senzor] NestJS route registered: ${controllerName}.${methodName} → ${path}`);\n }\n\n return result;\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentNestJS = (options?: SenzorOptions) => {\n hookRequire('@nestjs/core', (exports: any) => {\n patchRouterExecutionContext(exports, options);\n patchRouterExplorer(exports, options);\n });\n\n // Also try the specific sub-module paths (varies by NestJS version)\n hookRequire('@nestjs/core/router/router-execution-context', (exports: any) => {\n if (exports?.RouterExecutionContext?.prototype?.create) {\n patchMethod(\n exports.RouterExecutionContext.prototype,\n 'create',\n 'senzor.nestjs.rec.create.direct',\n (original) =>\n function patchedCreateDirect(\n this: any,\n instance: any,\n callback: Function,\n methodName: string,\n moduleKey: string,\n requestMethod: number,\n ...rest: any[]\n ) {\n const handler = original.call(this, instance, callback, methodName, moduleKey, requestMethod, ...rest);\n if (typeof handler !== 'function') return handler;\n\n const controllerName = getControllerName(instance);\n\n return function wrappedHandler(this: any, req: any, res: any, next: any) {\n const route = req?.route?.path || req?.url?.split('?')[0] || '/';\n\n const span = startCapturedSpan(\n `NestJS ${controllerName}.${methodName}`,\n 'function',\n {\n 'nestjs.controller': controllerName,\n 'nestjs.method': methodName,\n 'nestjs.module': moduleKey,\n 'nestjs.type': 'request_handler',\n 'http.route': route,\n },\n options\n );\n\n if (!span) return handler.call(this, req, res, next);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = handler.call(this, req, res, next);\n if (result && typeof result.then === 'function') {\n return result.then(\n (val: any) => { span.end(0); return val; },\n (err: any) => { span.end(500, { 'error.message': err?.message }); throw err; }\n );\n }\n span.end(0);\n return result;\n } catch (err: any) {\n span.end(500, { 'error.message': err?.message });\n throw err;\n }\n });\n };\n }\n );\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Hapi Instrumentation\n//\n// Instruments @hapi/hapi at the route registration layer:\n// - Server.prototype.route() — wraps route handlers at registration time\n// so every request generates a span with:\n// hapi.route, hapi.method, http.route\n//\n// Captures the full handler execution including any route-level validation,\n// payload parsing, and response formatting done by Hapi.\n//\n// The handler signature is always: (request, h) => response\n// ---------------------------------------------------------------------------\n\n/** HTTP method enum to string mapping for older Hapi versions. */\nconst METHOD_MAP: Record<number, string> = {\n 0: 'GET', 1: 'HEAD', 2: 'POST', 3: 'PUT',\n 4: 'DELETE', 5: 'OPTIONS', 6: 'PATCH',\n};\n\nconst normalizeMethod = (method: any): string => {\n if (typeof method === 'string') return method.toUpperCase();\n if (typeof method === 'number') return METHOD_MAP[method] || 'UNKNOWN';\n return 'UNKNOWN';\n};\n\n// ---------------------------------------------------------------------------\n// Handler wrapping\n// ---------------------------------------------------------------------------\n\nconst wrapHandler = (\n handler: Function,\n routePath: string,\n routeMethod: string,\n options?: SenzorOptions\n): Function => {\n if (typeof handler !== 'function') return handler;\n\n return function wrappedHapiHandler(this: any, request: any, h: any) {\n const method = normalizeMethod(routeMethod);\n const path = routePath || request?.route?.path || request?.path || '/';\n\n const span = startCapturedSpan(\n `Hapi ${method} ${path}`,\n 'function',\n {\n 'hapi.type': 'route_handler',\n 'hapi.route': path,\n 'hapi.method': method,\n 'http.route': path,\n framework: 'hapi',\n },\n options\n );\n\n if (!span) return handler.call(this, request, h);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = handler.call(this, request, h);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (val: any) => {\n const statusCode = val?.statusCode || request?.response?.statusCode || 200;\n span.end(statusCode >= 400 ? statusCode : 0, {\n 'http.response.status_code': statusCode,\n });\n return val;\n },\n (error: any) => {\n const statusCode = error?.output?.statusCode || 500;\n span.end(statusCode, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n 'http.response.status_code': statusCode,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n const statusCode = error?.output?.statusCode || 500;\n span.end(statusCode, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n 'http.response.status_code': statusCode,\n });\n throw error;\n }\n });\n };\n};\n\n// ---------------------------------------------------------------------------\n// Route config processing\n// ---------------------------------------------------------------------------\n\n/**\n * Process a single route configuration object and wrap its handler.\n * Hapi route configs can have handler at config.handler or config.options.handler.\n */\nconst processRouteConfig = (config: any, options?: SenzorOptions): any => {\n if (!config) return config;\n\n const method = config.method || 'GET';\n const path = config.path || '/';\n\n // Clone config to avoid mutating user's original object\n const wrapped = { ...config };\n\n // Handler can be at config.handler or config.options.handler\n if (typeof wrapped.handler === 'function') {\n wrapped.handler = wrapHandler(wrapped.handler, path, method, options);\n } else if (wrapped.options && typeof wrapped.options.handler === 'function') {\n wrapped.options = { ...wrapped.options };\n wrapped.options.handler = wrapHandler(wrapped.options.handler, path, method, options);\n } else if (wrapped.config && typeof wrapped.config.handler === 'function') {\n // Legacy Hapi config location\n wrapped.config = { ...wrapped.config };\n wrapped.config.handler = wrapHandler(wrapped.config.handler, path, method, options);\n }\n\n return wrapped;\n};\n\n// ---------------------------------------------------------------------------\n// Server.route() patching\n// ---------------------------------------------------------------------------\n\nconst patchServerRoute = (serverProto: any, options?: SenzorOptions) => {\n if (!serverProto) return;\n\n patchMethod(\n serverProto,\n 'route',\n 'senzor.hapi.server.route',\n (original) =>\n function patchedRoute(this: any, routeConfig: any) {\n // server.route() accepts a single config or an array of configs\n if (Array.isArray(routeConfig)) {\n const wrappedConfigs = routeConfig.map((config: any) =>\n processRouteConfig(config, options)\n );\n return original.call(this, wrappedConfigs);\n }\n\n const wrappedConfig = processRouteConfig(routeConfig, options);\n return original.call(this, wrappedConfig);\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Extension point patching (for lifecycle span visibility)\n// ---------------------------------------------------------------------------\n\nconst patchServerExt = (serverProto: any, options?: SenzorOptions) => {\n if (!serverProto) return;\n\n patchMethod(\n serverProto,\n 'ext',\n 'senzor.hapi.server.ext',\n (original) =>\n function patchedExt(this: any, event: any, method?: any, extOptions?: any) {\n // ext() can be called as:\n // ext(event, method, options) — single extension\n // ext([{ type, method, options }]) — array of extensions\n // ext({ type, method, options }) — single object\n\n if (typeof event === 'string' && typeof method === 'function') {\n const eventName = event;\n const originalMethod = method;\n\n const wrappedMethod = function (this: any, request: any, h: any) {\n const span = startCapturedSpan(\n `Hapi ext ${eventName}`,\n 'function',\n {\n 'hapi.type': 'lifecycle_hook',\n 'hapi.hook': eventName,\n framework: 'hapi',\n },\n options\n );\n\n if (!span) return originalMethod.call(this, request, h);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = originalMethod.call(this, request, h);\n if (result && typeof result.then === 'function') {\n return result.then(\n (val: any) => { span.end(0); return val; },\n (err: any) => {\n span.end(500, { 'error.message': err?.message });\n throw err;\n }\n );\n }\n span.end(0);\n return result;\n } catch (err: any) {\n span.end(500, { 'error.message': err?.message });\n throw err;\n }\n });\n };\n\n return original.call(this, event, wrappedMethod, extOptions);\n }\n\n // For array/object form, pass through unchanged (avoid complex nesting)\n return original.call(this, event, method, extOptions);\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentHapi = (options?: SenzorOptions) => {\n hookRequire('@hapi/hapi', (exports: any) => {\n // Hapi exports a Server class\n const Server = exports?.Server || exports?.server?.Server;\n\n if (Server?.prototype) {\n patchServerRoute(Server.prototype, options);\n\n // Only patch ext if framework spans are enabled\n if (options?.frameworkSpans !== false) {\n patchServerExt(Server.prototype, options);\n }\n }\n });\n\n // Also try the legacy 'hapi' package name (pre-scoped)\n hookRequire('hapi', (exports: any) => {\n const Server = exports?.Server || exports?.server?.Server;\n if (Server?.prototype) {\n patchServerRoute(Server.prototype, options);\n if (options?.frameworkSpans !== false) {\n patchServerExt(Server.prototype, options);\n }\n }\n });\n};\n","import { Context } from '../core/context';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\n\n// ---------------------------------------------------------------------------\n// Pino Log Correlation\n//\n// Injects traceId and spanId from the active Senzor context into every\n// pino log record. This enables log-to-trace correlation in the dashboard.\n//\n// Strategy: Wrap the pino factory to inject a mixin function that reads\n// from AsyncLocalStorage on every log call. If the user provides their\n// own mixin, both are composed together.\n//\n// Also patches existing logger prototypes to ensure loggers created before\n// instrumentation are also covered.\n//\n// Injected fields:\n// - traceId: string (APM trace ID or Task run ID)\n// - spanId: string (active span ID)\n// - senzor.context: 'apm' | 'task'\n// ---------------------------------------------------------------------------\n\n/** Get trace correlation fields from the current async context. */\nconst getTraceFields = (): Record<string, string> | null => {\n const trace = Context.current();\n if (!trace) return null;\n\n const fields: Record<string, string> = {\n traceId: trace.id,\n };\n\n if (trace.activeSpanId) {\n fields.spanId = trace.activeSpanId;\n }\n\n fields['senzor.context'] = trace.contextType;\n\n return fields;\n};\n\n/** Create a mixin function that injects trace context. */\nconst createTraceMixin = (userMixin?: Function): Function => {\n return (mergeObject: any, level: number) => {\n const traceFields = getTraceFields();\n const userFields = typeof userMixin === 'function'\n ? userMixin(mergeObject, level)\n : {};\n\n return {\n ...userFields,\n ...(traceFields || {}),\n };\n };\n};\n\n// ---------------------------------------------------------------------------\n// Factory wrapping\n// ---------------------------------------------------------------------------\n\nconst patchPinoFactory = (pinoModule: any, _options?: SenzorOptions) => {\n // pino is exported as a function (the factory) with properties on it\n // We need to wrap the function itself, which is tricky since it's the module export\n\n // Strategy: Patch the internal prototype's write method for already-created loggers\n // AND wrap the factory for new loggers\n\n // 1. Wrap the factory\n const originalPino = pinoModule;\n\n if (typeof pinoModule !== 'function') return;\n\n // We can't replace the module export directly from hookRequire,\n // but we can patch the prototype for existing loggers\n\n // 2. Patch the internal prototype\n // Create a temp logger to get the prototype\n try {\n const devNull = { write: () => {} };\n const tempLogger = pinoModule({ level: 'silent' }, devNull);\n const proto = Object.getPrototypeOf(tempLogger);\n\n if (proto && !proto.__senzorPatched) {\n // Find the write symbol or method\n const writeSymbol = Object.getOwnPropertySymbols(proto).find(\n (sym) => sym.toString().includes('write') || sym.toString().includes('pino.write')\n );\n\n if (writeSymbol) {\n const originalWrite = proto[writeSymbol];\n if (typeof originalWrite === 'function') {\n proto[writeSymbol] = function patchedWrite(this: any, obj: any, msg: any, num: any) {\n const traceFields = getTraceFields();\n if (traceFields && obj && typeof obj === 'object') {\n Object.assign(obj, traceFields);\n }\n return originalWrite.call(this, obj, msg, num);\n };\n }\n }\n\n // Also try patching the level methods directly as fallback\n const levels = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];\n for (const level of levels) {\n if (typeof proto[level] === 'function') {\n patchMethod(\n proto,\n level,\n `senzor.pino.${level}`,\n (original) =>\n function patchedLevel(this: any, ...args: any[]) {\n const traceFields = getTraceFields();\n if (!traceFields) return original.apply(this, args);\n\n // pino level methods accept:\n // .info(obj, msg, ...args)\n // .info(msg, ...args)\n // .info(err, msg, ...args)\n if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n // First arg is a merge object — inject trace fields\n args[0] = { ...args[0], ...traceFields };\n } else if (args.length > 0 && typeof args[0] === 'string') {\n // First arg is message string — prepend a merge object\n args.unshift(traceFields);\n } else if (args.length > 0 && args[0] instanceof Error) {\n // First arg is an error — add trace fields alongside\n const err = args[0];\n args[0] = { ...traceFields, err };\n if (typeof args[1] !== 'string') {\n args.splice(1, 0, err.message);\n }\n }\n\n return original.apply(this, args);\n }\n );\n }\n }\n\n // Patch child() to ensure child loggers also get correlation\n if (typeof proto.child === 'function') {\n patchMethod(\n proto,\n 'child',\n 'senzor.pino.child',\n (original) =>\n function patchedChild(this: any, bindings: any, ...args: any[]) {\n // Child loggers inherit the patched prototype automatically\n return original.call(this, bindings, ...args);\n }\n );\n }\n\n proto.__senzorPatched = true;\n }\n } catch {\n // Pino may not be fully loaded yet — the hookRequire retry will catch it\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentPino = (_options?: SenzorOptions) => {\n hookRequire('pino', (exports: any) => {\n patchPinoFactory(exports, _options);\n });\n};\n","import { Context } from '../core/context';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\n\n// ---------------------------------------------------------------------------\n// Winston Log Correlation\n//\n// Injects traceId and spanId from the active Senzor context into every\n// winston log entry. Enables log-to-trace correlation in the dashboard.\n//\n// Strategy: Patch Logger.prototype.write() to inject trace fields into\n// the info object before it flows to transports. This covers all log\n// methods (info, error, warn, debug, etc.) since they all call write().\n//\n// Injected fields:\n// - traceId: string\n// - spanId: string\n// - senzor.context: 'apm' | 'task'\n// ---------------------------------------------------------------------------\n\n/** Get trace correlation fields from the current async context. */\nconst getTraceFields = (): Record<string, string> | null => {\n const trace = Context.current();\n if (!trace) return null;\n\n const fields: Record<string, string> = {\n traceId: trace.id,\n };\n\n if (trace.activeSpanId) {\n fields.spanId = trace.activeSpanId;\n }\n\n fields['senzor.context'] = trace.contextType;\n\n return fields;\n};\n\n// ---------------------------------------------------------------------------\n// Logger.prototype.write patching\n// ---------------------------------------------------------------------------\n\nconst patchWinstonLogger = (winston: any, _options?: SenzorOptions) => {\n // winston exports createLogger, Logger, etc.\n // Logger is at winston.Logger or winston.transports (for older versions)\n\n // Try to get Logger from several locations\n let LoggerClass = winston?.Logger;\n\n // In winston 3.x, Logger is also accessible via the createLogger factory\n if (!LoggerClass) {\n try {\n const loggerModule = require('winston/lib/winston/logger');\n LoggerClass = loggerModule?.Logger || loggerModule;\n } catch { }\n }\n\n if (!LoggerClass?.prototype) return;\n\n // Patch write() — the core method all log calls funnel through\n patchMethod(\n LoggerClass.prototype,\n 'write',\n 'senzor.winston.logger.write',\n (original) =>\n function patchedWrite(this: any, info: any) {\n if (info && typeof info === 'object') {\n const traceFields = getTraceFields();\n if (traceFields) {\n // Inject trace fields into the info object\n // Use non-enumerable setter to avoid conflicts with symbols\n info.traceId = traceFields.traceId;\n if (traceFields.spanId) info.spanId = traceFields.spanId;\n info['senzor.context'] = traceFields['senzor.context'];\n }\n }\n return original.call(this, info);\n }\n );\n\n // Also patch log() as a safety net for custom transports that call log directly\n patchMethod(\n LoggerClass.prototype,\n 'log',\n 'senzor.winston.logger.log',\n (original) =>\n function patchedLog(this: any, ...args: any[]) {\n // log() normalizes args into an info object, then calls write()\n // Since write() is already patched, we just need to ensure the\n // info object exists for direct log() calls with string args\n //\n // log(level, message) or log({ level, message }) or log(info)\n const traceFields = getTraceFields();\n\n if (traceFields && args.length > 0) {\n // If first arg is an info-like object, inject directly\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n args[0] = { ...args[0], ...traceFields };\n }\n // For other signatures, write() patch handles it\n }\n\n return original.apply(this, args);\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// createLogger wrapping\n// ---------------------------------------------------------------------------\n\nconst patchCreateLogger = (winston: any, _options?: SenzorOptions) => {\n if (typeof winston?.createLogger !== 'function') return;\n\n patchMethod(\n winston,\n 'createLogger',\n 'senzor.winston.createLogger',\n (original) =>\n function patchedCreateLogger(this: any, opts: any) {\n const logger = original.call(this, opts);\n\n // Ensure the logger instance has patched write/log\n // (in case the prototype wasn't patched yet)\n if (logger && !logger.__senzorPatched) {\n const proto = Object.getPrototypeOf(logger);\n if (proto && !proto.__senzorPatched) {\n patchWinstonLogger({ Logger: { prototype: proto } }, _options);\n proto.__senzorPatched = true;\n }\n logger.__senzorPatched = true;\n }\n\n return logger;\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentWinston = (options?: SenzorOptions) => {\n hookRequire('winston', (exports: any) => {\n patchWinstonLogger(exports, options);\n patchCreateLogger(exports, options);\n });\n};\n","import { Context } from '../core/context';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\n\n// ---------------------------------------------------------------------------\n// Bunyan Log Correlation\n//\n// Injects traceId and spanId from the active Senzor context into every\n// bunyan log record. Enables log-to-trace correlation in the dashboard.\n//\n// Strategy: Patch Logger.prototype._emit() — the core logging method that\n// all level methods (info, debug, warn, error, fatal, trace) call.\n// The `rec` parameter is the log record object; we inject trace fields\n// before the original _emit serializes and writes it.\n//\n// Also patches Logger.prototype.child() to ensure child loggers inherit\n// the patched _emit via prototype chain.\n//\n// Injected fields:\n// - traceId: string\n// - spanId: string\n// - senzor_context: 'apm' | 'task'\n// ---------------------------------------------------------------------------\n\n/** Get trace correlation fields from the current async context. */\nconst getTraceFields = (): Record<string, string> | null => {\n const trace = Context.current();\n if (!trace) return null;\n\n const fields: Record<string, string> = {\n traceId: trace.id,\n };\n\n if (trace.activeSpanId) {\n fields.spanId = trace.activeSpanId;\n }\n\n // Use underscore instead of dot for bunyan compatibility\n // (dots in keys can cause issues with some bunyan serializers)\n fields.senzor_context = trace.contextType;\n\n return fields;\n};\n\n// ---------------------------------------------------------------------------\n// Logger.prototype._emit patching\n// ---------------------------------------------------------------------------\n\nconst patchBunyanLogger = (bunyan: any, _options?: SenzorOptions) => {\n // bunyan exports the Logger constructor directly\n // bunyan === Logger (the constructor function)\n // bunyan.createLogger is a factory that calls new Logger()\n\n const LoggerProto = bunyan?.prototype;\n\n if (!LoggerProto) return;\n\n // Patch _emit — the core method all log calls funnel through\n patchMethod(\n LoggerProto,\n '_emit',\n 'senzor.bunyan.logger._emit',\n (original) =>\n function patchedEmit(this: any, rec: any, noemit?: boolean) {\n if (rec && typeof rec === 'object') {\n const traceFields = getTraceFields();\n if (traceFields) {\n // Inject trace fields into the log record\n rec.traceId = traceFields.traceId;\n if (traceFields.spanId) rec.spanId = traceFields.spanId;\n rec.senzor_context = traceFields.senzor_context;\n }\n }\n return original.call(this, rec, noemit);\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentBunyan = (options?: SenzorOptions) => {\n hookRequire('bunyan', (exports: any) => {\n patchBunyanLogger(exports, options);\n\n // Also handle default export\n if (exports?.default?.prototype?._emit) {\n patchBunyanLogger(exports.default, options);\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// AWS SDK v3 Instrumentation\n//\n// Instruments @aws-sdk/smithy-client (the core of AWS SDK v3) by patching\n// the Client.prototype.send() method — the single dispatch point for ALL\n// AWS service calls (S3, DynamoDB, SQS, SNS, Lambda, etc.).\n//\n// Also hooks individual service packages as a fallback, intercepting their\n// Client classes directly.\n//\n// Captured span attributes follow OTel semantic conventions for cloud/AWS:\n// - rpc.system: 'aws-api'\n// - rpc.service: e.g. 'S3', 'DynamoDB'\n// - rpc.method: e.g. 'PutObject', 'GetItem'\n// - aws.region: configured region\n// - aws.request_id: from response metadata\n// - http.response.status_code: HTTP status of the API call\n// ---------------------------------------------------------------------------\n\n/** Known AWS service name mappings from client constructor names. */\nconst SERVICE_NAME_MAP: Record<string, string> = {\n S3Client: 'S3',\n DynamoDBClient: 'DynamoDB',\n SQSClient: 'SQS',\n SNSClient: 'SNS',\n LambdaClient: 'Lambda',\n SESClient: 'SES',\n SESv2Client: 'SESv2',\n CloudWatchClient: 'CloudWatch',\n CloudWatchLogsClient: 'CloudWatchLogs',\n KinesisClient: 'Kinesis',\n EventBridgeClient: 'EventBridge',\n SecretsManagerClient: 'SecretsManager',\n SSMClient: 'SSM',\n STSClient: 'STS',\n IAMClient: 'IAM',\n EC2Client: 'EC2',\n ECSClient: 'ECS',\n EKSClient: 'EKS',\n RDSClient: 'RDS',\n ElastiCacheClient: 'ElastiCache',\n RedshiftClient: 'Redshift',\n CognitoIdentityProviderClient: 'CognitoIdentityProvider',\n Route53Client: 'Route53',\n CloudFrontClient: 'CloudFront',\n APIGatewayClient: 'APIGateway',\n StepFunctionsClient: 'StepFunctions',\n CodeBuildClient: 'CodeBuild',\n CodePipelineClient: 'CodePipeline',\n ACMClient: 'ACM',\n KMSClient: 'KMS',\n BedrockRuntimeClient: 'BedrockRuntime',\n};\n\n// ---------------------------------------------------------------------------\n// Bedrock Runtime — GenAI attribute extraction\n// ---------------------------------------------------------------------------\n\n/** Bedrock model ID patterns for gen_ai.system mapping. */\nconst BEDROCK_SYSTEM_MAP: Record<string, string> = {\n anthropic: 'anthropic',\n amazon: 'aws_bedrock',\n meta: 'meta',\n cohere: 'cohere',\n mistral: 'mistral',\n ai21: 'ai21',\n stability: 'stability',\n};\n\nconst getBedrockSystem = (modelId: string | undefined): string => {\n if (!modelId) return 'aws_bedrock';\n const provider = modelId.split('.')[0]?.toLowerCase();\n return BEDROCK_SYSTEM_MAP[provider] || 'aws_bedrock';\n};\n\n/** Extract Bedrock-specific attributes from InvokeModel / InvokeModelWithResponseStream commands. */\nconst extractBedrockAttributes = (command: any, response: any): Record<string, any> => {\n const meta: Record<string, any> = {};\n const input = command?.input;\n if (!input) return meta;\n\n const modelId = input.modelId;\n if (modelId) {\n meta['gen_ai.system'] = getBedrockSystem(modelId);\n meta['gen_ai.request.model'] = modelId;\n }\n\n // Try to parse the response body for token usage\n // Bedrock responses are in the 'body' field as a Uint8Array or string\n try {\n let bodyStr: string | undefined;\n if (response?.body) {\n if (typeof response.body === 'string') {\n bodyStr = response.body;\n } else if (response.body instanceof Uint8Array) {\n bodyStr = new TextDecoder().decode(response.body);\n } else if (Buffer.isBuffer(response.body)) {\n bodyStr = response.body.toString('utf-8');\n }\n }\n\n if (bodyStr) {\n const parsed = JSON.parse(bodyStr);\n\n // Anthropic Messages API format\n if (parsed.usage) {\n if (parsed.usage.input_tokens !== undefined) {\n meta['gen_ai.usage.input_tokens'] = parsed.usage.input_tokens;\n }\n if (parsed.usage.output_tokens !== undefined) {\n meta['gen_ai.usage.output_tokens'] = parsed.usage.output_tokens;\n }\n }\n\n // Amazon Titan format\n if (parsed.inputTextTokenCount !== undefined) {\n meta['gen_ai.usage.input_tokens'] = meta['gen_ai.usage.input_tokens'] || parsed.inputTextTokenCount;\n }\n if (parsed.results?.[0]?.tokenCount !== undefined) {\n meta['gen_ai.usage.output_tokens'] = meta['gen_ai.usage.output_tokens'] || parsed.results[0].tokenCount;\n }\n\n // Cohere format\n if (parsed.meta?.billed_units) {\n meta['gen_ai.usage.input_tokens'] = meta['gen_ai.usage.input_tokens'] || parsed.meta.billed_units.input_tokens;\n meta['gen_ai.usage.output_tokens'] = meta['gen_ai.usage.output_tokens'] || parsed.meta.billed_units.output_tokens;\n }\n\n // Stop reason / finish reason\n if (parsed.stop_reason) meta['gen_ai.response.finish_reason'] = parsed.stop_reason;\n if (parsed.completionReason) meta['gen_ai.response.finish_reason'] = parsed.completionReason;\n }\n } catch {\n // Body parsing is best-effort — the span still captures the Bedrock call\n }\n\n return meta;\n};\n\n/** Check if a command is a Bedrock model invocation. */\nconst isBedrockInvocation = (operationName: string): boolean =>\n operationName === 'InvokeModel' ||\n operationName === 'InvokeModelWithResponseStream' ||\n operationName === 'Converse' ||\n operationName === 'ConverseStream';\n\n/** Extract Bedrock Converse API attributes. */\nconst extractBedrockConverseAttributes = (command: any, response: any): Record<string, any> => {\n const meta: Record<string, any> = {};\n const input = command?.input;\n if (!input) return meta;\n\n const modelId = input.modelId;\n if (modelId) {\n meta['gen_ai.system'] = getBedrockSystem(modelId);\n meta['gen_ai.request.model'] = modelId;\n }\n\n // Converse API returns usage directly in the response object\n if (response?.usage) {\n if (response.usage.inputTokens !== undefined) {\n meta['gen_ai.usage.input_tokens'] = response.usage.inputTokens;\n }\n if (response.usage.outputTokens !== undefined) {\n meta['gen_ai.usage.output_tokens'] = response.usage.outputTokens;\n }\n if (response.usage.totalTokens !== undefined) {\n meta['gen_ai.usage.total_tokens'] = response.usage.totalTokens;\n }\n }\n\n if (response?.stopReason) {\n meta['gen_ai.response.finish_reason'] = response.stopReason;\n }\n\n return meta;\n};\n\n/** Extract service name from client instance or command. */\nconst getServiceName = (client: any): string => {\n // Try constructor name mapping\n const ctorName = client?.constructor?.name;\n if (ctorName && SERVICE_NAME_MAP[ctorName]) {\n return SERVICE_NAME_MAP[ctorName];\n }\n\n // Try config.serviceId (AWS SDK v3 standard)\n if (client?.config?.serviceId) {\n return client.config.serviceId;\n }\n\n // Try middleware stack metadata\n if (client?.middlewareStack?.identify) {\n try {\n const id = client.middlewareStack.identify();\n if (typeof id === 'string' && id.length > 0) {\n return id.split(' ')[0];\n }\n } catch { }\n }\n\n // Fallback: strip 'Client' suffix from constructor name\n if (ctorName && ctorName.endsWith('Client')) {\n return ctorName.slice(0, -6) || 'AWS';\n }\n\n return 'AWS';\n};\n\n/** Extract operation name from a command object. */\nconst getOperationName = (command: any): string => {\n const name = command?.constructor?.name;\n if (!name) return 'UnknownCommand';\n // Strip 'Command' suffix: PutObjectCommand → PutObject\n return name.endsWith('Command') ? name.slice(0, -7) : name;\n};\n\n/** Extract region from client config. */\nconst getRegion = async (client: any): Promise<string | undefined> => {\n try {\n const region = client?.config?.region;\n if (typeof region === 'function') {\n return await region();\n }\n return region || undefined;\n } catch {\n return undefined;\n }\n};\n\n// ---------------------------------------------------------------------------\n// Core send() patching\n// ---------------------------------------------------------------------------\n\nconst patchClientSend = (clientProto: any, options?: SenzorOptions) => {\n if (!clientProto) return;\n\n patchMethod(\n clientProto,\n 'send',\n 'senzor.aws-sdk.client.send',\n (original) =>\n function patchedSend(this: any, command: any, ...args: any[]) {\n const serviceName = getServiceName(this);\n const operationName = getOperationName(command);\n const spanName = `AWS ${serviceName} ${operationName}`;\n\n const span = startCapturedSpan(\n spanName,\n 'http',\n {\n 'rpc.system': 'aws-api',\n 'rpc.service': serviceName,\n 'rpc.method': operationName,\n 'cloud.provider': 'aws',\n 'aws.service': serviceName,\n 'aws.operation': operationName,\n },\n options\n );\n\n if (!span) return original.call(this, command, ...args);\n\n // Resolve region asynchronously but don't block\n getRegion(this).then((region) => {\n if (region && span) {\n // Region is added on span end via meta\n (span as any).__awsRegion = region;\n }\n }).catch(() => { });\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, command, ...args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (response: any) => {\n const statusCode = response?.$metadata?.httpStatusCode;\n const requestId = response?.$metadata?.requestId;\n\n const endMeta: Record<string, any> = {\n 'aws.request_id': requestId,\n 'aws.region': (span as any).__awsRegion,\n 'http.response.status_code': statusCode,\n };\n\n // Bedrock GenAI attribute extraction\n if (isBedrockInvocation(operationName)) {\n const op = operationName;\n const bedrockMeta = (op === 'Converse' || op === 'ConverseStream')\n ? extractBedrockConverseAttributes(command, response)\n : extractBedrockAttributes(command, response);\n Object.assign(endMeta, bedrockMeta);\n }\n\n span.end(\n statusCode && statusCode >= 400 ? statusCode : 0,\n endMeta\n );\n\n return response;\n },\n (error: any) => {\n const statusCode = error?.$metadata?.httpStatusCode || 500;\n const requestId = error?.$metadata?.requestId;\n\n span.end(statusCode, {\n 'error.message': error?.message,\n 'error.type': error?.name || error?.code || 'AwsError',\n 'aws.request_id': requestId,\n 'aws.region': (span as any).__awsRegion,\n 'http.response.status_code': statusCode,\n });\n\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(error?.$metadata?.httpStatusCode || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Common AWS SDK v3 service packages to instrument. */\nconst AWS_SERVICE_PACKAGES = [\n '@aws-sdk/client-s3',\n '@aws-sdk/client-dynamodb',\n '@aws-sdk/client-sqs',\n '@aws-sdk/client-sns',\n '@aws-sdk/client-lambda',\n '@aws-sdk/client-ses',\n '@aws-sdk/client-sesv2',\n '@aws-sdk/client-cloudwatch',\n '@aws-sdk/client-cloudwatch-logs',\n '@aws-sdk/client-kinesis',\n '@aws-sdk/client-eventbridge',\n '@aws-sdk/client-secrets-manager',\n '@aws-sdk/client-ssm',\n '@aws-sdk/client-sts',\n '@aws-sdk/client-iam',\n '@aws-sdk/client-ec2',\n '@aws-sdk/client-ecs',\n '@aws-sdk/client-rds',\n '@aws-sdk/client-cognito-identity-provider',\n '@aws-sdk/client-route-53',\n '@aws-sdk/client-cloudfront',\n '@aws-sdk/client-api-gateway',\n '@aws-sdk/client-sfn',\n '@aws-sdk/client-codebuild',\n '@aws-sdk/client-kms',\n '@aws-sdk/client-bedrock-runtime',\n];\n\nexport const instrumentAwsSdk = (options?: SenzorOptions) => {\n // Primary: patch the smithy Client base class — covers ALL services\n hookRequire('@smithy/smithy-client', (exports: any) => {\n const Client = exports?.Client;\n if (Client?.prototype) {\n patchClientSend(Client.prototype, options);\n }\n });\n\n // Also try the older @aws-sdk/smithy-client path\n hookRequire('@aws-sdk/smithy-client', (exports: any) => {\n const Client = exports?.Client;\n if (Client?.prototype) {\n patchClientSend(Client.prototype, options);\n }\n });\n\n // Fallback: hook individual service packages for resilience\n // Only hook a subset of the most common ones to avoid over-registration\n for (const pkg of AWS_SERVICE_PACKAGES) {\n hookRequire(pkg, (exports: any) => {\n // Each package exports a *Client class (e.g., S3Client, DynamoDBClient)\n for (const key of Object.keys(exports)) {\n if (key.endsWith('Client') && exports[key]?.prototype?.send) {\n patchClientSend(exports[key].prototype, options);\n }\n }\n });\n }\n};\n","import { getSqlOperation, normalizeSql } from '../core/sanitizer';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Knex.js Instrumentation\n//\n// Instruments the Knex query builder at two layers:\n// 1. Client.prototype.query() — the final execution point for all queries.\n// Every .select(), .insert(), .where().update(), raw(), etc. funnels\n// through this method before hitting the underlying driver (pg, mysql,\n// sqlite3, mssql, oracledb).\n//\n// 2. Client.prototype._stream() — covers streaming queries.\n//\n// Captured span attributes (OTel semantic conventions):\n// - db.system.name: derived from client dialect (pg, mysql, sqlite3, etc.)\n// - db.operation.name: SELECT, INSERT, UPDATE, DELETE, etc.\n// - db.query.text: parameterized/normalized SQL\n// - db.collection.name: table name if detectable\n// - knex.method: Knex builder method (select, insert, update, del, raw)\n// ---------------------------------------------------------------------------\n\n/** Map knex dialect names to OTel db.system.name values. */\nconst DIALECT_MAP: Record<string, string> = {\n pg: 'postgresql',\n 'pg-native': 'postgresql',\n mysql: 'mysql',\n mysql2: 'mysql',\n sqlite3: 'sqlite',\n 'better-sqlite3': 'sqlite',\n mssql: 'mssql',\n oracledb: 'oracle',\n oracle: 'oracle',\n redshift: 'redshift',\n cockroachdb: 'cockroachdb',\n};\n\n/** Extract the database system from a Knex client instance. */\nconst getDbSystem = (client: any): string => {\n const dialect = client?.config?.client\n || client?.dialect\n || client?.driverName\n || 'unknown';\n\n const normalized = typeof dialect === 'string' ? dialect.toLowerCase() : 'unknown';\n return DIALECT_MAP[normalized] || normalized;\n};\n\n/** Extract table name from SQL statement. */\nconst extractTableName = (sql: string | undefined): string | undefined => {\n if (!sql) return undefined;\n // Match FROM table, INTO table, UPDATE table, JOIN table\n const match = sql.match(\n /(?:FROM|INTO|UPDATE|JOIN)\\s+[`\"[\\]]?(\\w+)[`\"\\]]?/i\n );\n return match?.[1] || undefined;\n};\n\n// ---------------------------------------------------------------------------\n// Client.prototype.query patching\n// ---------------------------------------------------------------------------\n\nconst patchKnexClient = (knexModule: any, options?: SenzorOptions) => {\n // Knex exports a factory function. The Client base class is at:\n // knex.Client (in some versions)\n // require('knex/lib/client') (internal)\n // We also intercept the factory to patch client instances.\n\n let ClientClass: any;\n\n // Try to get Client from the module\n ClientClass = knexModule?.Client;\n\n // Try the internal path\n if (!ClientClass) {\n try {\n ClientClass = require('knex/lib/client');\n } catch { }\n }\n\n if (!ClientClass?.prototype) return;\n\n // Patch query() — the core execution method\n patchMethod(\n ClientClass.prototype,\n 'query',\n 'senzor.knex.client.query',\n (original) =>\n function patchedQuery(this: any, connection: any, queryObj: any) {\n // queryObj contains { sql, bindings, method, options, ... }\n const sql = queryObj?.sql;\n const method = queryObj?.method || 'raw';\n const operation = getSqlOperation(sql) || method.toUpperCase();\n const dbSystem = getDbSystem(this);\n const tableName = extractTableName(sql);\n\n const span = startCapturedSpan(\n `Knex ${operation}`,\n 'db',\n {\n 'db.system.name': dbSystem,\n 'db.operation.name': operation,\n 'db.query.text': normalizeSql(sql, options),\n 'db.collection.name': tableName,\n 'knex.method': method,\n library: 'knex',\n },\n options\n );\n\n if (!span) return original.call(this, connection, queryObj);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, connection, queryObj);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n const rowCount = Array.isArray(value)\n ? value.length\n : value?.rowCount ?? value?.affectedRows;\n\n span.end(0, {\n 'db.response.row_count': rowCount,\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n 'db.error.code': error?.code,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n 'db.error.code': error?.code,\n });\n throw error;\n }\n });\n }\n );\n\n // Patch _stream() — for streaming queries\n if (typeof ClientClass.prototype._stream === 'function') {\n patchMethod(\n ClientClass.prototype,\n '_stream',\n 'senzor.knex.client._stream',\n (original) =>\n function patchedStream(this: any, connection: any, queryObj: any, stream: any, streamOptions: any) {\n const sql = queryObj?.sql;\n const operation = getSqlOperation(sql) || 'STREAM';\n const dbSystem = getDbSystem(this);\n\n const span = startCapturedSpan(\n `Knex STREAM ${operation}`,\n 'db',\n {\n 'db.system.name': dbSystem,\n 'db.operation.name': `STREAM_${operation}`,\n 'db.query.text': normalizeSql(sql, options),\n 'knex.method': 'stream',\n library: 'knex',\n },\n options\n );\n\n if (!span) return original.call(this, connection, queryObj, stream, streamOptions);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, connection, queryObj, stream, streamOptions);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Factory wrapping — ensure clients created via knex() get patched\n// ---------------------------------------------------------------------------\n\nconst patchKnexFactory = (knexModule: any, options?: SenzorOptions) => {\n if (typeof knexModule !== 'function') return;\n\n // Knex's default export is the factory function\n // We can't replace the module export, but Client.prototype is shared\n // across all instances, so patching the prototype is sufficient.\n\n // Also try to patch via the factory's client property\n if (knexModule.Client?.prototype) {\n patchKnexClient(knexModule, options);\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentKnex = (options?: SenzorOptions) => {\n hookRequire('knex', (exports: any) => {\n patchKnexFactory(exports, options);\n patchKnexClient(exports, options);\n\n // Handle default exports\n if (exports?.default) {\n patchKnexFactory(exports.default, options);\n patchKnexClient(exports.default, options);\n }\n });\n\n // Also try the internal client module directly\n hookRequire('knex/lib/client', (exports: any) => {\n if (exports?.prototype) {\n patchKnexClient({ Client: exports }, options);\n }\n });\n};\n","import { getSqlOperation, normalizeSql } from '../core/sanitizer';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Tedious (SQL Server / MSSQL) Instrumentation\n//\n// Instruments the `tedious` package — the primary pure-JS driver for\n// Microsoft SQL Server used by node-mssql, Knex (mssql dialect),\n// TypeORM, Sequelize, and Prisma (sqlserver provider).\n//\n// Patches Connection.prototype methods:\n// - execSql() — standard parameterized queries\n// - execSqlBatch() — raw SQL batch execution\n// - execBulkLoad() — bulk insert operations\n// - callProcedure() — stored procedure calls\n// - prepare() — prepared statement creation\n// - execute() — prepared statement execution\n//\n// Also instruments `mssql` (node-mssql) — the popular high-level wrapper\n// around tedious — by patching Request.prototype.query/execute/batch.\n//\n// Captured attributes (OTel semantic conventions):\n// - db.system.name: 'mssql'\n// - db.operation.name: operation type\n// - db.query.text: normalized SQL\n// - db.namespace: database name\n// - server.address: SQL Server hostname\n// - server.port: SQL Server port\n// ---------------------------------------------------------------------------\n\n/** Extract connection metadata from a tedious Connection instance. */\nconst getConnectionMeta = (connection: any): Record<string, any> => {\n const config = connection?.config;\n if (!config) return {};\n\n const meta: Record<string, any> = {\n 'db.system.name': 'mssql',\n };\n\n if (config.server) meta['server.address'] = config.server;\n if (config.options?.port) meta['server.port'] = config.options.port;\n if (config.options?.database) meta['db.namespace'] = config.options.database;\n\n return meta;\n};\n\n// ---------------------------------------------------------------------------\n// Connection method patching\n// ---------------------------------------------------------------------------\n\nconst patchTediousConnection = (tedious: any, options?: SenzorOptions) => {\n const Connection = tedious?.Connection;\n if (!Connection?.prototype) return;\n\n const proto = Connection.prototype;\n\n // --- execSql(request) ---\n patchMethod(\n proto,\n 'execSql',\n 'senzor.tedious.connection.execSql',\n (original) =>\n function patchedExecSql(this: any, request: any) {\n const sql = request?.sqlTextOrProcedure;\n const operation = getSqlOperation(sql) || 'QUERY';\n const connMeta = getConnectionMeta(this);\n\n const span = startCapturedSpan(\n `MSSQL ${operation}`,\n 'db',\n {\n ...connMeta,\n 'db.operation.name': operation,\n 'db.query.text': normalizeSql(sql, options),\n 'tedious.method': 'execSql',\n library: 'tedious',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n wrapTediousRequest(request, span);\n return original.call(this, request);\n });\n }\n );\n\n // --- execSqlBatch(request) ---\n patchMethod(\n proto,\n 'execSqlBatch',\n 'senzor.tedious.connection.execSqlBatch',\n (original) =>\n function patchedExecSqlBatch(this: any, request: any) {\n const sql = request?.sqlTextOrProcedure;\n const operation = getSqlOperation(sql) || 'BATCH';\n const connMeta = getConnectionMeta(this);\n\n const span = startCapturedSpan(\n `MSSQL BATCH ${operation}`,\n 'db',\n {\n ...connMeta,\n 'db.operation.name': `BATCH_${operation}`,\n 'db.query.text': normalizeSql(sql, options),\n 'tedious.method': 'execSqlBatch',\n library: 'tedious',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n wrapTediousRequest(request, span);\n return original.call(this, request);\n });\n }\n );\n\n // --- callProcedure(request) ---\n patchMethod(\n proto,\n 'callProcedure',\n 'senzor.tedious.connection.callProcedure',\n (original) =>\n function patchedCallProcedure(this: any, request: any) {\n const procName = request?.sqlTextOrProcedure || 'unknown';\n const connMeta = getConnectionMeta(this);\n\n const span = startCapturedSpan(\n `MSSQL CALL ${procName}`,\n 'db',\n {\n ...connMeta,\n 'db.operation.name': 'CALL',\n 'db.query.text': procName,\n 'db.collection.name': procName,\n 'tedious.method': 'callProcedure',\n library: 'tedious',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n wrapTediousRequest(request, span);\n return original.call(this, request);\n });\n }\n );\n\n // --- execBulkLoad(bulkLoad, rows, callback) ---\n patchMethod(\n proto,\n 'execBulkLoad',\n 'senzor.tedious.connection.execBulkLoad',\n (original) =>\n function patchedExecBulkLoad(this: any, bulkLoad: any, ...args: any[]) {\n const tableName = bulkLoad?.table || 'unknown';\n const connMeta = getConnectionMeta(this);\n\n const span = startCapturedSpan(\n `MSSQL BULK INSERT ${tableName}`,\n 'db',\n {\n ...connMeta,\n 'db.operation.name': 'BULK_INSERT',\n 'db.collection.name': tableName,\n 'tedious.method': 'execBulkLoad',\n library: 'tedious',\n },\n options\n );\n\n if (!span) return original.call(this, bulkLoad, ...args);\n\n return runWithCapturedSpan(span, () => {\n // Wrap the bulkLoad callback\n if (bulkLoad && typeof bulkLoad.callback === 'function') {\n const originalCallback = bulkLoad.callback;\n bulkLoad.callback = function (err: any, rowCount: any) {\n if (err) {\n span.end(500, {\n 'error.message': err.message,\n 'error.type': err.name || 'Error',\n });\n } else {\n span.end(0, { 'db.response.row_count': rowCount });\n }\n return originalCallback.call(this, err, rowCount);\n };\n } else {\n // If no callback on bulkLoad, try wrapping the last arg\n const lastIdx = args.length - 1;\n if (lastIdx >= 0 && typeof args[lastIdx] === 'function') {\n const cb = args[lastIdx];\n args[lastIdx] = function (err: any, rowCount: any) {\n if (err) {\n span.end(500, { 'error.message': err.message });\n } else {\n span.end(0, { 'db.response.row_count': rowCount });\n }\n return cb.apply(this, arguments);\n };\n } else {\n span.end(0);\n }\n }\n\n return original.call(this, bulkLoad, ...args);\n });\n }\n );\n\n // --- prepare(request) ---\n if (typeof proto.prepare === 'function') {\n patchMethod(\n proto,\n 'prepare',\n 'senzor.tedious.connection.prepare',\n (original) =>\n function patchedPrepare(this: any, request: any) {\n const sql = request?.sqlTextOrProcedure;\n const connMeta = getConnectionMeta(this);\n\n const span = startCapturedSpan(\n `MSSQL PREPARE`,\n 'db',\n {\n ...connMeta,\n 'db.operation.name': 'PREPARE',\n 'db.query.text': normalizeSql(sql, options),\n 'tedious.method': 'prepare',\n library: 'tedious',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n wrapTediousRequest(request, span);\n return original.call(this, request);\n });\n }\n );\n }\n\n // --- execute(request, parameters) ---\n if (typeof proto.execute === 'function') {\n patchMethod(\n proto,\n 'execute',\n 'senzor.tedious.connection.execute',\n (original) =>\n function patchedExecute(this: any, request: any, parameters: any) {\n const sql = request?.sqlTextOrProcedure;\n const operation = getSqlOperation(sql) || 'EXECUTE';\n const connMeta = getConnectionMeta(this);\n\n const span = startCapturedSpan(\n `MSSQL EXECUTE ${operation}`,\n 'db',\n {\n ...connMeta,\n 'db.operation.name': `EXECUTE_${operation}`,\n 'db.query.text': normalizeSql(sql, options),\n 'tedious.method': 'execute',\n library: 'tedious',\n },\n options\n );\n\n if (!span) return original.call(this, request, parameters);\n\n return runWithCapturedSpan(span, () => {\n wrapTediousRequest(request, span);\n return original.call(this, request, parameters);\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Tedious Request callback wrapping\n// ---------------------------------------------------------------------------\n\n/** Wrap a tedious Request's completion callback to end the span. */\nconst wrapTediousRequest = (request: any, span: any) => {\n if (!request || !span) return;\n\n // Tedious Request uses an event-based completion model\n // The 'requestCompleted' callback is the final callback passed to the Request constructor\n if (typeof request.callback === 'function') {\n const originalCallback = request.callback;\n request.callback = function (err: any, rowCount: any, rows: any) {\n if (err) {\n span.end(500, {\n 'error.message': err.message,\n 'error.type': err.name || 'RequestError',\n 'db.error.code': err.code,\n });\n } else {\n span.end(0, {\n 'db.response.row_count': rowCount,\n });\n }\n return originalCallback.call(this, err, rowCount, rows);\n };\n return;\n }\n\n // Fallback: listen for events\n if (typeof request.on === 'function') {\n let ended = false;\n request.on('requestCompleted', () => {\n if (!ended) { ended = true; span.end(0); }\n });\n request.on('error', (err: any) => {\n if (!ended) {\n ended = true;\n span.end(500, { 'error.message': err?.message });\n }\n });\n }\n};\n\n// ---------------------------------------------------------------------------\n// node-mssql (mssql) wrapper patching\n// ---------------------------------------------------------------------------\n\nconst patchMssql = (mssql: any, options?: SenzorOptions) => {\n // mssql exports Request, ConnectionPool, etc.\n const RequestClass = mssql?.Request;\n if (!RequestClass?.prototype) return;\n\n const proto = RequestClass.prototype;\n\n // Patch Request.prototype.query(sql)\n patchMethod(\n proto,\n 'query',\n 'senzor.mssql.request.query',\n (original) =>\n function patchedMssqlQuery(this: any, sql: string) {\n const operation = getSqlOperation(sql) || 'QUERY';\n\n const span = startCapturedSpan(\n `MSSQL ${operation}`,\n 'db',\n {\n 'db.system.name': 'mssql',\n 'db.operation.name': operation,\n 'db.query.text': normalizeSql(sql, options),\n library: 'mssql',\n },\n options\n );\n\n if (!span) return original.call(this, sql);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, sql);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, {\n 'db.response.row_count': value?.recordset?.length ?? value?.rowsAffected?.[0],\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n 'db.error.code': error?.code,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // Patch Request.prototype.execute(procedure)\n patchMethod(\n proto,\n 'execute',\n 'senzor.mssql.request.execute',\n (original) =>\n function patchedMssqlExecute(this: any, procedure: string) {\n const span = startCapturedSpan(\n `MSSQL CALL ${procedure}`,\n 'db',\n {\n 'db.system.name': 'mssql',\n 'db.operation.name': 'CALL',\n 'db.query.text': procedure,\n 'db.collection.name': procedure,\n library: 'mssql',\n },\n options\n );\n\n if (!span) return original.call(this, procedure);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, procedure);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // Patch Request.prototype.batch(sql)\n if (typeof proto.batch === 'function') {\n patchMethod(\n proto,\n 'batch',\n 'senzor.mssql.request.batch',\n (original) =>\n function patchedMssqlBatch(this: any, sql: string) {\n const operation = getSqlOperation(sql) || 'BATCH';\n\n const span = startCapturedSpan(\n `MSSQL BATCH ${operation}`,\n 'db',\n {\n 'db.system.name': 'mssql',\n 'db.operation.name': `BATCH_${operation}`,\n 'db.query.text': normalizeSql(sql, options),\n library: 'mssql',\n },\n options\n );\n\n if (!span) return original.call(this, sql);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, sql);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentTedious = (options?: SenzorOptions) => {\n hookRequire('tedious', (exports: any) => {\n patchTediousConnection(exports, options);\n });\n\n hookRequire('mssql', (exports: any) => {\n patchMssql(exports, options);\n });\n};\n","import { getSqlOperation, normalizeSql } from '../core/sanitizer';\nimport { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Cassandra (cassandra-driver) Instrumentation\n//\n// Instruments the DataStax cassandra-driver for Apache Cassandra / ScyllaDB.\n//\n// Patches Client.prototype methods:\n// - execute() — single query execution (parameterized)\n// - batch() — batch query execution (multiple statements)\n// - eachRow() — streaming row-by-row query\n// - stream() — readable stream interface\n//\n// CQL (Cassandra Query Language) uses similar syntax to SQL for basic\n// operations, so we reuse SQL extraction/normalization utilities.\n//\n// Captured attributes (OTel semantic conventions):\n// - db.system.name: 'cassandra'\n// - db.operation.name: SELECT, INSERT, UPDATE, DELETE, BATCH, etc.\n// - db.query.text: normalized CQL\n// - db.cassandra.consistency: consistency level used\n// - db.cassandra.coordinator.id: coordinator node address\n// - db.cassandra.page_size: page size for paged queries\n// - db.namespace: keyspace\n// - server.address: contact point\n// ---------------------------------------------------------------------------\n\n/** Map Cassandra consistency level numbers to names. */\nconst CONSISTENCY_NAMES: Record<number, string> = {\n 0: 'any',\n 1: 'one',\n 2: 'two',\n 3: 'three',\n 4: 'quorum',\n 5: 'all',\n 6: 'localQuorum',\n 7: 'eachQuorum',\n 8: 'serial',\n 9: 'localSerial',\n 10: 'localOne',\n};\n\nconst getConsistencyName = (level: any): string | undefined => {\n if (typeof level === 'string') return level;\n if (typeof level === 'number') return CONSISTENCY_NAMES[level];\n return undefined;\n};\n\n/** Extract connection metadata from a Client instance. */\nconst getClientMeta = (client: any): Record<string, any> => {\n const meta: Record<string, any> = {\n 'db.system.name': 'cassandra',\n };\n\n try {\n const options = client?.options;\n if (options?.keyspace) meta['db.namespace'] = options.keyspace;\n if (options?.contactPoints?.[0]) meta['server.address'] = options.contactPoints[0];\n if (options?.protocolOptions?.port) meta['server.port'] = options.protocolOptions.port;\n if (options?.localDataCenter) meta['db.cassandra.local_datacenter'] = options.localDataCenter;\n } catch { }\n\n return meta;\n};\n\n/** Extract table name from CQL. */\nconst extractCqlTable = (cql: string | undefined): string | undefined => {\n if (!cql) return undefined;\n const match = cql.match(/(?:FROM|INTO|UPDATE)\\s+(?:(\\w+)\\.)?(\\w+)/i);\n return match?.[2] || undefined;\n};\n\n// ---------------------------------------------------------------------------\n// Client.prototype patching\n// ---------------------------------------------------------------------------\n\nconst patchCassandraClient = (cassandra: any, options?: SenzorOptions) => {\n const Client = cassandra?.Client;\n if (!Client?.prototype) return;\n\n const proto = Client.prototype;\n\n // --- execute(query, params, queryOptions, callback) ---\n patchMethod(\n proto,\n 'execute',\n 'senzor.cassandra.client.execute',\n (original) =>\n function patchedExecute(this: any, query: string, ...args: any[]) {\n const operation = getSqlOperation(query) || 'QUERY';\n const clientMeta = getClientMeta(this);\n const tableName = extractCqlTable(query);\n\n // Extract query options (second or third arg depending on params)\n const queryOptions = args.find((a) => a && typeof a === 'object' && !Array.isArray(a) && typeof a !== 'function');\n const consistency = getConsistencyName(queryOptions?.consistency);\n const pageSize = queryOptions?.fetchSize;\n\n const span = startCapturedSpan(\n `Cassandra ${operation}`,\n 'db',\n {\n ...clientMeta,\n 'db.operation.name': operation,\n 'db.query.text': normalizeSql(query, options),\n 'db.collection.name': tableName,\n 'db.cassandra.consistency': consistency,\n 'db.cassandra.page_size': pageSize,\n library: 'cassandra-driver',\n },\n options\n );\n\n if (!span) return original.call(this, query, ...args);\n\n // Check if last arg is a callback\n const lastIdx = args.length - 1;\n const hasCallback = lastIdx >= 0 && typeof args[lastIdx] === 'function';\n\n if (hasCallback) {\n const cb = args[lastIdx];\n args[lastIdx] = function (err: any, result: any) {\n if (err) {\n span.end(500, {\n 'error.message': err.message,\n 'error.type': err.name || 'Error',\n 'db.error.code': err.code,\n });\n } else {\n span.end(0, {\n 'db.response.row_count': result?.rowLength ?? result?.rows?.length,\n 'db.cassandra.coordinator.id': result?.info?.queriedHost,\n });\n }\n return cb.call(this, err, result);\n };\n\n return runWithCapturedSpan(span, () => original.call(this, query, ...args));\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, query, ...args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, {\n 'db.response.row_count': value?.rowLength ?? value?.rows?.length,\n 'db.cassandra.coordinator.id': value?.info?.queriedHost,\n });\n return value;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n 'db.error.code': error?.code,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // --- batch(queries, queryOptions, callback) ---\n patchMethod(\n proto,\n 'batch',\n 'senzor.cassandra.client.batch',\n (original) =>\n function patchedBatch(this: any, queries: any[], ...args: any[]) {\n const batchSize = Array.isArray(queries) ? queries.length : 0;\n const clientMeta = getClientMeta(this);\n\n const queryOptions = args.find((a) => a && typeof a === 'object' && !Array.isArray(a) && typeof a !== 'function');\n const consistency = getConsistencyName(queryOptions?.consistency);\n\n const span = startCapturedSpan(\n `Cassandra BATCH (${batchSize} queries)`,\n 'db',\n {\n ...clientMeta,\n 'db.operation.name': 'BATCH',\n 'db.cassandra.batch_size': batchSize,\n 'db.cassandra.consistency': consistency,\n library: 'cassandra-driver',\n },\n options\n );\n\n if (!span) return original.call(this, queries, ...args);\n\n const lastIdx = args.length - 1;\n const hasCallback = lastIdx >= 0 && typeof args[lastIdx] === 'function';\n\n if (hasCallback) {\n const cb = args[lastIdx];\n args[lastIdx] = function (err: any, result: any) {\n if (err) {\n span.end(500, { 'error.message': err.message });\n } else {\n span.end(0);\n }\n return cb.call(this, err, result);\n };\n\n return runWithCapturedSpan(span, () => original.call(this, queries, ...args));\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, queries, ...args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // --- eachRow(query, params, queryOptions, rowCallback, finalCallback) ---\n patchMethod(\n proto,\n 'eachRow',\n 'senzor.cassandra.client.eachRow',\n (original) =>\n function patchedEachRow(this: any, query: string, ...args: any[]) {\n const operation = getSqlOperation(query) || 'SELECT';\n const clientMeta = getClientMeta(this);\n const tableName = extractCqlTable(query);\n\n const span = startCapturedSpan(\n `Cassandra EACHROW ${operation}`,\n 'db',\n {\n ...clientMeta,\n 'db.operation.name': `EACHROW_${operation}`,\n 'db.query.text': normalizeSql(query, options),\n 'db.collection.name': tableName,\n library: 'cassandra-driver',\n },\n options\n );\n\n if (!span) return original.call(this, query, ...args);\n\n // The last function arg is the final callback (completion)\n // The second-to-last function arg is the row callback\n let rowCount = 0;\n\n // Find and wrap callbacks\n for (let i = args.length - 1; i >= 0; i--) {\n if (typeof args[i] === 'function') {\n // This is the final callback (errorBack)\n const finalCb = args[i];\n args[i] = function (err: any, result: any) {\n if (err) {\n span.end(500, { 'error.message': err.message });\n } else {\n span.end(0, { 'db.response.row_count': rowCount });\n }\n return finalCb.call(this, err, result);\n };\n\n // Find the row callback (previous function arg)\n for (let j = i - 1; j >= 0; j--) {\n if (typeof args[j] === 'function') {\n const rowCb = args[j];\n args[j] = function (n: any, row: any) {\n rowCount++;\n return rowCb.call(this, n, row);\n };\n break;\n }\n }\n break;\n }\n }\n\n return runWithCapturedSpan(span, () => original.call(this, query, ...args));\n }\n );\n\n // --- stream(query, params, queryOptions) ---\n if (typeof proto.stream === 'function') {\n patchMethod(\n proto,\n 'stream',\n 'senzor.cassandra.client.stream',\n (original) =>\n function patchedStream(this: any, query: string, ...args: any[]) {\n const operation = getSqlOperation(query) || 'SELECT';\n const clientMeta = getClientMeta(this);\n\n const span = startCapturedSpan(\n `Cassandra STREAM ${operation}`,\n 'db',\n {\n ...clientMeta,\n 'db.operation.name': `STREAM_${operation}`,\n 'db.query.text': normalizeSql(query, options),\n library: 'cassandra-driver',\n },\n options\n );\n\n if (!span) return original.call(this, query, ...args);\n\n return runWithCapturedSpan(span, () => {\n const stream = original.call(this, query, ...args);\n\n if (stream && typeof stream.on === 'function') {\n let rowCount = 0;\n stream.on('data', () => { rowCount++; });\n stream.on('end', () => {\n span.end(0, { 'db.response.row_count': rowCount });\n });\n stream.on('error', (err: any) => {\n span.end(500, { 'error.message': err?.message });\n });\n } else {\n span.end(0);\n }\n\n return stream;\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentCassandra = (options?: SenzorOptions) => {\n hookRequire('cassandra-driver', (exports: any) => {\n patchCassandraClient(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Memcached Instrumentation\n//\n// Instruments the `memcached` npm package (the most popular pure-JS\n// Memcached client for Node.js, used by production deployments).\n//\n// Patches Memcached.prototype command methods:\n// - get(), gets(), getMulti() — read operations\n// - set(), add(), replace(), cas() — write operations\n// - append(), prepend() — mutation operations\n// - incr(), decr() — counter operations\n// - del() / delete() — delete operations\n// - touch() — TTL refresh\n// - stats(), version(), items() — admin/info operations\n// - flush() — cache flush\n//\n// All memcached operations are callback-based. The callback is always\n// the last argument: fn(err, result).\n//\n// Captured attributes (OTel semantic conventions):\n// - db.system.name: 'memcached'\n// - db.operation.name: GET, SET, DELETE, etc.\n// - db.memcached.key: cache key (if single key)\n// - db.memcached.key_count: number of keys (for multi-key ops)\n// - server.address: memcached server(s)\n// ---------------------------------------------------------------------------\n\n/** Commands to instrument, grouped by signature pattern. */\nconst KEY_VALUE_COMMANDS = ['set', 'add', 'replace', 'append', 'prepend'] as const;\nconst KEY_ONLY_COMMANDS = ['get', 'gets', 'del', 'delete', 'touch'] as const;\nconst KEY_NUMBER_COMMANDS = ['incr', 'decr'] as const;\nconst CAS_COMMAND = ['cas'] as const;\nconst MULTI_KEY_COMMANDS = ['getMulti'] as const;\nconst NO_KEY_COMMANDS = ['stats', 'version', 'items', 'flush'] as const;\n\n/** Get server address string from a Memcached instance. */\nconst getServerAddress = (client: any): string | undefined => {\n try {\n const servers = client?.servers;\n if (Array.isArray(servers) && servers.length > 0) {\n return servers.length === 1 ? servers[0] : `${servers[0]} (+${servers.length - 1})`;\n }\n return undefined;\n } catch {\n return undefined;\n }\n};\n\n// ---------------------------------------------------------------------------\n// Generic command wrapper\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap a callback-based memcached command.\n * The callback is always the last argument in memcached commands.\n */\nconst wrapCommand = (\n proto: any,\n commandName: string,\n getSpanMeta: (args: any[]) => Record<string, any>,\n options?: SenzorOptions\n) => {\n if (typeof proto[commandName] !== 'function') return;\n\n patchMethod(\n proto,\n commandName,\n `senzor.memcached.${commandName}`,\n (original) =>\n function patchedCommand(this: any, ...args: any[]) {\n const operation = commandName.toUpperCase();\n const serverAddress = getServerAddress(this);\n const extraMeta = getSpanMeta(args);\n\n const span = startCapturedSpan(\n `Memcached ${operation}`,\n 'db',\n {\n 'db.system.name': 'memcached',\n 'db.operation.name': operation,\n 'server.address': serverAddress,\n library: 'memcached',\n ...extraMeta,\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n // Wrap the callback (always last argument)\n const callbackIndex = args.length - 1;\n if (callbackIndex >= 0 && typeof args[callbackIndex] === 'function') {\n const originalCb = args[callbackIndex];\n args[callbackIndex] = function (err: any, ...results: any[]) {\n if (err) {\n span.end(500, {\n 'error.message': typeof err === 'string' ? err : err?.message,\n 'error.type': err?.name || 'MemcachedError',\n });\n } else {\n span.end(0);\n }\n return originalCb.call(this, err, ...results);\n };\n } else {\n // No callback — end span immediately\n span.end(0);\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n return original.apply(this, args);\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Memcached prototype patching\n// ---------------------------------------------------------------------------\n\nconst patchMemcachedClient = (Memcached: any, options?: SenzorOptions) => {\n const proto = Memcached?.prototype;\n if (!proto) return;\n\n // key-value commands: command(key, value, lifetime, callback)\n for (const cmd of KEY_VALUE_COMMANDS) {\n wrapCommand(proto, cmd, (args) => ({\n 'db.memcached.key': typeof args[0] === 'string' ? args[0] : undefined,\n }), options);\n }\n\n // key-only commands: command(key, callback) or command(key, ttl, callback)\n for (const cmd of KEY_ONLY_COMMANDS) {\n wrapCommand(proto, cmd, (args) => ({\n 'db.memcached.key': typeof args[0] === 'string' ? args[0] : undefined,\n }), options);\n }\n\n // key-number commands: command(key, amount, callback)\n for (const cmd of KEY_NUMBER_COMMANDS) {\n wrapCommand(proto, cmd, (args) => ({\n 'db.memcached.key': typeof args[0] === 'string' ? args[0] : undefined,\n }), options);\n }\n\n // cas: cas(key, value, cas, lifetime, callback)\n for (const cmd of CAS_COMMAND) {\n wrapCommand(proto, cmd, (args) => ({\n 'db.memcached.key': typeof args[0] === 'string' ? args[0] : undefined,\n }), options);\n }\n\n // multi-key commands: command(keys, callback) where keys is string[]\n for (const cmd of MULTI_KEY_COMMANDS) {\n wrapCommand(proto, cmd, (args) => ({\n 'db.memcached.key_count': Array.isArray(args[0]) ? args[0].length : undefined,\n }), options);\n }\n\n // no-key commands: command(callback)\n for (const cmd of NO_KEY_COMMANDS) {\n wrapCommand(proto, cmd, () => ({}), options);\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentMemcached = (options?: SenzorOptions) => {\n hookRequire('memcached', (exports: any) => {\n // memcached exports the constructor directly\n patchMemcachedClient(exports, options);\n\n // Handle default export\n if (exports?.default?.prototype) {\n patchMemcachedClient(exports.default, options);\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// generic-pool Instrumentation\n//\n// Instruments the `generic-pool` package — the de-facto connection/resource\n// pooling library used by many database drivers (pg, mysql2, tedious),\n// cache clients, and custom resource managers in Node.js.\n//\n// Patches Pool.prototype methods:\n// - acquire() — resource acquisition from the pool\n// - release() — resource return to the pool\n// - destroy() — resource destruction\n// - drain() — pool draining (graceful shutdown)\n//\n// These spans measure pool health and contention:\n// - How long acquire() takes reveals pool exhaustion\n// - Release/destroy patterns show resource lifecycle\n//\n// Captured attributes:\n// - pool.type: 'generic-pool'\n// - pool.operation: acquire, release, destroy, drain\n// - pool.size: current pool size\n// - pool.available: available resources\n// - pool.pending: pending acquisition requests\n// - pool.max: maximum pool size\n// - pool.min: minimum pool size\n// ---------------------------------------------------------------------------\n\n/** Extract pool stats from a generic-pool Pool instance. */\nconst getPoolStats = (pool: any): Record<string, any> => {\n const stats: Record<string, any> = {\n 'pool.type': 'generic-pool',\n };\n\n try {\n if (typeof pool.size !== 'undefined') stats['pool.size'] = pool.size;\n if (typeof pool.available !== 'undefined') stats['pool.available'] = pool.available;\n if (typeof pool.pending !== 'undefined') stats['pool.pending'] = pool.pending;\n if (typeof pool.borrowed !== 'undefined') stats['pool.borrowed'] = pool.borrowed;\n if (pool.max !== undefined) stats['pool.max'] = pool.max;\n if (pool.min !== undefined) stats['pool.min'] = pool.min;\n\n // Try _config for older versions\n if (pool._config) {\n if (stats['pool.max'] === undefined && pool._config.max) stats['pool.max'] = pool._config.max;\n if (stats['pool.min'] === undefined && pool._config.min) stats['pool.min'] = pool._config.min;\n }\n } catch { }\n\n return stats;\n};\n\n// ---------------------------------------------------------------------------\n// Pool method patching\n// ---------------------------------------------------------------------------\n\nconst patchPool = (poolProto: any, options?: SenzorOptions) => {\n if (!poolProto) return;\n\n // --- acquire(priority?) → Promise<resource> ---\n patchMethod(\n poolProto,\n 'acquire',\n 'senzor.generic-pool.pool.acquire',\n (original) =>\n function patchedAcquire(this: any, ...args: any[]) {\n const poolStats = getPoolStats(this);\n\n const span = startCapturedSpan(\n 'Pool acquire',\n 'custom',\n {\n ...poolStats,\n 'pool.operation': 'acquire',\n library: 'generic-pool',\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (resource: any) => {\n // Capture pool state after acquisition\n const postStats = getPoolStats(this);\n span.end(0, {\n 'pool.size_after': postStats['pool.size'],\n 'pool.available_after': postStats['pool.available'],\n 'pool.pending_after': postStats['pool.pending'],\n });\n return resource;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'PoolError',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n );\n\n // --- release(resource) → Promise<void> ---\n patchMethod(\n poolProto,\n 'release',\n 'senzor.generic-pool.pool.release',\n (original) =>\n function patchedRelease(this: any, resource: any) {\n const poolStats = getPoolStats(this);\n\n const span = startCapturedSpan(\n 'Pool release',\n 'custom',\n {\n ...poolStats,\n 'pool.operation': 'release',\n library: 'generic-pool',\n },\n options\n );\n\n if (!span) return original.call(this, resource);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, resource);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // --- destroy(resource) → Promise<void> ---\n patchMethod(\n poolProto,\n 'destroy',\n 'senzor.generic-pool.pool.destroy',\n (original) =>\n function patchedDestroy(this: any, resource: any) {\n const poolStats = getPoolStats(this);\n\n const span = startCapturedSpan(\n 'Pool destroy',\n 'custom',\n {\n ...poolStats,\n 'pool.operation': 'destroy',\n library: 'generic-pool',\n },\n options\n );\n\n if (!span) return original.call(this, resource);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, resource);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // --- drain() → Promise<void> ---\n if (typeof poolProto.drain === 'function') {\n patchMethod(\n poolProto,\n 'drain',\n 'senzor.generic-pool.pool.drain',\n (original) =>\n function patchedDrain(this: any) {\n const poolStats = getPoolStats(this);\n\n const span = startCapturedSpan(\n 'Pool drain',\n 'custom',\n {\n ...poolStats,\n 'pool.operation': 'drain',\n library: 'generic-pool',\n },\n options\n );\n\n if (!span) return original.call(this);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// createPool factory wrapping\n// ---------------------------------------------------------------------------\n\nconst patchCreatePool = (genericPool: any, options?: SenzorOptions) => {\n if (typeof genericPool?.createPool !== 'function') return;\n\n patchMethod(\n genericPool,\n 'createPool',\n 'senzor.generic-pool.createPool',\n (original) =>\n function patchedCreatePool(this: any, factory: any, config: any) {\n const pool = original.call(this, factory, config);\n\n if (pool && !pool.__senzorPatched) {\n const proto = Object.getPrototypeOf(pool);\n if (proto && !proto.__senzorPatched) {\n patchPool(proto, options);\n proto.__senzorPatched = true;\n }\n pool.__senzorPatched = true;\n }\n\n return pool;\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentGenericPool = (options?: SenzorOptions) => {\n hookRequire('generic-pool', (exports: any) => {\n // Patch the createPool factory\n patchCreatePool(exports, options);\n\n // Also try to find the Pool prototype directly\n if (exports?.Pool?.prototype) {\n patchPool(exports.Pool.prototype, options);\n }\n\n // Handle default export\n if (exports?.default) {\n patchCreatePool(exports.default, options);\n if (exports.default.Pool?.prototype) {\n patchPool(exports.default.Pool.prototype, options);\n }\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Restify Instrumentation\n//\n// Instruments the `restify` HTTP framework at the server layer:\n// - Server route registration methods (get, post, put, del, patch, head, opts)\n// to wrap route handlers and generate spans per request.\n// - Server.prototype.use() to optionally capture middleware spans.\n//\n// Restify handler signature: (req, res, next) — same as Express/Connect.\n// Route path is available at registration time via the route config.\n//\n// Captured attributes:\n// - http.route: registered route path\n// - http.method: HTTP method\n// - restify.type: 'route_handler' | 'middleware'\n// - restify.version: route version (if versioned routes)\n// - framework: 'restify'\n// ---------------------------------------------------------------------------\n\nconst HTTP_METHODS = ['get', 'post', 'put', 'del', 'patch', 'head', 'opts'] as const;\n\n/** Normalize restify method name to HTTP method. */\nconst METHOD_MAP: Record<string, string> = {\n get: 'GET', post: 'POST', put: 'PUT', del: 'DELETE',\n patch: 'PATCH', head: 'HEAD', opts: 'OPTIONS',\n};\n\n// ---------------------------------------------------------------------------\n// Handler wrapping\n// ---------------------------------------------------------------------------\n\nconst wrapHandler = (\n handler: Function,\n method: string,\n path: string,\n type: 'route_handler' | 'middleware',\n options?: SenzorOptions\n): Function => {\n if (typeof handler !== 'function') return handler;\n if ((handler as any).__senzorWrapped) return handler;\n\n const wrapped = function wrappedRestifyHandler(this: any, req: any, res: any, next: any) {\n const httpMethod = METHOD_MAP[method] || method.toUpperCase();\n const routePath = path || req?.route?.path || req?.getPath?.() || req?.url?.split('?')[0] || '/';\n\n const spanName = type === 'middleware'\n ? `Restify middleware ${handler.name || 'anonymous'}`\n : `Restify ${httpMethod} ${routePath}`;\n\n const span = startCapturedSpan(\n spanName,\n 'function',\n {\n 'restify.type': type,\n 'http.route': routePath,\n 'http.method': httpMethod,\n framework: 'restify',\n },\n options\n );\n\n if (!span) return handler.call(this, req, res, next);\n\n return runWithCapturedSpan(span, () => {\n // Wrap next() to end span when handler passes control\n const wrappedNext = function (...args: any[]) {\n const hasError = args.length > 0 && args[0] instanceof Error;\n if (hasError) {\n const err = args[0];\n span.end(err?.statusCode || 500, {\n 'error.message': err.message,\n 'error.type': err.name || 'Error',\n });\n } else {\n span.end(0);\n }\n return next?.(...args);\n };\n\n try {\n const result = handler.call(this, req, res, wrappedNext);\n\n // Handle async handlers returning promises\n if (result && typeof result.then === 'function') {\n return result.then(\n (val: any) => val,\n (error: any) => {\n span.end(error?.statusCode || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n );\n }\n\n return result;\n } catch (error: any) {\n span.end(error?.statusCode || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n };\n\n (wrapped as any).__senzorWrapped = true;\n return wrapped;\n};\n\n// ---------------------------------------------------------------------------\n// Server route method patching\n// ---------------------------------------------------------------------------\n\nconst patchRestifyServer = (restify: any, options?: SenzorOptions) => {\n // restify.createServer() returns a Server instance\n // We need to patch Server.prototype\n\n let ServerProto: any;\n\n // Try to get Server prototype from a temp server\n try {\n const tempServer = restify.createServer({ name: '__senzor_probe' });\n ServerProto = Object.getPrototypeOf(tempServer);\n // Close the temp server immediately\n try { tempServer.close(); } catch { }\n } catch { }\n\n // Fallback: try restify.Server\n if (!ServerProto) {\n ServerProto = restify?.Server?.prototype;\n }\n\n if (!ServerProto) return;\n\n // Patch route registration methods\n for (const method of HTTP_METHODS) {\n if (typeof ServerProto[method] !== 'function') continue;\n\n patchMethod(\n ServerProto,\n method,\n `senzor.restify.server.${method}`,\n (original) =>\n function patchedRouteMethod(this: any, ...args: any[]) {\n // Restify route methods accept:\n // server.get(path, handler1, handler2, ...)\n // server.get({ path, version }, handler1, handler2, ...)\n // server.get(path, [handler1, handler2])\n\n let path = '/';\n\n // Extract path from first argument\n if (typeof args[0] === 'string') {\n path = args[0];\n } else if (args[0] && typeof args[0] === 'object') {\n path = args[0].path || args[0].url || '/';\n }\n\n // Wrap all handler arguments\n for (let i = 0; i < args.length; i++) {\n if (typeof args[i] === 'function') {\n args[i] = wrapHandler(args[i], method, path, 'route_handler', options);\n } else if (Array.isArray(args[i])) {\n args[i] = args[i].map((h: any) =>\n typeof h === 'function' ? wrapHandler(h, method, path, 'route_handler', options) : h\n );\n }\n }\n\n return original.apply(this, args);\n }\n );\n }\n\n // Patch use() for middleware spans (optional)\n if (options?.captureMiddlewareSpans !== false && typeof ServerProto.use === 'function') {\n patchMethod(\n ServerProto,\n 'use',\n 'senzor.restify.server.use',\n (original) =>\n function patchedUse(this: any, ...args: any[]) {\n for (let i = 0; i < args.length; i++) {\n if (typeof args[i] === 'function') {\n args[i] = wrapHandler(args[i], 'use', '*', 'middleware', options);\n } else if (Array.isArray(args[i])) {\n args[i] = args[i].map((h: any) =>\n typeof h === 'function' ? wrapHandler(h, 'use', '*', 'middleware', options) : h\n );\n }\n }\n return original.apply(this, args);\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentRestify = (options?: SenzorOptions) => {\n hookRequire('restify', (exports: any) => {\n patchRestifyServer(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Connect Instrumentation\n//\n// Instruments the `connect` middleware framework — the foundation that\n// Express was originally built on. Many production apps still use\n// Connect directly for lightweight HTTP services.\n//\n// Patches the connect app's use() method to wrap every middleware\n// function with a span capturing execution time and errors.\n//\n// Connect middleware signature: (req, res, next) or (err, req, res, next)\n//\n// Captured attributes:\n// - connect.type: 'middleware'\n// - connect.name: middleware function name\n// - connect.route: mount path (if provided)\n// - framework: 'connect'\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Middleware wrapping\n// ---------------------------------------------------------------------------\n\nconst wrapMiddleware = (\n fn: Function,\n route: string,\n options?: SenzorOptions\n): Function => {\n if (typeof fn !== 'function') return fn;\n if ((fn as any).__senzorWrapped) return fn;\n\n const middlewareName = fn.name || 'anonymous';\n const isErrorHandler = fn.length >= 4;\n\n let wrapped: Function;\n\n if (isErrorHandler) {\n // Error-handling middleware: (err, req, res, next)\n wrapped = function wrappedConnectErrorMiddleware(\n this: any, err: any, req: any, res: any, next: any\n ) {\n const span = startCapturedSpan(\n `Connect error ${middlewareName}`,\n 'function',\n {\n 'connect.type': 'error_middleware',\n 'connect.name': middlewareName,\n 'connect.route': route,\n framework: 'connect',\n },\n options\n );\n\n if (!span) return fn.call(this, err, req, res, next);\n\n return runWithCapturedSpan(span, () => {\n const wrappedNext = function (...args: any[]) {\n const hasError = args.length > 0 && args[0] instanceof Error;\n span.end(hasError ? 500 : 0, hasError ? { 'error.message': args[0].message } : {});\n return next?.(...args);\n };\n\n try {\n const result = fn.call(this, err, req, res, wrappedNext);\n if (result && typeof result.then === 'function') {\n return result.catch((error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n });\n }\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n };\n } else {\n // Standard middleware: (req, res, next)\n wrapped = function wrappedConnectMiddleware(\n this: any, req: any, res: any, next: any\n ) {\n const span = startCapturedSpan(\n `Connect ${middlewareName}`,\n 'function',\n {\n 'connect.type': 'middleware',\n 'connect.name': middlewareName,\n 'connect.route': route,\n 'http.route': route !== '/' ? route : undefined,\n framework: 'connect',\n },\n options\n );\n\n if (!span) return fn.call(this, req, res, next);\n\n return runWithCapturedSpan(span, () => {\n const wrappedNext = function (...args: any[]) {\n const hasError = args.length > 0 && args[0] instanceof Error;\n span.end(hasError ? 500 : 0, hasError ? { 'error.message': args[0].message } : {});\n return next?.(...args);\n };\n\n try {\n const result = fn.call(this, req, res, wrappedNext);\n if (result && typeof result.then === 'function') {\n return result.catch((error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n });\n }\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n };\n }\n\n // Preserve original function length for Connect's error handler detection\n Object.defineProperty(wrapped, 'length', { value: fn.length });\n (wrapped as any).__senzorWrapped = true;\n\n return wrapped;\n};\n\n// ---------------------------------------------------------------------------\n// app.use() patching\n// ---------------------------------------------------------------------------\n\nconst patchConnectApp = (connectModule: any, options?: SenzorOptions) => {\n if (typeof connectModule !== 'function') return;\n\n // connect() returns an app. We need to patch the app's prototype.\n // Connect apps have use() on their prototype chain via proto.\n\n // Create a probe app to get the prototype\n let appProto: any;\n\n try {\n const app = connectModule();\n appProto = Object.getPrototypeOf(app);\n } catch { }\n\n if (!appProto) return;\n\n // Patch use()\n if (typeof appProto.use === 'function') {\n patchMethod(\n appProto,\n 'use',\n 'senzor.connect.app.use',\n (original) =>\n function patchedUse(this: any, ...args: any[]) {\n // use() accepts:\n // use(fn)\n // use(route, fn)\n // use(route, fn1, fn2, ...)\n\n let route = '/';\n let startIdx = 0;\n\n if (typeof args[0] === 'string') {\n route = args[0];\n startIdx = 1;\n }\n\n // Wrap all function arguments\n for (let i = startIdx; i < args.length; i++) {\n if (typeof args[i] === 'function') {\n args[i] = wrapMiddleware(args[i], route, options);\n }\n }\n\n return original.apply(this, args);\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentConnect = (options?: SenzorOptions) => {\n hookRequire('connect', (exports: any) => {\n patchConnectApp(exports, options);\n\n if (exports?.default) {\n patchConnectApp(exports.default, options);\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// DataLoader Instrumentation\n//\n// Instruments the `dataloader` package — the standard batching/caching\n// utility for solving N+1 queries in GraphQL resolvers, REST APIs,\n// and any data-fetching layer.\n//\n// Patches DataLoader.prototype methods:\n// - load(key) — single key lookup (batched)\n// - loadMany(keys) — multi-key lookup (batched)\n// - prime(key, val) — cache priming\n// - clear(key) — single cache eviction\n// - clearAll() — full cache clear\n//\n// The key insight: load() calls are batched by DataLoader and dispatched\n// together via the batch function. We instrument both the individual\n// load() calls AND the batch dispatch to show:\n// 1. Per-key latency (includes batching wait time)\n// 2. Batch execution performance\n//\n// Captured attributes:\n// - dataloader.operation: load, loadMany, prime, clear, clearAll, batch\n// - dataloader.key_count: number of keys in the batch\n// - dataloader.name: DataLoader instance name (if available)\n// - dataloader.cache_hit: whether result came from cache\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// DataLoader prototype patching\n// ---------------------------------------------------------------------------\n\nconst patchDataLoader = (DataLoader: any, options?: SenzorOptions) => {\n const proto = DataLoader?.prototype;\n if (!proto) return;\n\n // --- load(key) → Promise<value> ---\n patchMethod(\n proto,\n 'load',\n 'senzor.dataloader.load',\n (original) =>\n function patchedLoad(this: any, key: any) {\n const loaderName = this.name || this._name || 'DataLoader';\n\n const span = startCapturedSpan(\n `${loaderName} load`,\n 'function',\n {\n 'dataloader.operation': 'load',\n 'dataloader.name': loaderName,\n library: 'dataloader',\n },\n options\n );\n\n if (!span) return original.call(this, key);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, key);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0);\n return value;\n },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // --- loadMany(keys) → Promise<value[]> ---\n patchMethod(\n proto,\n 'loadMany',\n 'senzor.dataloader.loadMany',\n (original) =>\n function patchedLoadMany(this: any, keys: any[]) {\n const loaderName = this.name || this._name || 'DataLoader';\n const keyCount = Array.isArray(keys) ? keys.length : 0;\n\n const span = startCapturedSpan(\n `${loaderName} loadMany`,\n 'function',\n {\n 'dataloader.operation': 'loadMany',\n 'dataloader.name': loaderName,\n 'dataloader.key_count': keyCount,\n library: 'dataloader',\n },\n options\n );\n\n if (!span) return original.call(this, keys);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, keys);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (values: any) => {\n // Count errors in results\n const errorCount = Array.isArray(values)\n ? values.filter((v: any) => v instanceof Error).length\n : 0;\n\n span.end(errorCount > 0 ? 207 : 0, {\n 'dataloader.key_count': keyCount,\n 'dataloader.error_count': errorCount,\n });\n return values;\n },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // --- Wrap the batch function dispatch ---\n // DataLoader calls the batch function internally. We intercept it\n // by wrapping the constructor or the internal _batchLoadFn.\n // Since we can't easily wrap the constructor via patchMethod,\n // we patch _batchScheduleFn or override the dispatch mechanism.\n\n // Patch the internal _batch method if it exists\n const batchMethodName = '_dispatchBatch' in proto\n ? '_dispatchBatch'\n : '_dispatch' in proto\n ? '_dispatch'\n : null;\n\n if (batchMethodName && typeof proto[batchMethodName] === 'function') {\n patchMethod(\n proto,\n batchMethodName,\n `senzor.dataloader.${batchMethodName}`,\n (original) =>\n function patchedDispatch(this: any, ...args: any[]) {\n const loaderName = this.name || this._name || 'DataLoader';\n // The batch queue holds pending keys\n const batchSize = this._queue?.length || this._batch?.length || 0;\n\n const span = startCapturedSpan(\n `${loaderName} batch dispatch`,\n 'function',\n {\n 'dataloader.operation': 'batch',\n 'dataloader.name': loaderName,\n 'dataloader.batch_size': batchSize,\n library: 'dataloader',\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n // Batch dispatch is sync; the batch function's promise\n // is resolved internally. End span after dispatch.\n span.end(0, { 'dataloader.batch_size': batchSize });\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n\n // --- prime(key, value) ---\n if (typeof proto.prime === 'function') {\n patchMethod(\n proto,\n 'prime',\n 'senzor.dataloader.prime',\n (original) =>\n function patchedPrime(this: any, key: any, value: any) {\n const loaderName = this.name || this._name || 'DataLoader';\n\n const span = startCapturedSpan(\n `${loaderName} prime`,\n 'function',\n {\n 'dataloader.operation': 'prime',\n 'dataloader.name': loaderName,\n library: 'dataloader',\n },\n options\n );\n\n if (!span) return original.call(this, key, value);\n\n try {\n const result = original.call(this, key, value);\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n }\n );\n }\n\n // --- clearAll() ---\n if (typeof proto.clearAll === 'function') {\n patchMethod(\n proto,\n 'clearAll',\n 'senzor.dataloader.clearAll',\n (original) =>\n function patchedClearAll(this: any) {\n const loaderName = this.name || this._name || 'DataLoader';\n\n const span = startCapturedSpan(\n `${loaderName} clearAll`,\n 'function',\n {\n 'dataloader.operation': 'clearAll',\n 'dataloader.name': loaderName,\n library: 'dataloader',\n },\n options\n );\n\n if (!span) return original.call(this);\n\n try {\n const result = original.call(this);\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentDataloader = (options?: SenzorOptions) => {\n hookRequire('dataloader', (exports: any) => {\n // dataloader exports the constructor directly\n patchDataLoader(exports, options);\n\n // Handle default export (ESM interop)\n if (exports?.default?.prototype) {\n patchDataLoader(exports.default, options);\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// LRU-Memoizer Instrumentation\n//\n// Instruments the `lru-memoizer` package — a popular caching/memoization\n// library used by Auth0's node-auth0 SDK, passport strategies, and other\n// authentication/authorization flows for caching tokens, JWKS keys, etc.\n//\n// Strategy: Wrap the lru-memoizer factory functions to intercept the\n// returned memoized function. Each call to the memoized function gets\n// a span showing cache hit/miss and execution time.\n//\n// lru-memoizer exports:\n// - lruMemoizer(options) — callback-based memoizer (default)\n// - lruMemoizer.sync(options) — synchronous memoizer\n//\n// The options object contains:\n// - load: the function to memoize (fetches the value on cache miss)\n// - hash: key generation function\n// - max: max cache entries\n// - maxAge: TTL in ms\n//\n// Captured attributes:\n// - memoizer.operation: 'lookup'\n// - memoizer.name: function name or 'memoized'\n// - memoizer.cache_size: current cache size (if available)\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Memoized function wrapping\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap a memoized function (returned by lru-memoizer) to add spans.\n * The original load function name is used as the span name.\n */\nconst wrapMemoizedFunction = (\n memoized: Function,\n loadFnName: string,\n options?: SenzorOptions\n): Function => {\n if (typeof memoized !== 'function') return memoized;\n if ((memoized as any).__senzorWrapped) return memoized;\n\n const name = loadFnName || 'memoized';\n\n const wrapped = function wrappedMemoized(this: any, ...args: any[]) {\n const span = startCapturedSpan(\n `LRU ${name}`,\n 'function',\n {\n 'memoizer.operation': 'lookup',\n 'memoizer.name': name,\n library: 'lru-memoizer',\n },\n options\n );\n\n if (!span) return memoized.apply(this, args);\n\n // Check if last arg is a callback\n const lastIdx = args.length - 1;\n const hasCallback = lastIdx >= 0 && typeof args[lastIdx] === 'function';\n\n if (hasCallback) {\n const originalCb = args[lastIdx];\n args[lastIdx] = function (err: any, ...results: any[]) {\n if (err) {\n span.end(500, {\n 'error.message': typeof err === 'string' ? err : err?.message,\n 'error.type': err?.name || 'Error',\n });\n } else {\n span.end(0);\n }\n return originalCb.call(this, err, ...results);\n };\n\n return runWithCapturedSpan(span, () => {\n try {\n return memoized.apply(this, args);\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n\n // Promise-based or sync\n return runWithCapturedSpan(span, () => {\n try {\n const result = memoized.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n };\n\n // Preserve any properties on the original memoized function\n // (e.g., .keys(), .reset(), .del())\n for (const key of Object.keys(memoized)) {\n try { (wrapped as any)[key] = (memoized as any)[key]; } catch { }\n }\n\n (wrapped as any).__senzorWrapped = true;\n return wrapped;\n};\n\n// ---------------------------------------------------------------------------\n// Factory wrapping\n// ---------------------------------------------------------------------------\n\nconst patchLruMemoizer = (lruMemoizer: any, options?: SenzorOptions) => {\n if (typeof lruMemoizer !== 'function') return lruMemoizer;\n\n // Wrap the main factory (callback-based)\n const wrappedFactory = function patchedLruMemoizer(this: any, memoizerOptions: any) {\n const loadFnName = memoizerOptions?.load?.name || memoizerOptions?.name || 'memoized';\n const result = lruMemoizer.call(this, memoizerOptions);\n return wrapMemoizedFunction(result, loadFnName, options);\n };\n\n // Copy all static properties\n for (const key of Object.keys(lruMemoizer)) {\n try { (wrappedFactory as any)[key] = (lruMemoizer as any)[key]; } catch { }\n }\n\n // Wrap .sync() if it exists\n if (typeof lruMemoizer.sync === 'function') {\n const originalSync = lruMemoizer.sync;\n (wrappedFactory as any).sync = function patchedSync(this: any, memoizerOptions: any) {\n const loadFnName = memoizerOptions?.load?.name || memoizerOptions?.name || 'memoized-sync';\n const result = originalSync.call(this, memoizerOptions);\n return wrapMemoizedFunction(result, loadFnName, options);\n };\n }\n\n return wrappedFactory;\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentLruMemoizer = (options?: SenzorOptions) => {\n hookRequire('lru-memoizer', (exports: any) => {\n // lru-memoizer exports the factory directly\n if (typeof exports === 'function') {\n return patchLruMemoizer(exports, options);\n }\n\n // Handle { default: fn } or { memoizer: fn }\n if (typeof exports?.default === 'function') {\n exports.default = patchLruMemoizer(exports.default, options);\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// File System (fs) Instrumentation\n//\n// Instruments Node.js core `fs` module to capture file I/O operations.\n// File system calls are a common source of latency in Node.js applications\n// (template rendering, config loading, log writing, file uploads, etc.).\n//\n// Only instruments ASYNC methods (callback + promises) — never sync methods,\n// as those block the event loop and adding span overhead would be wasteful.\n//\n// Patches:\n// - Callback-based: fs.readFile, fs.writeFile, fs.stat, fs.access,\n// fs.readdir, fs.mkdir, fs.rmdir, fs.unlink, fs.rename, fs.copyFile,\n// fs.appendFile, fs.chmod, fs.chown, fs.link, fs.symlink, fs.realpath,\n// fs.mkdtemp, fs.open, fs.close\n// - Promise-based: fs.promises.* (same set)\n//\n// Captured attributes:\n// - fs.operation: readFile, writeFile, stat, etc.\n// - fs.path: file path (sanitized — no secrets in paths)\n// - fs.flags: open flags (r, w, a, etc.)\n// ---------------------------------------------------------------------------\n\n/** Operations to instrument. Grouped by argument patterns. */\nconst PATH_OPERATIONS = [\n 'readFile', 'writeFile', 'appendFile', 'stat', 'lstat',\n 'access', 'readdir', 'mkdir', 'rmdir', 'unlink',\n 'chmod', 'chown', 'realpath', 'mkdtemp', 'truncate',\n 'readlink', 'exists',\n] as const;\n\nconst TWO_PATH_OPERATIONS = [\n 'rename', 'copyFile', 'link', 'symlink',\n] as const;\n\n/** Sanitize a file path — strip home directory prefix for privacy. */\nconst sanitizePath = (filePath: any): string | undefined => {\n if (typeof filePath !== 'string' && !(filePath instanceof Buffer) && !(filePath instanceof URL)) {\n return undefined;\n }\n const pathStr = String(filePath);\n // Truncate very long paths\n if (pathStr.length > 200) return pathStr.slice(0, 200) + '...';\n return pathStr;\n};\n\n// ---------------------------------------------------------------------------\n// Callback-based fs method patching\n// ---------------------------------------------------------------------------\n\nconst patchFsCallbackMethod = (\n fsModule: any,\n methodName: string,\n pathArgCount: number,\n options?: SenzorOptions\n) => {\n if (typeof fsModule[methodName] !== 'function') return;\n\n patchMethod(\n fsModule,\n methodName,\n `senzor.fs.${methodName}`,\n (original) =>\n function patchedFsMethod(this: any, ...args: any[]) {\n const operation = methodName.toUpperCase();\n const filePath = sanitizePath(args[0]);\n\n const spanMeta: Record<string, any> = {\n 'fs.operation': methodName,\n 'fs.path': filePath,\n library: 'fs',\n };\n\n if (pathArgCount === 2 && args[1]) {\n spanMeta['fs.destination'] = sanitizePath(args[1]);\n }\n\n const span = startCapturedSpan(\n `FS ${operation}`,\n 'custom',\n spanMeta,\n options\n );\n\n if (!span) return original.apply(this, args);\n\n // Find and wrap the callback (last function argument)\n const callbackIndex = args.findIndex(\n (arg, idx) => idx >= pathArgCount && typeof arg === 'function'\n );\n\n if (callbackIndex >= 0) {\n const originalCb = args[callbackIndex];\n args[callbackIndex] = function (err: any, ...results: any[]) {\n if (err) {\n span.end(500, {\n 'error.message': err.message,\n 'error.type': err.name || 'Error',\n 'error.code': err.code,\n });\n } else {\n span.end(0);\n }\n return originalCb.call(this, err, ...results);\n };\n }\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n // If no callback found, end span after sync return\n if (callbackIndex < 0) {\n span.end(0);\n }\n\n return result;\n } catch (error: any) {\n span.end(500, {\n 'error.message': error?.message,\n 'error.code': error?.code,\n });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Promise-based fs.promises method patching\n// ---------------------------------------------------------------------------\n\nconst patchFsPromiseMethod = (\n fsPromises: any,\n methodName: string,\n pathArgCount: number,\n options?: SenzorOptions\n) => {\n if (typeof fsPromises[methodName] !== 'function') return;\n\n patchMethod(\n fsPromises,\n methodName,\n `senzor.fs.promises.${methodName}`,\n (original) =>\n function patchedFsPromiseMethod(this: any, ...args: any[]) {\n const operation = methodName.toUpperCase();\n const filePath = sanitizePath(args[0]);\n\n const spanMeta: Record<string, any> = {\n 'fs.operation': methodName,\n 'fs.path': filePath,\n 'fs.api': 'promises',\n library: 'fs',\n };\n\n if (pathArgCount === 2 && args[1]) {\n spanMeta['fs.destination'] = sanitizePath(args[1]);\n }\n\n const span = startCapturedSpan(\n `FS ${operation}`,\n 'custom',\n spanMeta,\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.code': error?.code,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Core fs module patching\n// ---------------------------------------------------------------------------\n\nconst patchFs = (fsModule: any, options?: SenzorOptions) => {\n if (!fsModule) return;\n\n // Patch callback-based methods (single path argument)\n for (const method of PATH_OPERATIONS) {\n patchFsCallbackMethod(fsModule, method, 1, options);\n }\n\n // Patch callback-based methods (two path arguments)\n for (const method of TWO_PATH_OPERATIONS) {\n patchFsCallbackMethod(fsModule, method, 2, options);\n }\n\n // Patch open/close separately (they have different signatures)\n patchFsCallbackMethod(fsModule, 'open', 1, options);\n patchFsCallbackMethod(fsModule, 'close', 1, options);\n\n // Patch fs.promises\n const promises = fsModule.promises;\n if (promises) {\n for (const method of PATH_OPERATIONS) {\n if (method === 'exists') continue; // fs.promises.exists doesn't exist\n patchFsPromiseMethod(promises, method, 1, options);\n }\n\n for (const method of TWO_PATH_OPERATIONS) {\n patchFsPromiseMethod(promises, method, 2, options);\n }\n\n patchFsPromiseMethod(promises, 'open', 1, options);\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentFs = (options?: SenzorOptions) => {\n // fs is a Node.js built-in — require it directly\n try {\n const fs = require('fs');\n patchFs(fs, options);\n } catch { }\n\n // Also hook for any dynamic requires\n hookRequire('fs', (exports: any) => {\n patchFs(exports, options);\n });\n\n hookRequire('node:fs', (exports: any) => {\n patchFs(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// OpenAI SDK Instrumentation\n//\n// Instruments the official `openai` npm package (v4+) to capture API calls\n// to OpenAI services (GPT, DALL-E, Whisper, Embeddings, Assistants, etc.).\n//\n// Strategy: Patch the core APIClient._request() method — the single\n// dispatch point for ALL OpenAI API calls. This covers:\n// - chat.completions.create()\n// - completions.create()\n// - embeddings.create()\n// - images.generate()\n// - audio.transcriptions.create()\n// - moderations.create()\n// - files.*, fine_tuning.*, assistants.*, threads.*, etc.\n//\n// Also patches specific resource methods for richer attribute capture\n// (model name, token usage, etc.).\n//\n// Captured attributes (following emerging GenAI OTel conventions):\n// - gen_ai.system: 'openai'\n// - gen_ai.request.model: model name (gpt-4, gpt-3.5-turbo, etc.)\n// - gen_ai.operation.name: chat, completions, embeddings, etc.\n// - gen_ai.response.model: actual model used in response\n// - gen_ai.usage.input_tokens: prompt tokens\n// - gen_ai.usage.output_tokens: completion tokens\n// - gen_ai.request.max_tokens: requested max tokens\n// - gen_ai.request.temperature: temperature setting\n// - http.response.status_code: API response status\n// ---------------------------------------------------------------------------\n\n/** Map of resource path segments to operation names. */\nconst OPERATION_MAP: Record<string, string> = {\n 'chat/completions': 'chat',\n completions: 'completions',\n embeddings: 'embeddings',\n images: 'images',\n 'images/generations': 'images.generate',\n 'images/edits': 'images.edit',\n 'images/variations': 'images.variation',\n 'audio/transcriptions': 'audio.transcribe',\n 'audio/translations': 'audio.translate',\n 'audio/speech': 'audio.speech',\n moderations: 'moderations',\n 'fine_tuning/jobs': 'fine_tuning',\n files: 'files',\n assistants: 'assistants',\n threads: 'threads',\n 'threads/runs': 'threads.runs',\n 'threads/messages': 'threads.messages',\n batches: 'batches',\n 'vector_stores': 'vector_stores',\n};\n\n/** Extract operation name from the API path. */\nconst getOperationName = (path: string): string => {\n if (!path) return 'unknown';\n\n // Normalize path: strip leading slash, version prefix\n const normalized = path.replace(/^\\/?(v1\\/)?/, '').replace(/\\/[a-f0-9-]{20,}(\\/|$)/g, '/');\n\n // Try exact match first, then prefix match\n for (const [pattern, name] of Object.entries(OPERATION_MAP)) {\n if (normalized === pattern || normalized.startsWith(pattern + '/')) {\n return name;\n }\n }\n\n // Fallback: first path segment\n return normalized.split('/')[0] || 'api';\n};\n\n/** Extract model from request body. */\nconst getRequestModel = (body: any): string | undefined => {\n if (!body || typeof body !== 'object') return undefined;\n return body.model || undefined;\n};\n\n// ---------------------------------------------------------------------------\n// Core APIClient._request patching\n// ---------------------------------------------------------------------------\n\nconst patchOpenAIClient = (openaiModule: any, options?: SenzorOptions) => {\n // openai v4 exports OpenAI class (default export)\n const OpenAI = openaiModule?.OpenAI || openaiModule?.default || openaiModule;\n\n if (!OpenAI || typeof OpenAI !== 'function') return;\n\n const proto = OpenAI.prototype;\n if (!proto) return;\n\n // Find the internal request method — could be _request, post, get, etc.\n // In openai v4, the base client (APIClient) has these methods:\n // post(), get(), put(), patch(), delete() which all call _request()\n\n // Patch the HTTP methods on the prototype\n const httpMethods = ['post', 'get', 'put', 'patch', 'delete'] as const;\n\n for (const method of httpMethods) {\n if (typeof proto[method] !== 'function') continue;\n\n patchMethod(\n proto,\n method,\n `senzor.openai.client.${method}`,\n (original) =>\n function patchedMethod(this: any, path: string, opts?: any) {\n const operationName = getOperationName(path);\n const model = getRequestModel(opts?.body);\n const httpMethod = method.toUpperCase();\n\n const spanName = model\n ? `OpenAI ${operationName} ${model}`\n : `OpenAI ${operationName}`;\n\n const span = startCapturedSpan(\n spanName,\n 'http',\n {\n 'gen_ai.system': 'openai',\n 'gen_ai.operation.name': operationName,\n 'gen_ai.request.model': model,\n 'gen_ai.request.max_tokens': opts?.body?.max_tokens,\n 'gen_ai.request.temperature': opts?.body?.temperature,\n 'http.request.method': httpMethod,\n 'url.path': path,\n library: 'openai',\n },\n options\n );\n\n if (!span) return original.call(this, path, opts);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, path, opts);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (response: any) => {\n const endMeta: Record<string, any> = {};\n\n // Extract usage from response\n if (response?.usage) {\n endMeta['gen_ai.usage.input_tokens'] = response.usage.prompt_tokens;\n endMeta['gen_ai.usage.output_tokens'] = response.usage.completion_tokens;\n endMeta['gen_ai.usage.total_tokens'] = response.usage.total_tokens;\n }\n\n // Extract actual model used\n if (response?.model) {\n endMeta['gen_ai.response.model'] = response.model;\n }\n\n // Extract finish reason\n if (response?.choices?.[0]?.finish_reason) {\n endMeta['gen_ai.response.finish_reason'] = response.choices[0].finish_reason;\n }\n\n span.end(0, endMeta);\n return response;\n },\n (error: any) => {\n const statusCode = error?.status || error?.statusCode || 500;\n span.end(statusCode, {\n 'error.message': error?.message,\n 'error.type': error?.name || error?.type || 'OpenAIError',\n 'http.response.status_code': statusCode,\n 'gen_ai.error.code': error?.code,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n const statusCode = error?.status || 500;\n span.end(statusCode, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n 'http.response.status_code': statusCode,\n });\n throw error;\n }\n });\n }\n );\n }\n\n // Also try to patch the internal request dispatcher\n if (typeof proto._request === 'function') {\n patchMethod(\n proto,\n '_request',\n 'senzor.openai.client._request',\n (original) =>\n function patchedRequest(this: any, requestOptions: any, ...args: any[]) {\n // _request receives the full request options object\n const path = requestOptions?.path || '';\n const method = requestOptions?.method || 'POST';\n const operationName = getOperationName(path);\n const model = getRequestModel(requestOptions?.body);\n\n const spanName = model\n ? `OpenAI ${operationName} ${model}`\n : `OpenAI ${operationName}`;\n\n const span = startCapturedSpan(\n spanName,\n 'http',\n {\n 'gen_ai.system': 'openai',\n 'gen_ai.operation.name': operationName,\n 'gen_ai.request.model': model,\n 'http.request.method': method,\n 'url.path': path,\n library: 'openai',\n },\n options\n );\n\n if (!span) return original.call(this, requestOptions, ...args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, requestOptions, ...args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (response: any) => {\n const endMeta: Record<string, any> = {};\n\n if (response?.usage) {\n endMeta['gen_ai.usage.input_tokens'] = response.usage.prompt_tokens;\n endMeta['gen_ai.usage.output_tokens'] = response.usage.completion_tokens;\n }\n if (response?.model) {\n endMeta['gen_ai.response.model'] = response.model;\n }\n\n span.end(0, endMeta);\n return response;\n },\n (error: any) => {\n span.end(error?.status || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'OpenAIError',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentOpenAI = (options?: SenzorOptions) => {\n hookRequire('openai', (exports: any) => {\n patchOpenAIClient(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Anthropic SDK Instrumentation\n//\n// Instruments the official `@anthropic-ai/sdk` package (v0.20+).\n//\n// The Anthropic SDK is architecturally identical to OpenAI v4 — both are\n// built on the same Stainless-generated base client (`APIClient`) with\n// HTTP dispatch via `.post()`, `.get()`, etc.\n//\n// Patches:\n// - Anthropic.prototype.post/get/put/patch/delete — HTTP dispatch methods\n// - Anthropic.prototype._request — internal request dispatcher\n//\n// This covers ALL API calls:\n// - messages.create() (streaming & non-streaming)\n// - messages.batches.create()\n// - completions.create() (legacy)\n//\n// Captured attributes (OTel GenAI semantic conventions):\n// - gen_ai.system: 'anthropic'\n// - gen_ai.request.model: claude-sonnet-4-20250514, etc.\n// - gen_ai.operation.name: messages, completions, batches\n// - gen_ai.response.model: actual model from response\n// - gen_ai.usage.input_tokens: prompt token count\n// - gen_ai.usage.output_tokens: completion token count\n// - gen_ai.request.max_tokens: max_tokens parameter\n// - gen_ai.request.temperature: temperature parameter\n// - gen_ai.response.stop_reason: end_turn, max_tokens, etc.\n// ---------------------------------------------------------------------------\n\n/** Map API path segments to operation names. */\nconst OPERATION_MAP: Record<string, string> = {\n messages: 'messages',\n 'messages/batches': 'messages.batches',\n completions: 'completions',\n};\n\nconst getOperationName = (path: string): string => {\n if (!path) return 'unknown';\n const normalized = path.replace(/^\\/?(v1\\/)?/, '');\n\n for (const [pattern, name] of Object.entries(OPERATION_MAP)) {\n if (normalized === pattern || normalized.startsWith(pattern + '/')) {\n return name;\n }\n }\n\n return normalized.split('/')[0] || 'api';\n};\n\nconst getRequestModel = (body: any): string | undefined => {\n if (!body || typeof body !== 'object') return undefined;\n return body.model || undefined;\n};\n\n// ---------------------------------------------------------------------------\n// Core client patching\n// ---------------------------------------------------------------------------\n\nconst patchAnthropicClient = (anthropicModule: any, options?: SenzorOptions) => {\n const Anthropic = anthropicModule?.Anthropic\n || anthropicModule?.default\n || anthropicModule;\n\n if (!Anthropic || typeof Anthropic !== 'function') return;\n\n const proto = Anthropic.prototype;\n if (!proto) return;\n\n // Patch HTTP dispatch methods\n const httpMethods = ['post', 'get', 'put', 'patch', 'delete'] as const;\n\n for (const method of httpMethods) {\n if (typeof proto[method] !== 'function') continue;\n\n patchMethod(\n proto,\n method,\n `senzor.anthropic.client.${method}`,\n (original) =>\n function patchedMethod(this: any, path: string, opts?: any) {\n const operationName = getOperationName(path);\n const model = getRequestModel(opts?.body);\n const httpMethod = method.toUpperCase();\n\n const spanName = model\n ? `Anthropic ${operationName} ${model}`\n : `Anthropic ${operationName}`;\n\n const span = startCapturedSpan(\n spanName,\n 'http',\n {\n 'gen_ai.system': 'anthropic',\n 'gen_ai.operation.name': operationName,\n 'gen_ai.request.model': model,\n 'gen_ai.request.max_tokens': opts?.body?.max_tokens,\n 'gen_ai.request.temperature': opts?.body?.temperature,\n 'gen_ai.request.top_p': opts?.body?.top_p,\n 'http.request.method': httpMethod,\n 'url.path': path,\n library: 'anthropic',\n },\n options\n );\n\n if (!span) return original.call(this, path, opts);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, path, opts);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (response: any) => {\n const endMeta: Record<string, any> = {};\n\n // Anthropic response format\n if (response?.usage) {\n endMeta['gen_ai.usage.input_tokens'] = response.usage.input_tokens;\n endMeta['gen_ai.usage.output_tokens'] = response.usage.output_tokens;\n }\n if (response?.model) {\n endMeta['gen_ai.response.model'] = response.model;\n }\n if (response?.stop_reason) {\n endMeta['gen_ai.response.stop_reason'] = response.stop_reason;\n }\n\n span.end(0, endMeta);\n return response;\n },\n (error: any) => {\n const statusCode = error?.status || error?.statusCode || 500;\n span.end(statusCode, {\n 'error.message': error?.message,\n 'error.type': error?.name || error?.type || 'AnthropicError',\n 'http.response.status_code': statusCode,\n 'gen_ai.error.code': error?.error?.type,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(error?.status || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'Error',\n });\n throw error;\n }\n });\n }\n );\n }\n\n // Also patch _request as fallback\n if (typeof proto._request === 'function') {\n patchMethod(\n proto,\n '_request',\n 'senzor.anthropic.client._request',\n (original) =>\n function patchedRequest(this: any, requestOptions: any, ...args: any[]) {\n const path = requestOptions?.path || '';\n const method = requestOptions?.method || 'POST';\n const operationName = getOperationName(path);\n const model = getRequestModel(requestOptions?.body);\n\n const spanName = model\n ? `Anthropic ${operationName} ${model}`\n : `Anthropic ${operationName}`;\n\n const span = startCapturedSpan(\n spanName,\n 'http',\n {\n 'gen_ai.system': 'anthropic',\n 'gen_ai.operation.name': operationName,\n 'gen_ai.request.model': model,\n 'http.request.method': method,\n 'url.path': path,\n library: 'anthropic',\n },\n options\n );\n\n if (!span) return original.call(this, requestOptions, ...args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, requestOptions, ...args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (response: any) => {\n const endMeta: Record<string, any> = {};\n if (response?.usage) {\n endMeta['gen_ai.usage.input_tokens'] = response.usage.input_tokens;\n endMeta['gen_ai.usage.output_tokens'] = response.usage.output_tokens;\n }\n if (response?.model) {\n endMeta['gen_ai.response.model'] = response.model;\n }\n span.end(0, endMeta);\n return response;\n },\n (error: any) => {\n span.end(error?.status || 500, {\n 'error.message': error?.message,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentAnthropic = (options?: SenzorOptions) => {\n hookRequire('@anthropic-ai/sdk', (exports: any) => {\n patchAnthropicClient(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Google Generative AI (Gemini) Instrumentation\n//\n// Instruments both the client-side `@google/generative-ai` package and the\n// server-side `@google-cloud/vertexai` package for Google's Gemini models.\n//\n// @google/generative-ai patches:\n// - GenerativeModel.prototype.generateContent()\n// - GenerativeModel.prototype.generateContentStream()\n// - GenerativeModel.prototype.countTokens()\n// - GenerativeModel.prototype.embedContent()\n// - GenerativeModel.prototype.batchEmbedContents()\n// - ChatSession.prototype.sendMessage()\n// - ChatSession.prototype.sendMessageStream()\n//\n// @google-cloud/vertexai patches:\n// - GenerativeModel.prototype.generateContent()\n// - GenerativeModel.prototype.generateContentStream()\n//\n// Captured attributes (OTel GenAI semantic conventions):\n// - gen_ai.system: 'google_ai' | 'vertex_ai'\n// - gen_ai.request.model: gemini-1.5-pro, etc.\n// - gen_ai.operation.name: generateContent, chat, embedContent, etc.\n// - gen_ai.usage.input_tokens: promptTokenCount\n// - gen_ai.usage.output_tokens: candidatesTokenCount\n// - gen_ai.response.finish_reason: from candidates[0].finishReason\n// ---------------------------------------------------------------------------\n\n/** Extract token usage from Gemini response. */\nconst extractUsage = (response: any): Record<string, any> => {\n const meta: Record<string, any> = {};\n const usage = response?.usageMetadata;\n\n if (usage) {\n if (usage.promptTokenCount !== undefined) {\n meta['gen_ai.usage.input_tokens'] = usage.promptTokenCount;\n }\n if (usage.candidatesTokenCount !== undefined) {\n meta['gen_ai.usage.output_tokens'] = usage.candidatesTokenCount;\n }\n if (usage.totalTokenCount !== undefined) {\n meta['gen_ai.usage.total_tokens'] = usage.totalTokenCount;\n }\n }\n\n // Extract finish reason from first candidate\n const finishReason = response?.candidates?.[0]?.finishReason;\n if (finishReason) {\n meta['gen_ai.response.finish_reason'] = finishReason;\n }\n\n return meta;\n};\n\n/** Extract usage from a GenerateContentResponse (may be wrapped). */\nconst extractResponseUsage = (result: any): Record<string, any> => {\n // result could be GenerateContentResult { response } or the response directly\n const response = result?.response || result;\n return extractUsage(response);\n};\n\n// ---------------------------------------------------------------------------\n// @google/generative-ai patching\n// ---------------------------------------------------------------------------\n\nconst patchGoogleGenAI = (genaiModule: any, options?: SenzorOptions) => {\n // Patch GenerativeModel\n const GenerativeModel = genaiModule?.GenerativeModel;\n if (GenerativeModel?.prototype) {\n const proto = GenerativeModel.prototype;\n\n // --- generateContent ---\n patchMethod(\n proto,\n 'generateContent',\n 'senzor.google-genai.generateContent',\n (original) =>\n function patchedGenerateContent(this: any, request: any) {\n const modelName = this.model || this.modelName || 'unknown';\n\n const span = startCapturedSpan(\n `Gemini generateContent ${modelName}`,\n 'http',\n {\n 'gen_ai.system': 'google_ai',\n 'gen_ai.operation.name': 'generateContent',\n 'gen_ai.request.model': modelName,\n 'gen_ai.request.temperature': this.generationConfig?.temperature,\n 'gen_ai.request.max_tokens': this.generationConfig?.maxOutputTokens,\n 'gen_ai.request.top_p': this.generationConfig?.topP,\n library: 'google-genai',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, request);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, extractResponseUsage(value));\n return value;\n },\n (error: any) => {\n span.end(error?.status || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'GoogleGenAIError',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n\n // --- generateContentStream ---\n if (typeof proto.generateContentStream === 'function') {\n patchMethod(\n proto,\n 'generateContentStream',\n 'senzor.google-genai.generateContentStream',\n (original) =>\n function patchedGenerateContentStream(this: any, request: any) {\n const modelName = this.model || this.modelName || 'unknown';\n\n const span = startCapturedSpan(\n `Gemini generateContentStream ${modelName}`,\n 'http',\n {\n 'gen_ai.system': 'google_ai',\n 'gen_ai.operation.name': 'generateContentStream',\n 'gen_ai.request.model': modelName,\n library: 'google-genai',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, request);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (streamResult: any) => {\n // Stream result has a .response promise for final aggregated response\n if (streamResult?.response && typeof streamResult.response.then === 'function') {\n streamResult.response.then(\n (resp: any) => span.end(0, extractUsage(resp)),\n () => span.end(0)\n );\n } else {\n span.end(0);\n }\n return streamResult;\n },\n (error: any) => {\n span.end(error?.status || 500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n\n // --- countTokens ---\n if (typeof proto.countTokens === 'function') {\n patchMethod(\n proto,\n 'countTokens',\n 'senzor.google-genai.countTokens',\n (original) =>\n function patchedCountTokens(this: any, request: any) {\n const modelName = this.model || this.modelName || 'unknown';\n\n const span = startCapturedSpan(\n `Gemini countTokens ${modelName}`,\n 'http',\n {\n 'gen_ai.system': 'google_ai',\n 'gen_ai.operation.name': 'countTokens',\n 'gen_ai.request.model': modelName,\n library: 'google-genai',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, request);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, {\n 'gen_ai.usage.total_tokens': value?.totalTokens,\n });\n return value;\n },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n\n // --- embedContent ---\n if (typeof proto.embedContent === 'function') {\n patchMethod(\n proto,\n 'embedContent',\n 'senzor.google-genai.embedContent',\n (original) =>\n function patchedEmbedContent(this: any, request: any) {\n const modelName = this.model || this.modelName || 'unknown';\n\n const span = startCapturedSpan(\n `Gemini embedContent ${modelName}`,\n 'http',\n {\n 'gen_ai.system': 'google_ai',\n 'gen_ai.operation.name': 'embedContent',\n 'gen_ai.request.model': modelName,\n library: 'google-genai',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, request);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n }\n\n // Patch ChatSession\n const ChatSession = genaiModule?.ChatSession;\n if (ChatSession?.prototype) {\n const chatProto = ChatSession.prototype;\n\n for (const method of ['sendMessage', 'sendMessageStream'] as const) {\n if (typeof chatProto[method] !== 'function') continue;\n\n patchMethod(\n chatProto,\n method,\n `senzor.google-genai.chat.${method}`,\n (original) =>\n function patchedChatMethod(this: any, ...args: any[]) {\n const modelName = this.model || this._model || 'unknown';\n const isStream = method === 'sendMessageStream';\n\n const span = startCapturedSpan(\n `Gemini chat.${method} ${modelName}`,\n 'http',\n {\n 'gen_ai.system': 'google_ai',\n 'gen_ai.operation.name': isStream ? 'chat.stream' : 'chat',\n 'gen_ai.request.model': modelName,\n library: 'google-genai',\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, extractResponseUsage(value));\n return value;\n },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n }\n};\n\n// ---------------------------------------------------------------------------\n// @google-cloud/vertexai patching (same model classes, different system tag)\n// ---------------------------------------------------------------------------\n\nconst patchVertexAI = (vertexModule: any, options?: SenzorOptions) => {\n const GenerativeModel = vertexModule?.GenerativeModel;\n if (!GenerativeModel?.prototype) return;\n\n const proto = GenerativeModel.prototype;\n\n for (const method of ['generateContent', 'generateContentStream'] as const) {\n if (typeof proto[method] !== 'function') continue;\n\n patchMethod(\n proto,\n method,\n `senzor.vertexai.${method}`,\n (original) =>\n function patchedVertexMethod(this: any, request: any) {\n const modelName = this.model || this.modelName || 'unknown';\n\n const span = startCapturedSpan(\n `VertexAI ${method} ${modelName}`,\n 'http',\n {\n 'gen_ai.system': 'vertex_ai',\n 'gen_ai.operation.name': method,\n 'gen_ai.request.model': modelName,\n library: 'vertex-ai',\n },\n options\n );\n\n if (!span) return original.call(this, request);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, request);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, extractResponseUsage(value));\n return value;\n },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentGoogleGenAI = (options?: SenzorOptions) => {\n hookRequire('@google/generative-ai', (exports: any) => {\n patchGoogleGenAI(exports, options);\n });\n\n hookRequire('@google-cloud/vertexai', (exports: any) => {\n patchVertexAI(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Azure OpenAI Instrumentation\n//\n// Instruments the `@azure/openai` package (pre-v2) for Azure-hosted\n// OpenAI models.\n//\n// IMPORTANT: Azure OpenAI SDK v2+ (released 2024) wraps the standard\n// `openai` npm package internally. If the user has v2+, our existing\n// OpenAI instrumentation already captures those calls automatically.\n// This file covers the older, Azure-specific v1.x API.\n//\n// Patches OpenAIClient.prototype methods:\n// - getChatCompletions() — chat model inference\n// - getCompletions() — legacy completion inference\n// - getEmbeddings() — embedding generation\n// - getImages() — DALL-E image generation\n// - getAudioTranscription() — Whisper transcription\n// - getAudioTranslation() — Whisper translation\n//\n// Captured attributes (OTel GenAI semantic conventions):\n// - gen_ai.system: 'azure_openai'\n// - gen_ai.request.model: deployment name\n// - gen_ai.operation.name: chat, completions, embeddings, etc.\n// - gen_ai.usage.input_tokens: prompt tokens\n// - gen_ai.usage.output_tokens: completion tokens\n// - gen_ai.response.finish_reason: stop, length, etc.\n// ---------------------------------------------------------------------------\n\n/** Methods to instrument with their operation name and token extraction strategy. */\nconst METHODS: {\n name: string;\n operation: string;\n extractUsage: (result: any) => Record<string, any>;\n}[] = [\n {\n name: 'getChatCompletions',\n operation: 'chat',\n extractUsage: (result: any) => {\n const meta: Record<string, any> = {};\n if (result?.usage) {\n meta['gen_ai.usage.input_tokens'] = result.usage.promptTokens;\n meta['gen_ai.usage.output_tokens'] = result.usage.completionTokens;\n meta['gen_ai.usage.total_tokens'] = result.usage.totalTokens;\n }\n if (result?.choices?.[0]?.finishReason) {\n meta['gen_ai.response.finish_reason'] = result.choices[0].finishReason;\n }\n if (result?.model) {\n meta['gen_ai.response.model'] = result.model;\n }\n return meta;\n },\n },\n {\n name: 'getCompletions',\n operation: 'completions',\n extractUsage: (result: any) => {\n const meta: Record<string, any> = {};\n if (result?.usage) {\n meta['gen_ai.usage.input_tokens'] = result.usage.promptTokens;\n meta['gen_ai.usage.output_tokens'] = result.usage.completionTokens;\n }\n if (result?.choices?.[0]?.finishReason) {\n meta['gen_ai.response.finish_reason'] = result.choices[0].finishReason;\n }\n return meta;\n },\n },\n {\n name: 'getEmbeddings',\n operation: 'embeddings',\n extractUsage: (result: any) => {\n const meta: Record<string, any> = {};\n if (result?.usage) {\n meta['gen_ai.usage.input_tokens'] = result.usage.promptTokens;\n meta['gen_ai.usage.total_tokens'] = result.usage.totalTokens;\n }\n return meta;\n },\n },\n {\n name: 'getImages',\n operation: 'images',\n extractUsage: () => ({}),\n },\n {\n name: 'getAudioTranscription',\n operation: 'audio.transcribe',\n extractUsage: () => ({}),\n },\n {\n name: 'getAudioTranslation',\n operation: 'audio.translate',\n extractUsage: () => ({}),\n },\n];\n\n// ---------------------------------------------------------------------------\n// OpenAIClient prototype patching\n// ---------------------------------------------------------------------------\n\nconst patchAzureOpenAIClient = (azureModule: any, options?: SenzorOptions) => {\n const OpenAIClient = azureModule?.OpenAIClient;\n if (!OpenAIClient?.prototype) return;\n\n const proto = OpenAIClient.prototype;\n\n for (const methodConfig of METHODS) {\n if (typeof proto[methodConfig.name] !== 'function') continue;\n\n patchMethod(\n proto,\n methodConfig.name,\n `senzor.azure-openai.${methodConfig.name}`,\n (original) =>\n function patchedAzureMethod(this: any, deploymentName: string, ...args: any[]) {\n const span = startCapturedSpan(\n `Azure OpenAI ${methodConfig.operation} ${deploymentName}`,\n 'http',\n {\n 'gen_ai.system': 'azure_openai',\n 'gen_ai.operation.name': methodConfig.operation,\n 'gen_ai.request.model': deploymentName,\n 'cloud.provider': 'azure',\n library: 'azure-openai',\n },\n options\n );\n\n if (!span) return original.call(this, deploymentName, ...args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, deploymentName, ...args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, methodConfig.extractUsage(value));\n return value;\n },\n (error: any) => {\n span.end(error?.status || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'AzureOpenAIError',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentAzureOpenAI = (options?: SenzorOptions) => {\n hookRequire('@azure/openai', (exports: any) => {\n patchAzureOpenAIClient(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Cohere SDK Instrumentation\n//\n// Instruments the `cohere-ai` npm package for Cohere's NLP models\n// (Command, Embed, Rerank, Classify, Summarize, etc.).\n//\n// Patches CohereClient.prototype (or CohereClientV2.prototype) methods:\n// - chat() — conversational generation (Command R/R+)\n// - chatStream() — streaming chat\n// - generate() — text generation (legacy)\n// - embed() — embedding generation\n// - rerank() — semantic reranking\n// - classify() — text classification\n// - summarize() — text summarization\n// - tokenize() — tokenization\n// - detokenize() — detokenization\n//\n// Captured attributes (OTel GenAI semantic conventions):\n// - gen_ai.system: 'cohere'\n// - gen_ai.request.model: command-r-plus, embed-english-v3.0, etc.\n// - gen_ai.operation.name: chat, generate, embed, rerank, etc.\n// - gen_ai.usage.input_tokens: billed input tokens\n// - gen_ai.usage.output_tokens: billed output tokens\n// - gen_ai.response.finish_reason: COMPLETE, MAX_TOKENS, etc.\n// ---------------------------------------------------------------------------\n\n/** Methods to instrument with metadata extractors. */\nconst METHODS: {\n name: string;\n operation: string;\n getModel: (args: any[]) => string | undefined;\n extractUsage: (result: any) => Record<string, any>;\n}[] = [\n {\n name: 'chat',\n operation: 'chat',\n getModel: (args) => args[0]?.model,\n extractUsage: (result) => {\n const meta: Record<string, any> = {};\n // Cohere v2 chat response\n if (result?.meta?.billedUnits) {\n meta['gen_ai.usage.input_tokens'] = result.meta.billedUnits.inputTokens;\n meta['gen_ai.usage.output_tokens'] = result.meta.billedUnits.outputTokens;\n }\n // Cohere v1 chat response\n if (result?.meta?.tokens) {\n meta['gen_ai.usage.input_tokens'] = meta['gen_ai.usage.input_tokens'] || result.meta.tokens.inputTokens;\n meta['gen_ai.usage.output_tokens'] = meta['gen_ai.usage.output_tokens'] || result.meta.tokens.outputTokens;\n }\n if (result?.finishReason || result?.finish_reason) {\n meta['gen_ai.response.finish_reason'] = result.finishReason || result.finish_reason;\n }\n return meta;\n },\n },\n {\n name: 'chatStream',\n operation: 'chat.stream',\n getModel: (args) => args[0]?.model,\n extractUsage: () => ({}), // Stream — usage comes in final event\n },\n {\n name: 'generate',\n operation: 'generate',\n getModel: (args) => args[0]?.model,\n extractUsage: (result) => {\n const meta: Record<string, any> = {};\n if (result?.meta?.billedUnits) {\n meta['gen_ai.usage.input_tokens'] = result.meta.billedUnits.inputTokens;\n meta['gen_ai.usage.output_tokens'] = result.meta.billedUnits.outputTokens;\n }\n return meta;\n },\n },\n {\n name: 'embed',\n operation: 'embed',\n getModel: (args) => args[0]?.model,\n extractUsage: (result) => {\n const meta: Record<string, any> = {};\n if (result?.meta?.billedUnits) {\n meta['gen_ai.usage.input_tokens'] = result.meta.billedUnits.inputTokens;\n }\n return meta;\n },\n },\n {\n name: 'rerank',\n operation: 'rerank',\n getModel: (args) => args[0]?.model,\n extractUsage: (result) => {\n const meta: Record<string, any> = {};\n if (result?.meta?.billedUnits) {\n meta['gen_ai.usage.input_tokens'] = result.meta.billedUnits.searchUnits;\n }\n meta['cohere.results_count'] = result?.results?.length;\n return meta;\n },\n },\n {\n name: 'classify',\n operation: 'classify',\n getModel: (args) => args[0]?.model,\n extractUsage: () => ({}),\n },\n {\n name: 'summarize',\n operation: 'summarize',\n getModel: (args) => args[0]?.model,\n extractUsage: (result) => {\n const meta: Record<string, any> = {};\n if (result?.meta?.billedUnits) {\n meta['gen_ai.usage.input_tokens'] = result.meta.billedUnits.inputTokens;\n meta['gen_ai.usage.output_tokens'] = result.meta.billedUnits.outputTokens;\n }\n return meta;\n },\n },\n {\n name: 'tokenize',\n operation: 'tokenize',\n getModel: (args) => args[0]?.model,\n extractUsage: (result) => ({\n 'cohere.token_count': result?.tokens?.length,\n }),\n },\n {\n name: 'detokenize',\n operation: 'detokenize',\n getModel: (args) => args[0]?.model,\n extractUsage: () => ({}),\n },\n];\n\n// ---------------------------------------------------------------------------\n// CohereClient patching\n// ---------------------------------------------------------------------------\n\nconst patchCohereClient = (proto: any, clientName: string, options?: SenzorOptions) => {\n if (!proto) return;\n\n for (const methodConfig of METHODS) {\n if (typeof proto[methodConfig.name] !== 'function') continue;\n\n patchMethod(\n proto,\n methodConfig.name,\n `senzor.cohere.${clientName}.${methodConfig.name}`,\n (original) =>\n function patchedCohereMethod(this: any, ...args: any[]) {\n const model = methodConfig.getModel(args);\n\n const spanName = model\n ? `Cohere ${methodConfig.operation} ${model}`\n : `Cohere ${methodConfig.operation}`;\n\n const span = startCapturedSpan(\n spanName,\n 'http',\n {\n 'gen_ai.system': 'cohere',\n 'gen_ai.operation.name': methodConfig.operation,\n 'gen_ai.request.model': model,\n library: 'cohere',\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, methodConfig.extractUsage(value));\n return value;\n },\n (error: any) => {\n span.end(error?.statusCode || error?.status || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'CohereError',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentCohere = (options?: SenzorOptions) => {\n hookRequire('cohere-ai', (exports: any) => {\n // CohereClient (v1)\n if (exports?.CohereClient?.prototype) {\n patchCohereClient(exports.CohereClient.prototype, 'client', options);\n }\n // CohereClientV2 (v2)\n if (exports?.CohereClientV2?.prototype) {\n patchCohereClient(exports.CohereClientV2.prototype, 'clientV2', options);\n }\n // Default export\n if (exports?.default?.prototype) {\n patchCohereClient(exports.default.prototype, 'default', options);\n }\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Mistral AI SDK Instrumentation\n//\n// Instruments the official `@mistralai/mistralai` package.\n//\n// Mistral SDK architecture: The `Mistral` class has resource namespaces\n// (chat, fim, embeddings, classifiers, models, agents, files, etc.) that\n// each have async methods returning promises.\n//\n// The SDK also has an internal `_request` or `_fetch` method on the base\n// client. We patch both the high-level resource methods AND the internal\n// dispatch for full coverage.\n//\n// Patches:\n// - Mistral.prototype methods (post, get, etc.) — internal HTTP dispatch\n// - chat.complete() / chat.stream() — via resource namespaces\n// - embeddings.create()\n// - fim.complete() / fim.stream()\n// - classifiers.moderate() / classifiers.moderateChat()\n//\n// Captured attributes (OTel GenAI semantic conventions):\n// - gen_ai.system: 'mistral'\n// - gen_ai.request.model: mistral-large, codestral, etc.\n// - gen_ai.operation.name: chat, embeddings, fim, classify\n// - gen_ai.usage.input_tokens: prompt tokens\n// - gen_ai.usage.output_tokens: completion tokens\n// - gen_ai.response.model: actual model from response\n// - gen_ai.response.finish_reason: stop, length, etc.\n// ---------------------------------------------------------------------------\n\n/** Extract token usage from Mistral response. */\nconst extractMistralUsage = (result: any): Record<string, any> => {\n const meta: Record<string, any> = {};\n\n if (result?.usage) {\n meta['gen_ai.usage.input_tokens'] = result.usage.promptTokens ?? result.usage.prompt_tokens;\n meta['gen_ai.usage.output_tokens'] = result.usage.completionTokens ?? result.usage.completion_tokens;\n meta['gen_ai.usage.total_tokens'] = result.usage.totalTokens ?? result.usage.total_tokens;\n }\n\n if (result?.model) {\n meta['gen_ai.response.model'] = result.model;\n }\n\n const finishReason = result?.choices?.[0]?.finishReason\n ?? result?.choices?.[0]?.finish_reason;\n if (finishReason) {\n meta['gen_ai.response.finish_reason'] = finishReason;\n }\n\n return meta;\n};\n\n// ---------------------------------------------------------------------------\n// Resource method patching\n// ---------------------------------------------------------------------------\n\n/** Patch a specific method on a resource namespace object. */\nconst patchResourceMethod = (\n resource: any,\n methodName: string,\n operation: string,\n getModel: (args: any[]) => string | undefined,\n extractUsage: (result: any) => Record<string, any>,\n patchKey: string,\n options?: SenzorOptions\n) => {\n if (!resource || typeof resource[methodName] !== 'function') return;\n\n patchMethod(\n resource,\n methodName,\n patchKey,\n (original) =>\n function patchedMistralMethod(this: any, ...args: any[]) {\n const model = getModel(args);\n const spanName = model\n ? `Mistral ${operation} ${model}`\n : `Mistral ${operation}`;\n\n const span = startCapturedSpan(\n spanName,\n 'http',\n {\n 'gen_ai.system': 'mistral',\n 'gen_ai.operation.name': operation,\n 'gen_ai.request.model': model,\n library: 'mistral',\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, extractUsage(value));\n return value;\n },\n (error: any) => {\n span.end(error?.statusCode || error?.status || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'MistralError',\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n};\n\n// ---------------------------------------------------------------------------\n// Mistral client patching\n// ---------------------------------------------------------------------------\n\nconst patchMistralClient = (mistralModule: any, options?: SenzorOptions) => {\n const Mistral = mistralModule?.Mistral\n || mistralModule?.MistralClient\n || mistralModule?.default;\n\n if (!Mistral || typeof Mistral !== 'function') return;\n\n const proto = Mistral.prototype;\n if (!proto) return;\n\n // Patch internal HTTP methods on the client prototype\n const httpMethods = ['post', 'get', 'put', 'patch', 'delete'] as const;\n for (const method of httpMethods) {\n if (typeof proto[method] !== 'function') continue;\n\n patchMethod(\n proto,\n method,\n `senzor.mistral.client.${method}`,\n (original) =>\n function patchedHttpMethod(this: any, path: string, ...args: any[]) {\n const body = args[0]?.body || args[0];\n const model = body?.model;\n const operation = path?.replace(/^\\/?(v1\\/)?/, '').split('/')[0] || 'api';\n\n const spanName = model\n ? `Mistral ${operation} ${model}`\n : `Mistral ${operation}`;\n\n const span = startCapturedSpan(\n spanName,\n 'http',\n {\n 'gen_ai.system': 'mistral',\n 'gen_ai.operation.name': operation,\n 'gen_ai.request.model': model,\n 'http.request.method': method.toUpperCase(),\n 'url.path': path,\n library: 'mistral',\n },\n options\n );\n\n if (!span) return original.call(this, path, ...args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.call(this, path, ...args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n span.end(0, extractMistralUsage(value));\n return value;\n },\n (error: any) => {\n span.end(error?.status || 500, {\n 'error.message': error?.message,\n });\n throw error;\n }\n );\n }\n\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n\n // Try to patch resource namespaces on instances\n // These are created in the constructor, so we wrap the constructor\n try {\n const tempClient = new Mistral({ apiKey: '__senzor_probe__' });\n\n // Patch chat resource\n if (tempClient.chat) {\n const chatProto = Object.getPrototypeOf(tempClient.chat);\n if (chatProto) {\n patchResourceMethod(chatProto, 'complete', 'chat', (a) => a[0]?.model, extractMistralUsage, 'senzor.mistral.chat.complete', options);\n patchResourceMethod(chatProto, 'stream', 'chat.stream', (a) => a[0]?.model, () => ({}), 'senzor.mistral.chat.stream', options);\n }\n }\n\n // Patch embeddings resource\n if (tempClient.embeddings) {\n const embedProto = Object.getPrototypeOf(tempClient.embeddings);\n if (embedProto) {\n patchResourceMethod(embedProto, 'create', 'embeddings', (a) => a[0]?.model, extractMistralUsage, 'senzor.mistral.embeddings.create', options);\n }\n }\n\n // Patch fim resource\n if ((tempClient as any).fim) {\n const fimProto = Object.getPrototypeOf((tempClient as any).fim);\n if (fimProto) {\n patchResourceMethod(fimProto, 'complete', 'fim', (a) => a[0]?.model, extractMistralUsage, 'senzor.mistral.fim.complete', options);\n patchResourceMethod(fimProto, 'stream', 'fim.stream', (a) => a[0]?.model, () => ({}), 'senzor.mistral.fim.stream', options);\n }\n }\n } catch {\n // Mistral constructor may require a real API key — resource patching is best-effort\n // The HTTP method patches on the prototype still cover all calls\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentMistral = (options?: SenzorOptions) => {\n hookRequire('@mistralai/mistralai', (exports: any) => {\n patchMistralClient(exports, options);\n });\n};\n","import { SenzorOptions } from '../core/types';\nimport { hookRequire } from './hook';\nimport { patchMethod } from './patch';\nimport { runWithCapturedSpan, startCapturedSpan } from './span';\n\n// ---------------------------------------------------------------------------\n// Firebase Admin SDK Instrumentation\n//\n// Instruments `firebase-admin` services:\n// 1. Firestore — document/collection CRUD and queries\n// 2. Auth — user management and token verification\n// 3. Storage — file upload/download operations\n// 4. Messaging (FCM) — push notification delivery\n//\n// Also instruments `firebase-functions` for Cloud Functions triggers.\n//\n// Strategy: Hook each firebase-admin sub-module separately since they're\n// lazy-loaded. Firestore is the most critical — we patch DocumentReference,\n// CollectionReference, Query, and Transaction prototypes.\n//\n// Captured attributes:\n// - db.system.name: 'firestore' (for Firestore ops)\n// - db.operation.name: GET, SET, ADD, UPDATE, DELETE, QUERY\n// - db.collection.name: collection path\n// - firebase.service: 'firestore' | 'auth' | 'storage' | 'messaging'\n// - firebase.operation: specific operation name\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Firestore patching\n// ---------------------------------------------------------------------------\n\n/** Wrap an async Firestore method that returns a promise. */\nconst wrapFirestoreMethod = (\n proto: any,\n methodName: string,\n getSpanInfo: (instance: any, args: any[]) => { name: string; meta: Record<string, any> },\n patchKey: string,\n options?: SenzorOptions\n) => {\n if (!proto || typeof proto[methodName] !== 'function') return;\n\n patchMethod(\n proto,\n methodName,\n patchKey,\n (original) =>\n function patchedFirestoreMethod(this: any, ...args: any[]) {\n const { name, meta } = getSpanInfo(this, args);\n\n const span = startCapturedSpan(name, 'db', meta, options);\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n const endMeta: Record<string, any> = {};\n // DocumentSnapshot\n if (value?.exists !== undefined) {\n endMeta['firestore.exists'] = value.exists;\n }\n // QuerySnapshot\n if (value?.size !== undefined) {\n endMeta['db.response.row_count'] = value.size;\n }\n span.end(0, endMeta);\n return value;\n },\n (error: any) => {\n span.end(error?.code || 500, {\n 'error.message': error?.message,\n 'error.type': error?.name || 'FirestoreError',\n 'db.error.code': error?.code,\n });\n throw error;\n }\n );\n }\n\n // WriteResult (for set, update, delete — they return a WriteResult promise)\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n};\n\n/** Get the collection path from a DocumentReference or CollectionReference. */\nconst getPath = (ref: any): string => {\n try {\n return ref?.path || ref?._path?.toString() || 'unknown';\n } catch {\n return 'unknown';\n }\n};\n\nconst getCollectionName = (ref: any): string => {\n try {\n // For DocumentReference, parent is the collection\n if (ref?.parent?.id) return ref.parent.id;\n // For CollectionReference, id is the collection name\n if (ref?.id) return ref.id;\n // For Query, try _query or _path\n if (ref?._query?._path) return ref._query._path.toString().split('/').pop() || 'unknown';\n return getPath(ref).split('/').filter(Boolean).slice(-2, -1)[0] || 'unknown';\n } catch {\n return 'unknown';\n }\n};\n\nconst patchFirestore = (firestoreModule: any, options?: SenzorOptions) => {\n // --- DocumentReference ---\n const DocRef = firestoreModule?.DocumentReference;\n if (DocRef?.prototype) {\n const docProto = DocRef.prototype;\n\n // get()\n wrapFirestoreMethod(docProto, 'get', (instance) => ({\n name: `Firestore GET ${getPath(instance)}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'GET',\n 'db.collection.name': getCollectionName(instance),\n 'firestore.path': getPath(instance),\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.docRef.get', options);\n\n // set()\n wrapFirestoreMethod(docProto, 'set', (instance) => ({\n name: `Firestore SET ${getPath(instance)}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'SET',\n 'db.collection.name': getCollectionName(instance),\n 'firestore.path': getPath(instance),\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.docRef.set', options);\n\n // update()\n wrapFirestoreMethod(docProto, 'update', (instance) => ({\n name: `Firestore UPDATE ${getPath(instance)}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'UPDATE',\n 'db.collection.name': getCollectionName(instance),\n 'firestore.path': getPath(instance),\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.docRef.update', options);\n\n // delete()\n wrapFirestoreMethod(docProto, 'delete', (instance) => ({\n name: `Firestore DELETE ${getPath(instance)}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'DELETE',\n 'db.collection.name': getCollectionName(instance),\n 'firestore.path': getPath(instance),\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.docRef.delete', options);\n\n // create()\n if (typeof docProto.create === 'function') {\n wrapFirestoreMethod(docProto, 'create', (instance) => ({\n name: `Firestore CREATE ${getPath(instance)}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'CREATE',\n 'db.collection.name': getCollectionName(instance),\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.docRef.create', options);\n }\n }\n\n // --- CollectionReference ---\n const ColRef = firestoreModule?.CollectionReference;\n if (ColRef?.prototype) {\n // add()\n wrapFirestoreMethod(ColRef.prototype, 'add', (instance) => ({\n name: `Firestore ADD ${getPath(instance)}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'ADD',\n 'db.collection.name': getCollectionName(instance),\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.colRef.add', options);\n\n // listDocuments()\n if (typeof ColRef.prototype.listDocuments === 'function') {\n wrapFirestoreMethod(ColRef.prototype, 'listDocuments', (instance) => ({\n name: `Firestore LIST ${getPath(instance)}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'LIST',\n 'db.collection.name': getCollectionName(instance),\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.colRef.listDocuments', options);\n }\n }\n\n // --- Query ---\n const Query = firestoreModule?.Query;\n if (Query?.prototype) {\n wrapFirestoreMethod(Query.prototype, 'get', (instance) => ({\n name: `Firestore QUERY ${getCollectionName(instance)}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'QUERY',\n 'db.collection.name': getCollectionName(instance),\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.query.get', options);\n }\n\n // --- Transaction ---\n const Transaction = firestoreModule?.Transaction;\n if (Transaction?.prototype) {\n for (const method of ['get', 'set', 'update', 'delete', 'create'] as const) {\n if (typeof Transaction.prototype[method] !== 'function') continue;\n // Transaction methods are sync (they queue operations) — except get()\n if (method === 'get') {\n wrapFirestoreMethod(Transaction.prototype, 'get', (_instance, args) => ({\n name: `Firestore TX GET ${getPath(args[0])}`,\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'TX_GET',\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.transaction.get', options);\n }\n }\n }\n\n // --- WriteBatch ---\n const WriteBatch = firestoreModule?.WriteBatch;\n if (WriteBatch?.prototype && typeof WriteBatch.prototype.commit === 'function') {\n wrapFirestoreMethod(WriteBatch.prototype, 'commit', () => ({\n name: 'Firestore BATCH COMMIT',\n meta: {\n 'db.system.name': 'firestore',\n 'db.operation.name': 'BATCH_COMMIT',\n 'firebase.service': 'firestore',\n library: 'firebase-admin',\n },\n }), 'senzor.firebase.writeBatch.commit', options);\n }\n};\n\n// ---------------------------------------------------------------------------\n// Auth patching\n// ---------------------------------------------------------------------------\n\nconst AUTH_METHODS = [\n 'createUser', 'getUser', 'getUserByEmail', 'getUserByPhoneNumber',\n 'listUsers', 'deleteUser', 'deleteUsers', 'updateUser',\n 'verifyIdToken', 'verifySessionCookie', 'createSessionCookie',\n 'revokeRefreshTokens', 'setCustomUserClaims', 'generateEmailVerificationLink',\n 'generatePasswordResetLink', 'generateSignInWithEmailLink',\n] as const;\n\nconst patchFirebaseAuth = (authModule: any, options?: SenzorOptions) => {\n // Auth is typically at auth().* or Auth.prototype\n const Auth = authModule?.Auth;\n if (!Auth?.prototype) return;\n\n for (const method of AUTH_METHODS) {\n if (typeof Auth.prototype[method] !== 'function') continue;\n\n patchMethod(\n Auth.prototype,\n method,\n `senzor.firebase.auth.${method}`,\n (original) =>\n function patchedAuthMethod(this: any, ...args: any[]) {\n const span = startCapturedSpan(\n `Firebase Auth ${method}`,\n 'function',\n {\n 'firebase.service': 'auth',\n 'firebase.operation': method,\n library: 'firebase-admin',\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => { span.end(0); return value; },\n (error: any) => {\n span.end(500, {\n 'error.message': error?.message,\n 'error.type': error?.code || error?.name || 'AuthError',\n });\n throw error;\n }\n );\n }\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Messaging (FCM) patching\n// ---------------------------------------------------------------------------\n\nconst MESSAGING_METHODS = [\n 'send', 'sendEach', 'sendEachForMulticast', 'sendMulticast',\n 'sendToDevice', 'sendToTopic', 'sendToCondition',\n 'subscribeToTopic', 'unsubscribeFromTopic',\n] as const;\n\nconst patchFirebaseMessaging = (messagingModule: any, options?: SenzorOptions) => {\n const Messaging = messagingModule?.Messaging;\n if (!Messaging?.prototype) return;\n\n for (const method of MESSAGING_METHODS) {\n if (typeof Messaging.prototype[method] !== 'function') continue;\n\n patchMethod(\n Messaging.prototype,\n method,\n `senzor.firebase.messaging.${method}`,\n (original) =>\n function patchedMessagingMethod(this: any, ...args: any[]) {\n const span = startCapturedSpan(\n `Firebase FCM ${method}`,\n 'messaging',\n {\n 'firebase.service': 'messaging',\n 'firebase.operation': method,\n 'messaging.system': 'fcm',\n library: 'firebase-admin',\n },\n options\n );\n\n if (!span) return original.apply(this, args);\n\n return runWithCapturedSpan(span, () => {\n try {\n const result = original.apply(this, args);\n if (result && typeof result.then === 'function') {\n return result.then(\n (value: any) => {\n const endMeta: Record<string, any> = {};\n // sendEach/sendMulticast returns BatchResponse\n if (value?.successCount !== undefined) {\n endMeta['firebase.fcm.success_count'] = value.successCount;\n endMeta['firebase.fcm.failure_count'] = value.failureCount;\n }\n span.end(0, endMeta);\n return value;\n },\n (error: any) => {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n );\n }\n span.end(0);\n return result;\n } catch (error: any) {\n span.end(500, { 'error.message': error?.message });\n throw error;\n }\n });\n }\n );\n }\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport const instrumentFirebase = (options?: SenzorOptions) => {\n // Firestore\n hookRequire('firebase-admin/firestore', (exports: any) => {\n patchFirestore(exports, options);\n });\n hookRequire('@google-cloud/firestore', (exports: any) => {\n patchFirestore(exports, options);\n });\n\n // Auth\n hookRequire('firebase-admin/auth', (exports: any) => {\n patchFirebaseAuth(exports, options);\n });\n\n // Messaging\n hookRequire('firebase-admin/messaging', (exports: any) => {\n patchFirebaseMessaging(exports, options);\n });\n\n // firebase-admin main module — try to access services from it\n hookRequire('firebase-admin', (exports: any) => {\n // In newer firebase-admin, services are at exports.firestore, exports.auth, etc.\n // They're getter-based, so accessing them triggers sub-module loading\n // which our hooks above will catch.\n // Just ensure the main module export is patched if it exposes prototypes\n try {\n const firestore = exports?.firestore;\n if (firestore) {\n // This forces the lazy-load, which triggers our hookRequire above\n }\n } catch { }\n });\n};\n","// ---------------------------------------------------------------------------\n// Senzor Lambda Auto-Handler Wrapper\n//\n// This module is the entry point for zero-code-change Lambda Extension Layer\n// deployments. It is referenced as the Lambda function's handler:\n//\n// Handler: @senzops/apm-node/dist/lambda-handler.handler\n//\n// It reads the user's original handler from an environment variable,\n// dynamically loads it, wraps it with Senzor instrumentation, and\n// re-exports the wrapped function.\n//\n// Required environment variables:\n// SENZOR_API_KEY — Senzor API key\n// SENZOR_LAMBDA_HANDLER — Original handler in module.function format\n// (e.g., \"index.handler\", \"src/app.myHandler\")\n//\n// Optional environment variables:\n// All standard SENZOR_* env vars (see register.ts)\n//\n// How it works:\n// 1. Initializes Senzor SDK via the same logic as register.ts\n// 2. Parses SENZOR_LAMBDA_HANDLER into module path + export name\n// 3. Resolves the module from LAMBDA_TASK_ROOT (the function's code dir)\n// 4. Extracts the named export (supports nested paths like \"a.b.c\")\n// 5. Wraps with wrapLambda() for full APM coverage\n// 6. Exports as \"handler\" for Lambda to invoke\n//\n// This gives users the same experience as New Relic / Datadog Lambda Layers:\n// just add the layer, set 2 env vars, zero code changes.\n// ---------------------------------------------------------------------------\n\nimport { client } from './core/client';\nimport { getEnv } from './core/runtime';\nimport { wrapLambda } from './wrappers/lambda';\nimport * as path from 'path';\n\n// ---------------------------------------------------------------------------\n// 1. Initialize Senzor SDK (same logic as register.ts)\n// ---------------------------------------------------------------------------\n\nconst truthy = (value: string | undefined): boolean =>\n value === '1' || value === 'true' || value === 'yes';\n\nconst numberFromEnv = (value: string | undefined): number | undefined => {\n if (!value) return undefined;\n const parsed = Number(value);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n};\n\nconst apiKey =\n getEnv('SENZOR_API_KEY') ||\n getEnv('SENZOR_APM_API_KEY') ||\n getEnv('SENZOR_SERVICE_API_KEY');\n\nconst endpoint =\n getEnv('SENZOR_ENDPOINT') ||\n getEnv('SENZOR_APM_ENDPOINT');\n\nconst isLambda = !!getEnv('AWS_LAMBDA_FUNCTION_NAME');\n\nconst options = {\n apiKey: apiKey || '',\n endpoint,\n debug: truthy(getEnv('SENZOR_DEBUG')),\n autoLogs: getEnv('SENZOR_AUTO_LOGS') === 'false' ? false : undefined,\n batchSize: numberFromEnv(getEnv('SENZOR_BATCH_SIZE')) ?? (isLambda ? 10 : undefined),\n flushInterval: numberFromEnv(getEnv('SENZOR_FLUSH_INTERVAL')) ?? (isLambda ? 0 : undefined),\n flushTimeoutMs: numberFromEnv(getEnv('SENZOR_FLUSH_TIMEOUT_MS')),\n maxQueueSize: numberFromEnv(getEnv('SENZOR_MAX_QUEUE_SIZE')),\n maxSpansPerTrace: numberFromEnv(getEnv('SENZOR_MAX_SPANS_PER_TRACE')),\n captureHeaders: truthy(getEnv('SENZOR_CAPTURE_HEADERS')),\n captureDbStatement:\n getEnv('SENZOR_CAPTURE_DB_STATEMENT') === 'false' ? false : undefined,\n frameworkSpans:\n getEnv('SENZOR_FRAMEWORK_SPANS') === 'false' ? false : undefined,\n captureMiddlewareSpans:\n getEnv('SENZOR_CAPTURE_MIDDLEWARE_SPANS') === 'false' ? false : undefined,\n captureRouterSpans:\n getEnv('SENZOR_CAPTURE_ROUTER_SPANS') === 'false' ? false : undefined,\n captureLifecycleHookSpans:\n getEnv('SENZOR_CAPTURE_LIFECYCLE_HOOK_SPANS') === 'false' ? false : undefined,\n runtimeMetrics:\n getEnv('SENZOR_RUNTIME_METRICS') === 'false' || isLambda ? false : undefined,\n runtimeMetricsInterval: numberFromEnv(getEnv('SENZOR_RUNTIME_METRICS_INTERVAL')),\n};\n\nif (apiKey) {\n client.init(options);\n} else {\n client.preload(options);\n}\n\n// ---------------------------------------------------------------------------\n// 2. Resolve and wrap the user's original handler\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a Lambda handler string into module path and function path.\n *\n * Examples:\n * \"index.handler\" → { modulePath: \"index\", fnPath: [\"handler\"] }\n * \"src/app.myHandler\" → { modulePath: \"src/app\", fnPath: [\"myHandler\"] }\n * \"dist/handlers.api.get\" → { modulePath: \"dist/handlers\", fnPath: [\"api\", \"get\"] }\n *\n * Lambda convention: everything before the LAST dot that isn't part of a\n * directory path is the module, everything after is the function path.\n * Since module paths can contain dots in directory names, we split on the\n * last dot after the last path separator.\n */\nconst parseHandlerString = (handlerStr: string): { modulePath: string; fnPath: string[] } => {\n const lastSlash = Math.max(handlerStr.lastIndexOf('/'), handlerStr.lastIndexOf('\\\\'));\n const afterSlash = lastSlash >= 0 ? handlerStr.substring(lastSlash + 1) : handlerStr;\n const beforeSlash = lastSlash >= 0 ? handlerStr.substring(0, lastSlash + 1) : '';\n\n const firstDot = afterSlash.indexOf('.');\n if (firstDot < 0) {\n // No dot — treat the whole thing as the module, export \"handler\"\n return { modulePath: handlerStr, fnPath: ['handler'] };\n }\n\n const moduleName = afterSlash.substring(0, firstDot);\n const fnParts = afterSlash.substring(firstDot + 1).split('.');\n\n return {\n modulePath: beforeSlash + moduleName,\n fnPath: fnParts,\n };\n};\n\n/**\n * Resolve a handler export from a module given a function path.\n * Supports nested exports: [\"api\", \"get\"] resolves module.api.get\n */\nconst resolveExport = (moduleExports: any, fnPath: string[]): Function | null => {\n let current = moduleExports;\n\n for (const part of fnPath) {\n if (current == null || typeof current !== 'object') return null;\n current = current[part];\n }\n\n // Also check .default for ESM interop\n if (current == null && moduleExports?.default) {\n current = moduleExports.default;\n for (const part of fnPath) {\n if (current == null || typeof current !== 'object') return null;\n current = current[part];\n }\n }\n\n return typeof current === 'function' ? current : null;\n};\n\n/**\n * Load the user's original handler module. Tries multiple resolution strategies:\n * 1. Absolute path from LAMBDA_TASK_ROOT\n * 2. require() with the module path as-is (for node_modules)\n * 3. With common extensions (.js, .mjs, .cjs)\n */\nconst loadHandlerModule = (modulePath: string): any => {\n const taskRoot = process.env.LAMBDA_TASK_ROOT || process.cwd();\n const absolutePath = path.resolve(taskRoot, modulePath);\n\n // Strategy 1: Direct absolute path\n try {\n return require(absolutePath);\n } catch { }\n\n // Strategy 2: With extensions\n const extensions = ['.js', '.cjs', '.mjs'];\n for (const ext of extensions) {\n try {\n return require(absolutePath + ext);\n } catch { }\n }\n\n // Strategy 3: Module as-is (may be in node_modules or an absolute path)\n try {\n return require(modulePath);\n } catch { }\n\n return null;\n};\n\n// ---------------------------------------------------------------------------\n// 3. Build and export the wrapped handler\n// ---------------------------------------------------------------------------\n\nconst handlerEnv = getEnv('SENZOR_LAMBDA_HANDLER');\n\nlet wrappedHandler: Function;\n\nif (!handlerEnv) {\n // No handler configured — export a diagnostic handler that returns an error\n wrappedHandler = async () => {\n const message =\n 'Senzor Lambda Layer: SENZOR_LAMBDA_HANDLER environment variable is not set. ' +\n 'Set it to your original handler (e.g., \"index.handler\") and set the Lambda ' +\n 'function handler to \"@senzops/apm-node/dist/lambda-handler.handler\".';\n\n console.error(`[Senzor] ${message}`);\n\n return {\n statusCode: 500,\n body: JSON.stringify({ error: message }),\n };\n };\n} else {\n const { modulePath, fnPath } = parseHandlerString(handlerEnv);\n const handlerModule = loadHandlerModule(modulePath);\n\n if (!handlerModule) {\n const errorMsg = `Senzor Lambda Layer: Could not load handler module \"${modulePath}\" ` +\n `(from SENZOR_LAMBDA_HANDLER=\"${handlerEnv}\"). Verify the module path exists ` +\n `relative to your Lambda function code.`;\n\n console.error(`[Senzor] ${errorMsg}`);\n\n wrappedHandler = async () => ({\n statusCode: 500,\n body: JSON.stringify({ error: errorMsg }),\n });\n } else {\n const originalHandler = resolveExport(handlerModule, fnPath);\n\n if (!originalHandler) {\n const errorMsg = `Senzor Lambda Layer: Module \"${modulePath}\" loaded successfully ` +\n `but export \"${fnPath.join('.')}\" is not a function. ` +\n `Available exports: ${Object.keys(handlerModule).join(', ')}`;\n\n console.error(`[Senzor] ${errorMsg}`);\n\n wrappedHandler = async () => ({\n statusCode: 500,\n body: JSON.stringify({ error: errorMsg }),\n });\n } else {\n // Success — wrap the handler with full Senzor APM instrumentation\n wrappedHandler = wrapLambda(originalHandler as any);\n\n if (truthy(getEnv('SENZOR_DEBUG'))) {\n console.log(\n `[Senzor] Lambda handler wrapped: ${handlerEnv} → ` +\n `module=\"${modulePath}\", export=\"${fnPath.join('.')}\"`,\n );\n }\n }\n }\n}\n\n/**\n * The wrapped Lambda handler. Configure your Lambda function to use:\n *\n * Handler: @senzops/apm-node/dist/lambda-handler.handler\n *\n * And set environment variables:\n *\n * SENZOR_API_KEY=sz_apm_xxx\n * SENZOR_LAMBDA_HANDLER=index.handler\n */\nexport const handler = wrappedHandler;\n","import { SENZOR_INTERNAL_HEADER } from '../utils/internal';\nimport { SenzorOptions, Trace, TaskRun, SenzorError, SenzorLog } from './types';\nimport type { RuntimeMetricsPayload } from '../instrumentation/runtime';\n\ninterface ApmPayload {\n traces: Trace[];\n errors: SenzorError[];\n logs: SenzorLog[];\n runtimeMetrics?: RuntimeMetricsPayload[];\n}\n\ninterface TaskPayload {\n runs: TaskRun[];\n errors: SenzorError[];\n logs: SenzorLog[];\n}\n\nexport class Transport {\n private traceQueue: Trace[] = [];\n private apmErrorQueue: SenzorError[] = [];\n private apmLogQueue: SenzorLog[] = [];\n private runtimeMetricsQueue: RuntimeMetricsPayload[] = [];\n\n private taskQueue: TaskRun[] = [];\n private taskErrorQueue: SenzorError[] = [];\n private taskLogQueue: SenzorLog[] = [];\n\n private timer: ReturnType<typeof setInterval> | null = null;\n private timerStarted = false;\n private apmEndpoint: string;\n private taskEndpoint: string;\n private isFlushing = false;\n private flushAgain = false;\n private droppedItems = 0;\n\n constructor(private config: SenzorOptions) {\n const baseEndpoint = config.endpoint || 'https://api.senzor.dev';\n this.apmEndpoint = baseEndpoint.includes('/api/ingest')\n ? baseEndpoint\n : `${baseEndpoint}/api/ingest/apm`;\n this.taskEndpoint = baseEndpoint.includes('/api/ingest')\n ? baseEndpoint.replace('/apm', '/task')\n : `${baseEndpoint}/api/ingest/task`;\n\n // Timer and shutdown flush are deferred to first enqueue.\n // Cloudflare Workers forbids setInterval / process access in global scope,\n // and init() may be called at module evaluation time (e.g. Nitro plugins).\n }\n\n private ensureTimer() {\n if (this.timerStarted) return;\n this.timerStarted = true;\n\n try {\n if (typeof setInterval !== 'undefined') {\n this.timer = setInterval(\n () => void this.flush(),\n this.config.flushInterval || 10000\n );\n if (this.timer && typeof (this.timer as any).unref === 'function') {\n (this.timer as any).unref();\n }\n }\n } catch {}\n\n this.installShutdownFlush();\n }\n\n public addTrace(trace: any) {\n this.enqueue(this.traceQueue, trace);\n this.checkFlush();\n }\n\n public addTask(task: TaskRun) {\n this.enqueue(this.taskQueue, task);\n this.checkFlush();\n }\n\n public addError(error: SenzorError, type: 'apm' | 'task' = 'apm') {\n this.enqueue(\n type === 'task' ? this.taskErrorQueue : this.apmErrorQueue,\n error\n );\n this.checkFlush();\n }\n\n public addLog(log: SenzorLog, type: 'apm' | 'task' = 'apm') {\n this.enqueue(\n type === 'task' ? this.taskLogQueue : this.apmLogQueue,\n log\n );\n this.checkFlush();\n }\n\n public addRuntimeMetrics(payload: RuntimeMetricsPayload) {\n this.enqueue(this.runtimeMetricsQueue, payload);\n // Runtime metrics don't trigger immediate flush — they ride the next timer\n }\n\n private enqueue<T>(queue: T[], item: T) {\n this.ensureTimer();\n queue.push(item);\n\n const maxQueueSize = this.config.maxQueueSize ?? 10000;\n while (queue.length > maxQueueSize) {\n queue.shift();\n this.droppedItems++;\n }\n }\n\n private prependWithLimit<T>(queue: T[], items: T[]) {\n if (!items.length) return;\n queue.unshift(...items);\n\n const maxQueueSize = this.config.maxQueueSize ?? 10000;\n while (queue.length > maxQueueSize) {\n queue.pop();\n this.droppedItems++;\n }\n }\n\n private checkFlush() {\n const totalApm =\n this.traceQueue.length +\n this.apmErrorQueue.length +\n this.apmLogQueue.length;\n const totalTask =\n this.taskQueue.length +\n this.taskErrorQueue.length +\n this.taskLogQueue.length;\n\n if (\n totalApm >= (this.config.batchSize || 100) ||\n totalTask >= (this.config.batchSize || 100)\n ) {\n void this.flush();\n }\n }\n\n private takeApmPayload(): ApmPayload {\n const payload: ApmPayload = {\n traces: this.traceQueue,\n errors: this.apmErrorQueue,\n logs: this.apmLogQueue,\n };\n\n if (this.runtimeMetricsQueue.length > 0) {\n payload.runtimeMetrics = this.runtimeMetricsQueue;\n this.runtimeMetricsQueue = [];\n }\n\n this.traceQueue = [];\n this.apmErrorQueue = [];\n this.apmLogQueue = [];\n return payload;\n }\n\n private takeTaskPayload(): TaskPayload {\n const payload = {\n runs: this.taskQueue,\n errors: this.taskErrorQueue,\n logs: this.taskLogQueue\n };\n\n this.taskQueue = [];\n this.taskErrorQueue = [];\n this.taskLogQueue = [];\n return payload;\n }\n\n private restoreApmPayload(payload: ApmPayload) {\n this.prependWithLimit(this.apmLogQueue, payload.logs);\n this.prependWithLimit(this.apmErrorQueue, payload.errors);\n this.prependWithLimit(this.traceQueue, payload.traces);\n if (payload.runtimeMetrics) {\n this.prependWithLimit(this.runtimeMetricsQueue, payload.runtimeMetrics);\n }\n }\n\n private restoreTaskPayload(payload: TaskPayload) {\n this.prependWithLimit(this.taskLogQueue, payload.logs);\n this.prependWithLimit(this.taskErrorQueue, payload.errors);\n this.prependWithLimit(this.taskQueue, payload.runs);\n }\n\n private hasApmPayload(payload: ApmPayload): boolean {\n return (\n payload.traces.length > 0 ||\n payload.errors.length > 0 ||\n payload.logs.length > 0 ||\n (payload.runtimeMetrics?.length ?? 0) > 0\n );\n }\n\n private hasTaskPayload(payload: TaskPayload): boolean {\n return (\n payload.runs.length > 0 ||\n payload.errors.length > 0 ||\n payload.logs.length > 0\n );\n }\n\n private async postJson(endpoint: string, payload: unknown) {\n const controller = new AbortController();\n const timeout = setTimeout(\n () => controller.abort(),\n this.config.flushTimeoutMs ?? 5000\n );\n\n if (typeof timeout.unref === 'function') timeout.unref();\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-service-api-key': this.config.apiKey,\n [SENZOR_INTERNAL_HEADER]: 'true'\n },\n body: JSON.stringify(payload),\n keepalive: true,\n signal: controller.signal\n });\n\n if (!response.ok) {\n throw new Error(`Senzor ingest failed with status ${response.status}`);\n }\n } finally {\n clearTimeout(timeout);\n }\n }\n\n public async flush() {\n if (this.isFlushing) {\n this.flushAgain = true;\n return;\n }\n\n this.isFlushing = true;\n\n try {\n do {\n this.flushAgain = false;\n\n const apmPayload = this.takeApmPayload();\n const taskPayload = this.takeTaskPayload();\n const sends: Promise<void>[] = [];\n\n if (this.hasApmPayload(apmPayload)) {\n sends.push(\n this.postJson(this.apmEndpoint, apmPayload).catch((error) => {\n this.restoreApmPayload(apmPayload);\n throw error;\n })\n );\n }\n\n if (this.hasTaskPayload(taskPayload)) {\n sends.push(\n this.postJson(this.taskEndpoint, taskPayload).catch((error) => {\n this.restoreTaskPayload(taskPayload);\n throw error;\n })\n );\n }\n\n if (!sends.length) continue;\n\n const results = await Promise.allSettled(sends);\n const failures = results.filter(\n (result) => result.status === 'rejected'\n );\n\n if (this.config.debug) {\n console.log(\n `[Senzor] Flushed: APM(${apmPayload.traces.length} traces, ${apmPayload.logs.length} logs), Task(${taskPayload.runs.length} runs, ${taskPayload.logs.length} logs), failures=${failures.length}, dropped=${this.droppedItems}`\n );\n }\n } while (this.flushAgain);\n } catch (err) {\n if (this.config.debug) console.error('[Senzor] Transport Flush Error:', err);\n } finally {\n this.isFlushing = false;\n }\n }\n\n private installShutdownFlush() {\n if (typeof process === 'undefined' || typeof process.once !== 'function') return;\n\n const key = Symbol.for('senzor.transport.shutdownFlushInstalled');\n const proc = process as unknown as Record<symbol, boolean>;\n if (proc[key]) return;\n\n Object.defineProperty(proc, key, {\n value: true,\n enumerable: false\n });\n\n const flushSyncBestEffort = () => {\n void this.flush();\n };\n\n process.once('beforeExit', flushSyncBestEffort);\n }\n}\n","import { Transport } from './transport';\r\nimport { Context } from './context';\r\nimport { SenzorOptions, ActiveTrace, TaskRun, SenzorLog } from './types';\r\nimport { isNode } from './runtime';\r\nimport { SDK_META } from '../utils/sdkMeta';\r\nimport { parseTraceparent } from '../utils/traceContext';\r\nimport { generateSpanId, generateTraceId } from '../utils/ids';\r\nimport { sanitizeAttributes } from './sanitizer';\r\nimport { startCapturedSpan } from '../instrumentation/span';\r\nimport { RuntimeMetricsCollector } from '../instrumentation/runtime';\r\n\r\n// Memory-safe JSON stringifier to handle cyclical objects \r\n// (like Express 'req' objects) passed into console.log\r\nconst safeStringify = (obj: any): string => {\r\n const cache = new Set();\r\n return JSON.stringify(obj, (key, value) => {\r\n if (typeof value === 'object' && value !== null) {\r\n if (cache.has(value)) return '[Circular]';\r\n cache.add(value);\r\n }\r\n return value;\r\n });\r\n};\r\n\r\nexport class SenzorClient {\r\n private transport: Transport | null = null;\r\n private options: SenzorOptions | null = null;\r\n private isInstrumented = false;\r\n private runtimeMetricsCollector: RuntimeMetricsCollector | null = null;\r\n\r\n public preload(options: Partial<SenzorOptions> = {}) {\r\n const endpoint = options.endpoint || 'https://api.senzor.dev/api/ingest/apm';\r\n const debug = options.debug || false;\r\n\r\n this.options = {\r\n apiKey: '',\r\n ...this.options,\r\n ...options\r\n };\r\n\r\n this.installNativeInstrumentations(endpoint, debug);\r\n }\r\n\r\n public init(options: SenzorOptions) {\r\n if (!options.apiKey) {\r\n console.warn('[Senzor] API Key missing. SDK disabled.');\r\n return;\r\n }\r\n this.options = options;\r\n const endpoint = options.endpoint || 'https://api.senzor.dev/api/ingest/apm';\r\n const debug = options.debug || false;\r\n\r\n this.transport = new Transport({ ...options, endpoint });\r\n this.installNativeInstrumentations(endpoint, debug);\r\n }\r\n\r\n private isInstrumentationEnabled(name: string): boolean {\r\n const setting = this.options?.instrumentations;\r\n if (setting === false) return false;\r\n if (Array.isArray(setting)) return setting.includes(name);\r\n return true;\r\n }\r\n\r\n private installNativeInstrumentations(endpoint: string, debug: boolean) {\r\n if (this.isInstrumented) return;\r\n\r\n this.setupGlobalErrorHandlers();\r\n this.setupLogInterception();\r\n\r\n // Fetch instrumentation works on all runtimes (Workers, Node, Bun, Deno)\r\n try {\r\n if (this.isInstrumentationEnabled('fetch')) {\r\n const { instrumentFetch } = require('../instrumentation/http');\r\n instrumentFetch(endpoint, this.options || undefined);\r\n }\r\n } catch {}\r\n\r\n // Node-only instrumentations: http, module hooking, db drivers, etc.\r\n if (isNode()) {\r\n try { if (this.isInstrumentationEnabled('http')) { const { instrumentHttp } = require('../instrumentation/http'); instrumentHttp(this, endpoint, this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('express')) { const { instrumentExpress } = require('../instrumentation/express'); instrumentExpress(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('fastify')) { const { instrumentFastify } = require('../instrumentation/fastify'); instrumentFastify(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('koa')) { const { instrumentKoa } = require('../instrumentation/koa'); instrumentKoa(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('undici')) { const { instrumentUndici } = require('../instrumentation/undici'); instrumentUndici(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('mongo')) { const { instrumentMongo } = require('../instrumentation/mongo'); instrumentMongo(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('mongoose')) { const { instrumentMongoose } = require('../instrumentation/mongoose'); instrumentMongoose(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('pg')) { const { instrumentPg } = require('../instrumentation/pg'); instrumentPg(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('mysql')) { const { instrumentMysql } = require('../instrumentation/mysql'); instrumentMysql(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('redis')) { const { instrumentRedis } = require('../instrumentation/redis'); instrumentRedis(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('bullmq')) { const { instrumentBullMQ } = require('../instrumentation/bullmq'); instrumentBullMQ(this, debug); } } catch {}\r\n try { if (this.isInstrumentationEnabled('cron')) { const { instrumentNodeCron } = require('../instrumentation/cron'); instrumentNodeCron(this, debug); } } catch {}\r\n\r\n // --- Phase 1 Instrumentations ---\r\n try { if (this.isInstrumentationEnabled('grpc')) { const { instrumentGrpc } = require('../instrumentation/grpc'); instrumentGrpc(this, this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('graphql')) { const { instrumentGraphQL } = require('../instrumentation/graphql'); instrumentGraphQL(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('dns')) { const { instrumentDns } = require('../instrumentation/dns'); instrumentDns(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('net')) { const { instrumentNet } = require('../instrumentation/net'); instrumentNet(this.options || undefined); } } catch {}\r\n\r\n // --- Phase 2 Instrumentations: Messaging ---\r\n try { if (this.isInstrumentationEnabled('kafka')) { const { instrumentKafka } = require('../instrumentation/kafka'); instrumentKafka(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('amqplib')) { const { instrumentAmqplib } = require('../instrumentation/amqplib'); instrumentAmqplib(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('socketio')) { const { instrumentSocketIO } = require('../instrumentation/socketio'); instrumentSocketIO(this.options || undefined); } } catch {}\r\n\r\n // --- Phase 3 Instrumentations: Frameworks & Log Correlation ---\r\n try { if (this.isInstrumentationEnabled('nestjs')) { const { instrumentNestJS } = require('../instrumentation/nestjs'); instrumentNestJS(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('hapi')) { const { instrumentHapi } = require('../instrumentation/hapi'); instrumentHapi(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('pino')) { const { instrumentPino } = require('../instrumentation/pino'); instrumentPino(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('winston')) { const { instrumentWinston } = require('../instrumentation/winston'); instrumentWinston(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('bunyan')) { const { instrumentBunyan } = require('../instrumentation/bunyan'); instrumentBunyan(this.options || undefined); } } catch {}\r\n\r\n // --- Phase 4 Instrumentations: Cloud & Database ---\r\n try { if (this.isInstrumentationEnabled('aws-sdk')) { const { instrumentAwsSdk } = require('../instrumentation/aws-sdk'); instrumentAwsSdk(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('knex')) { const { instrumentKnex } = require('../instrumentation/knex'); instrumentKnex(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('tedious')) { const { instrumentTedious } = require('../instrumentation/tedious'); instrumentTedious(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('cassandra')) { const { instrumentCassandra } = require('../instrumentation/cassandra'); instrumentCassandra(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('memcached')) { const { instrumentMemcached } = require('../instrumentation/memcached'); instrumentMemcached(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('generic-pool')) { const { instrumentGenericPool } = require('../instrumentation/generic-pool'); instrumentGenericPool(this.options || undefined); } } catch {}\r\n\r\n // --- Phase 5 Instrumentations: Frameworks, Utilities & AI ---\r\n try { if (this.isInstrumentationEnabled('restify')) { const { instrumentRestify } = require('../instrumentation/restify'); instrumentRestify(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('connect')) { const { instrumentConnect } = require('../instrumentation/connect'); instrumentConnect(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('dataloader')) { const { instrumentDataloader } = require('../instrumentation/dataloader'); instrumentDataloader(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('lru-memoizer')) { const { instrumentLruMemoizer } = require('../instrumentation/lru-memoizer'); instrumentLruMemoizer(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('fs')) { const { instrumentFs } = require('../instrumentation/fs'); instrumentFs(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('openai')) { const { instrumentOpenAI } = require('../instrumentation/openai'); instrumentOpenAI(this.options || undefined); } } catch {}\r\n\r\n // --- Phase 6 Instrumentations: AI SDKs & Firebase ---\r\n try { if (this.isInstrumentationEnabled('anthropic')) { const { instrumentAnthropic } = require('../instrumentation/anthropic'); instrumentAnthropic(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('google-genai')) { const { instrumentGoogleGenAI } = require('../instrumentation/google-genai'); instrumentGoogleGenAI(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('azure-openai')) { const { instrumentAzureOpenAI } = require('../instrumentation/azure-openai'); instrumentAzureOpenAI(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('cohere')) { const { instrumentCohere } = require('../instrumentation/cohere'); instrumentCohere(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('mistral')) { const { instrumentMistral } = require('../instrumentation/mistral'); instrumentMistral(this.options || undefined); } } catch {}\r\n try { if (this.isInstrumentationEnabled('firebase')) { const { instrumentFirebase } = require('../instrumentation/firebase'); instrumentFirebase(this.options || undefined); } } catch {}\r\n\r\n // --- Runtime Metrics ---\r\n if (this.options?.runtimeMetrics !== false && this.transport) {\r\n try {\r\n this.runtimeMetricsCollector = new RuntimeMetricsCollector({\r\n interval: this.options?.runtimeMetricsInterval ?? 15000,\r\n onMetrics: (payload) => {\r\n this.transport?.addRuntimeMetrics(payload);\r\n },\r\n });\r\n this.runtimeMetricsCollector.start();\r\n } catch {}\r\n }\r\n }\r\n\r\n this.isInstrumented = true;\r\n if (debug) console.log('[Senzor] Auto-instrumentation enabled');\r\n }\r\n\r\n // --- Enterprise Auto-Log Interception ---\r\n private setupLogInterception() {\r\n if (this.options?.autoLogs === false) return; // Opt-out check\r\n\r\n const levels = ['log', 'info', 'warn', 'error', 'debug'] as const;\r\n const originalConsole = {\r\n log: console.log,\r\n info: console.info,\r\n warn: console.warn,\r\n error: console.error,\r\n debug: console.debug\r\n };\r\n\r\n let isIntercepting = false; // Lock to prevent SDK internal logs from looping infinitely\r\n\r\n levels.forEach(level => {\r\n console[level] = (...args: any[]) => {\r\n // Always execute original console so user's terminal isn't broken\r\n originalConsole[level].apply(console, args);\r\n\r\n if (isIntercepting || !this.transport) return;\r\n isIntercepting = true;\r\n\r\n try {\r\n let message = '';\r\n let attributes: Record<string, any> = {};\r\n\r\n args.forEach(arg => {\r\n if (typeof arg === 'string') {\r\n message += (message ? ' ' : '') + arg;\r\n } else if (arg instanceof Error) {\r\n message += (message ? ' ' : '') + arg.message;\r\n attributes.errorStack = arg.stack;\r\n attributes.errorName = arg.name;\r\n } else if (typeof arg === 'object' && arg !== null) {\r\n try {\r\n // New Relic Style Destructuring: Merge all object keys into `attributes`\r\n const parsed = JSON.parse(safeStringify(arg));\r\n attributes = { ...attributes, ...sanitizeAttributes(parsed, this.options || undefined) };\r\n } catch (e) {\r\n attributes.unparseableObject = true;\r\n }\r\n } else {\r\n message += (message ? ' ' : '') + String(arg);\r\n }\r\n });\r\n\r\n // Fallback if the user purely logged an object without text e.g., console.log({ user: 123 })\r\n if (!message && Object.keys(attributes).length > 0) {\r\n message = 'Object Log';\r\n }\r\n\r\n // Attach to Active Context seamlessly (Works for BOTH APM and Tasks!)\r\n const currentTrace = Context.current();\r\n const logType = currentTrace?.contextType === 'task' ? 'task' : 'apm';\r\n\r\n const logPayload: SenzorLog = {\r\n message: message || 'Empty log',\r\n level: level === 'log' ? 'info' : level, // Map generic log -> info\r\n attributes,\r\n timestamp: new Date().toISOString()\r\n };\r\n\r\n // Attach the specific contextual ID\r\n if (currentTrace) {\r\n if (logType === 'task') logPayload.runId = currentTrace.id;\r\n else logPayload.traceId = currentTrace.id;\r\n }\r\n\r\n this.transport.addLog(logPayload, logType);\r\n } catch (e) {\r\n // Absolute failure isolation. Never crash host app during logging.\r\n } finally {\r\n isIntercepting = false; // Release lock\r\n }\r\n };\r\n });\r\n }\r\n\r\n private setupGlobalErrorHandlers() {\r\n if (!isNode()) return;\r\n\r\n if ((process as any).__senzorGlobalHandlersInstalled) {\r\n return;\r\n }\r\n\r\n (process as any).__senzorGlobalHandlersInstalled = true;\r\n\r\n const getProcessContext = () => {\r\n try {\r\n return {\r\n pid: process.pid,\r\n ppid: process.ppid,\r\n platform: process.platform,\r\n uptimeSec: Math.floor(process.uptime()),\r\n env: process.env.NODE_ENV || 'unknown'\r\n };\r\n } catch {\r\n return {};\r\n }\r\n };\r\n\r\n const getMemoryContext = () => {\r\n try {\r\n const mem = process.memoryUsage();\r\n return {\r\n rss: mem.rss,\r\n heapTotal: mem.heapTotal,\r\n heapUsed: mem.heapUsed,\r\n external: mem.external,\r\n arrayBuffers: mem.arrayBuffers\r\n };\r\n } catch {\r\n return {};\r\n }\r\n };\r\n\r\n const safeCapture = (error: unknown, meta: any = {}) => {\r\n try {\r\n let parsedError: Error;\r\n if (error instanceof Error) {\r\n parsedError = error;\r\n } else if (typeof error === 'string') {\r\n parsedError = new Error(error);\r\n } else {\r\n try {\r\n parsedError = new Error(JSON.stringify(error));\r\n } catch {\r\n parsedError = new Error('Non-serializable rejection reason');\r\n }\r\n }\r\n const enrichedMeta = {\r\n ...meta,\r\n runtime: { name: 'node', version: process.version },\r\n process: getProcessContext(),\r\n memory: getMemoryContext(),\r\n sdk: { name: SDK_META.name, version: SDK_META.version }\r\n };\r\n\r\n this.captureError(parsedError, enrichedMeta);\r\n } catch (internalFailure) {\r\n try {\r\n if (this.options?.debug) {\r\n console.error('[Senzor] Error handler failure:', internalFailure);\r\n }\r\n } catch { }\r\n }\r\n };\r\n\r\n process.on('uncaughtExceptionMonitor', (error) => safeCapture(error, { type: 'uncaughtExceptionMonitor', severity: 'fatal' }));\r\n process.on('uncaughtException', (error) => safeCapture(error, { type: 'uncaughtException', severity: 'fatal' }));\r\n process.on('unhandledRejection', (reason) => safeCapture(reason, { type: 'unhandledRejection', severity: 'error' }));\r\n process.on('warning', (warning) => safeCapture(warning, { type: 'processWarning', severity: 'warning' }));\r\n process.on('multipleResolves', (type, promise, reason) => safeCapture(reason || new Error('Multiple promise resolves'), { type: 'multipleResolves', resolveType: type, severity: 'warning' }));\r\n process.on('rejectionHandled', (promise) => { if (this.options?.debug) { try { console.warn('[Senzor] rejectionHandled event detected'); } catch { } } });\r\n process.on('SIGTERM', () => safeCapture(new Error('Process received SIGTERM'), { type: 'processSignal', signal: 'SIGTERM' }));\r\n process.on('SIGINT', () => safeCapture(new Error('Process received SIGINT'), { type: 'processSignal', signal: 'SIGINT' }));\r\n }\r\n\r\n public startTrace<T>(data: Partial<ActiveTrace['data']> & { headers?: any }, next: () => T): T {\r\n if (!this.transport) return next();\r\n\r\n const existingTrace = Context.current();\r\n if (existingTrace?.contextType === 'apm') {\r\n Object.assign(existingTrace.data, data);\r\n return next();\r\n }\r\n\r\n let inheritedTraceId: string | undefined = undefined;\r\n let inheritedParentSpanId: string | undefined = undefined;\r\n\r\n if (data.headers) {\r\n const getHeader = (key: string) => {\r\n if (data.headers[key]) return data.headers[key];\r\n if (data.headers[key.toLowerCase()]) return data.headers[key.toLowerCase()];\r\n return undefined;\r\n };\r\n\r\n const traceparent = getHeader('traceparent');\r\n const parsedContext = parseTraceparent(traceparent);\r\n\r\n if (parsedContext) {\r\n inheritedTraceId = parsedContext.traceId;\r\n inheritedParentSpanId = parsedContext.parentSpanId;\r\n } else {\r\n const rawTrace = getHeader('x-senzor-trace-id');\r\n const rawSpan = getHeader('x-senzor-parent-span-id');\r\n inheritedTraceId = Array.isArray(rawTrace) ? rawTrace[0] : rawTrace;\r\n inheritedParentSpanId = Array.isArray(rawSpan) ? rawSpan[0] : rawSpan;\r\n }\r\n }\r\n\r\n const activeTraceId = inheritedTraceId || generateTraceId();\r\n const rootSpanId = generateSpanId();\r\n\r\n const trace: ActiveTrace = {\r\n id: activeTraceId,\r\n contextType: 'apm',\r\n startTime: performance.now(),\r\n rootSpanId,\r\n activeSpanId: rootSpanId,\r\n data: { ...data, parentTraceId: inheritedTraceId, parentSpanId: inheritedParentSpanId, rootSpanId },\r\n spans: [],\r\n maxSpans: this.options?.maxSpansPerTrace ?? 500,\r\n state: {\r\n ended: false,\r\n droppedSpans: 0\r\n }\r\n };\r\n\r\n return Context.run(trace, next);\r\n }\r\n\r\n public endTrace(status: number, extraData: any = {}) {\r\n const trace = Context.current();\r\n if (!trace || trace.contextType !== 'apm' || !this.transport) return;\r\n if (trace.state.ended) return;\r\n trace.state.ended = true;\r\n const duration = performance.now() - trace.startTime;\r\n\r\n const payload = {\r\n traceId: trace.id,\r\n parentTraceId: trace.data.parentTraceId,\r\n parentSpanId: trace.data.parentSpanId,\r\n rootSpanId: trace.rootSpanId,\r\n ...trace.data,\r\n ...extraData,\r\n status,\r\n duration,\r\n spans: trace.spans,\r\n droppedSpans: trace.state.droppedSpans,\r\n timestamp: new Date().toISOString()\r\n };\r\n this.transport.addTrace(payload);\r\n }\r\n\r\n // --- TASK MONITORING METHODS ---\r\n public startTask<T>(name: string, type: 'cron' | 'queue' | 'pipeline' | 'custom', options: any, next: () => T): T {\r\n if (!this.transport) return next();\r\n\r\n const currentContext = Context.current();\r\n const triggerTraceId = currentContext?.contextType === 'apm' ? currentContext.id : undefined;\r\n\r\n const startMemory = isNode() && process.memoryUsage ? process.memoryUsage().heapUsed : 0;\r\n const startCpu = isNode() && process.cpuUsage ? process.cpuUsage() : undefined;\r\n\r\n const task: ActiveTrace = {\r\n id: generateTraceId(),\r\n contextType: 'task',\r\n startTime: performance.now(),\r\n rootSpanId: generateSpanId(),\r\n startMemory,\r\n startCpu,\r\n data: { taskName: name, taskType: type, triggerTraceId, ...options },\r\n spans: [],\r\n maxSpans: this.options?.maxSpansPerTrace ?? 500,\r\n state: {\r\n ended: false,\r\n droppedSpans: 0\r\n }\r\n };\r\n task.activeSpanId = task.rootSpanId;\r\n return Context.run(task, next);\r\n }\r\n\r\n public endTask(status: 'success' | 'failed', extraMetadata: any = {}) {\r\n const task = Context.current();\r\n if (!task || task.contextType !== 'task' || !this.transport) return;\r\n if (task.state.ended) return;\r\n task.state.ended = true;\r\n\r\n let resourceMetrics;\r\n if (isNode() && process.memoryUsage && task.startMemory !== undefined && process.cpuUsage && task.startCpu) {\r\n const endMemory = process.memoryUsage().heapUsed;\r\n const cpuDelta = process.cpuUsage(task.startCpu);\r\n\r\n resourceMetrics = {\r\n memoryDeltaBytes: endMemory - task.startMemory,\r\n cpuUserUs: cpuDelta.user,\r\n cpuSystemUs: cpuDelta.system\r\n };\r\n }\r\n\r\n const payload: TaskRun = {\r\n runId: task.id,\r\n taskName: task.data.taskName,\r\n taskType: task.data.taskType,\r\n triggerTraceId: task.data.triggerTraceId,\r\n queueDelay: task.data.queueDelay,\r\n attempts: task.data.attempts,\r\n isDeadLetter: task.data.isDeadLetter,\r\n metadata: { ...task.data.metadata, ...extraMetadata, droppedSpans: task.state.droppedSpans },\r\n resourceMetrics,\r\n status,\r\n duration: performance.now() - task.startTime,\r\n spans: task.spans,\r\n timestamp: new Date().toISOString()\r\n };\r\n\r\n this.transport.addTask(payload);\r\n }\r\n\r\n public wrapTask<T extends (...args: any[]) => any>(name: string, type: 'cron' | 'queue' | 'pipeline' | 'custom', options: any = {}, fn: T): T {\r\n return (async (...args: any[]) => {\r\n return this.startTask(name, type, options, async () => {\r\n try {\r\n const result = await fn(...args);\r\n this.endTask('success');\r\n return result;\r\n } catch (error) {\r\n this.captureError(error, { taskName: name });\r\n this.endTask('failed');\r\n throw error;\r\n }\r\n });\r\n }) as unknown as T;\r\n }\r\n\r\n public captureError(error: unknown, context: any = {}) {\r\n if (!this.transport) return;\r\n\r\n let parsedError: Error;\r\n if (error instanceof Error) {\r\n parsedError = error;\r\n } else {\r\n parsedError = new Error(String(error));\r\n }\r\n\r\n const currentTrace = Context.current();\r\n\r\n const errPayload = {\r\n errorClass: parsedError.name || 'Error',\r\n message: parsedError.message,\r\n stackTrace: parsedError.stack,\r\n context: sanitizeAttributes(context, this.options || undefined),\r\n timestamp: new Date().toISOString()\r\n };\r\n\r\n if (currentTrace?.contextType === 'task') {\r\n this.transport.addError({ ...errPayload, runId: currentTrace.id }, 'task');\r\n } else {\r\n this.transport.addError({ ...errPayload, traceId: currentTrace?.id }, 'apm');\r\n }\r\n }\r\n\r\n public track(data: any) {\r\n this.transport?.addTrace({ traceId: generateTraceId(), ...data, spans: [], timestamp: new Date().toISOString() });\r\n }\r\n\r\n public startSpan(name: string, type: 'db' | 'http' | 'function' | 'custom' = 'custom') {\r\n const span = startCapturedSpan(name, type, {}, this.options || undefined);\r\n if (!span) return { end: () => { } };\r\n return { end: (meta?: any, status?: number) => span.end(status, meta) };\r\n }\r\n\r\n public async flush() { if (this.transport) await this.transport.flush(); }\r\n}\r\n\r\nexport const client = new SenzorClient();\r\n","const _isNode = typeof process !== 'undefined' &&\n typeof process.versions !== 'undefined' &&\n typeof process.versions.node !== 'undefined';\n\nexport const isNode = (): boolean => _isNode;\n\nexport const isEdgeRuntime = (): boolean =>\n typeof navigator !== 'undefined' &&\n typeof navigator.userAgent === 'string' &&\n navigator.userAgent.includes('Cloudflare');\n\nexport const getEnv = (key: string): string | undefined => {\n if (_isNode) return process.env[key];\n return undefined;\n};\n","{\r\n \"name\": \"@senzops/apm-node\",\r\n \"version\": \"1.3.1\",\r\n \"description\": \"Universal APM SDK for Senzor\",\r\n \"main\": \"dist/index.js\",\r\n \"types\": \"dist/index.d.ts\",\r\n \"exports\": {\r\n \".\": {\r\n \"types\": \"./dist/index.d.ts\",\r\n \"worker\": \"./dist/index.mjs\",\r\n \"require\": \"./dist/index.js\",\r\n \"import\": \"./dist/index.mjs\"\r\n },\r\n \"./register\": {\r\n \"types\": \"./dist/register.d.ts\",\r\n \"require\": \"./dist/register.js\",\r\n \"import\": \"./dist/register.mjs\"\r\n },\r\n \"./lambda-handler\": {\r\n \"types\": \"./dist/lambda-handler.d.ts\",\r\n \"require\": \"./dist/lambda-handler.js\",\r\n \"import\": \"./dist/lambda-handler.mjs\"\r\n }\r\n },\r\n \"scripts\": {\r\n \"build\": \"tsup\",\r\n \"prepublishOnly\": \"npm run build\"\r\n },\r\n \"devDependencies\": {\r\n \"@types/node\": \"^20.19.41\",\r\n \"tsup\": \"^8.0.0\",\r\n \"typescript\": \"^5.0.0\"\r\n },\r\n \"engines\": {\r\n \"node\": \">=18.0.0\",\r\n \"bun\": \">=1.0.0\"\r\n },\r\n \"keywords\": [\r\n \"apm\",\r\n \"monitoring\",\r\n \"senzor\",\r\n \"node\",\r\n \"javascript\",\r\n \"api\",\r\n \"observability\",\r\n \"cloudflare-workers\",\r\n \"edge\",\r\n \"universal\"\r\n ],\r\n \"author\": \"Senzops\",\r\n \"license\": \"MIT\"\r\n}\r\n","import pkg from '../../package.json';\r\n\r\nexport const SDK_META = {\r\n name: pkg.name,\r\n version: pkg.version\r\n};","import { isNode } from '../core/runtime';\n\n// ---------------------------------------------------------------------------\n// Runtime Metrics Collector\n//\n// Collects Node.js runtime health metrics at configurable intervals:\n// - Event loop lag (delay)\n// - Event loop utilization (ELU) — Node.js 14.10+\n// - Garbage collection duration and frequency\n// - Heap memory usage and allocation\n// - Active handles and requests count\n// - CPU usage (user + system)\n//\n// These metrics are sent as a separate payload type to the APM ingest\n// endpoint, enabling runtime health dashboards.\n//\n// Follows OTel Runtime Metrics semantic conventions where applicable.\n// ---------------------------------------------------------------------------\n\nexport interface RuntimeMetricsPayload {\n timestamp: string;\n metrics: RuntimeMetrics;\n}\n\nexport interface RuntimeMetrics {\n // Event Loop\n eventLoop: {\n lagMs: number; // Current event loop lag in milliseconds\n lagP50Ms?: number; // p50 lag (if histogram available)\n lagP99Ms?: number; // p99 lag (if histogram available)\n utilizationPercent?: number; // Event loop utilization 0-100 (Node 14.10+)\n };\n\n // Garbage Collection\n gc: {\n totalDurationMs: number; // Total GC time since last report\n totalCount: number; // Total GC pauses since last report\n majorCount: number; // Major (mark-sweep) GC count\n minorCount: number; // Minor (scavenge) GC count\n incrementalCount: number; // Incremental marking count\n weakCallbackCount: number; // Weak callback processing count\n };\n\n // Memory\n memory: {\n heapUsedBytes: number;\n heapTotalBytes: number;\n externalBytes: number;\n arrayBuffersBytes: number;\n rssBytes: number;\n heapUsedPercent: number; // heapUsed / heapTotal * 100\n };\n\n // Process\n process: {\n activeHandles: number;\n activeRequests: number;\n cpuUserUs: number; // CPU user time delta since last report (microseconds)\n cpuSystemUs: number; // CPU system time delta since last report (microseconds)\n uptimeSeconds: number;\n };\n}\n\n// ---------------------------------------------------------------------------\n// GC Observer (uses perf_hooks PerformanceObserver)\n// ---------------------------------------------------------------------------\n\ninterface GcStats {\n totalDurationMs: number;\n totalCount: number;\n majorCount: number; // kind=2 (MarkSweepCompact)\n minorCount: number; // kind=1 (Scavenge)\n incrementalCount: number; // kind=4 (IncrementalMarking)\n weakCallbackCount: number; // kind=8 (ProcessWeakCallbacks)\n}\n\nconst GC_KINDS: Record<number, keyof Pick<GcStats, 'majorCount' | 'minorCount' | 'incrementalCount' | 'weakCallbackCount'>> = {\n 1: 'minorCount',\n 2: 'majorCount',\n 4: 'incrementalCount',\n 8: 'weakCallbackCount',\n};\n\nclass GcObserver {\n private stats: GcStats = {\n totalDurationMs: 0,\n totalCount: 0,\n majorCount: 0,\n minorCount: 0,\n incrementalCount: 0,\n weakCallbackCount: 0,\n };\n private observer: any = null;\n\n start() {\n try {\n const { PerformanceObserver } = require('perf_hooks');\n\n this.observer = new PerformanceObserver((list: any) => {\n for (const entry of list.getEntries()) {\n this.stats.totalDurationMs += entry.duration;\n this.stats.totalCount++;\n\n const kindKey = GC_KINDS[entry.detail?.kind ?? entry.kind];\n if (kindKey) {\n this.stats[kindKey]++;\n }\n }\n });\n\n this.observer.observe({ type: 'gc', buffered: true });\n } catch {\n // perf_hooks or gc observation not available\n }\n }\n\n /** Take and reset collected GC stats since last call. */\n take(): GcStats {\n const snapshot = { ...this.stats };\n this.stats = {\n totalDurationMs: 0,\n totalCount: 0,\n majorCount: 0,\n minorCount: 0,\n incrementalCount: 0,\n weakCallbackCount: 0,\n };\n return snapshot;\n }\n\n stop() {\n try {\n this.observer?.disconnect();\n } catch { }\n this.observer = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Event Loop Lag Measurement\n// ---------------------------------------------------------------------------\n\nclass EventLoopLagMeter {\n private lastCheck = 0;\n private lagMs = 0;\n private timer: any = null;\n private monitoringHistogram: any = null;\n\n start() {\n // High-resolution lag sampling via setImmediate\n this.lastCheck = performance.now();\n this.scheduleSample();\n\n // Try to use monitorEventLoopDelay for histogram (Node 12+)\n try {\n const { monitorEventLoopDelay } = require('perf_hooks');\n this.monitoringHistogram = monitorEventLoopDelay({ resolution: 20 });\n this.monitoringHistogram.enable();\n } catch { }\n }\n\n private scheduleSample() {\n this.timer = setTimeout(() => {\n const now = performance.now();\n // Timer was scheduled for ~100ms; anything above that is lag\n const elapsed = now - this.lastCheck;\n this.lagMs = Math.max(0, elapsed - 100);\n this.lastCheck = now;\n this.scheduleSample();\n }, 100);\n\n if (this.timer && typeof this.timer.unref === 'function') {\n this.timer.unref();\n }\n }\n\n take(): { lagMs: number; lagP50Ms?: number; lagP99Ms?: number } {\n const result: any = { lagMs: Math.round(this.lagMs * 100) / 100 };\n\n if (this.monitoringHistogram) {\n try {\n // percentile() returns nanoseconds\n result.lagP50Ms = Math.round(this.monitoringHistogram.percentile(50) / 1e6 * 100) / 100;\n result.lagP99Ms = Math.round(this.monitoringHistogram.percentile(99) / 1e6 * 100) / 100;\n this.monitoringHistogram.reset();\n } catch { }\n }\n\n return result;\n }\n\n stop() {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n try {\n this.monitoringHistogram?.disable();\n } catch { }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Event Loop Utilization (Node 14.10+)\n// ---------------------------------------------------------------------------\n\nclass EventLoopUtilization {\n private elu1: any = null;\n private getELU: (() => any) | null = null;\n\n start() {\n try {\n const { performance: perfHooks } = require('perf_hooks');\n if (typeof perfHooks.eventLoopUtilization === 'function') {\n this.getELU = () => perfHooks.eventLoopUtilization();\n this.elu1 = this.getELU();\n }\n } catch { }\n }\n\n take(): number | undefined {\n if (!this.getELU || !this.elu1) return undefined;\n try {\n const elu2 = this.getELU();\n const { performance: perfHooks } = require('perf_hooks');\n const util = perfHooks.eventLoopUtilization(this.elu1, elu2);\n this.elu1 = elu2;\n return Math.round(util.utilization * 10000) / 100; // 0-100 with 2 decimal\n } catch {\n return undefined;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime Metrics Collector\n// ---------------------------------------------------------------------------\n\nexport interface RuntimeMetricsOptions {\n /** Collection interval in milliseconds. Default: 15000 (15s). */\n interval?: number;\n /** Callback invoked with each metrics snapshot. */\n onMetrics: (payload: RuntimeMetricsPayload) => void;\n}\n\nexport class RuntimeMetricsCollector {\n private gcObserver = new GcObserver();\n private lagMeter = new EventLoopLagMeter();\n private eluMeter = new EventLoopUtilization();\n private lastCpu: NodeJS.CpuUsage | undefined;\n private timer: any = null;\n private interval: number;\n private onMetrics: (payload: RuntimeMetricsPayload) => void;\n private started = false;\n\n constructor(options: RuntimeMetricsOptions) {\n this.interval = options.interval || 15000;\n this.onMetrics = options.onMetrics;\n }\n\n start() {\n if (!isNode() || this.started) return;\n this.started = true;\n\n this.gcObserver.start();\n this.lagMeter.start();\n this.eluMeter.start();\n\n try {\n this.lastCpu = process.cpuUsage();\n } catch { }\n\n this.timer = setInterval(() => {\n try {\n this.collect();\n } catch { }\n }, this.interval);\n\n if (this.timer && typeof this.timer.unref === 'function') {\n this.timer.unref();\n }\n }\n\n private collect() {\n const mem = process.memoryUsage();\n const gc = this.gcObserver.take();\n const lagInfo = this.lagMeter.take();\n const eluPercent = this.eluMeter.take();\n\n // CPU delta\n let cpuUserUs = 0;\n let cpuSystemUs = 0;\n try {\n if (this.lastCpu) {\n const delta = process.cpuUsage(this.lastCpu);\n cpuUserUs = delta.user;\n cpuSystemUs = delta.system;\n }\n this.lastCpu = process.cpuUsage();\n } catch { }\n\n // Active handles/requests\n let activeHandles = 0;\n let activeRequests = 0;\n try {\n activeHandles = (process as any)._getActiveHandles?.()?.length ?? 0;\n activeRequests = (process as any)._getActiveRequests?.()?.length ?? 0;\n } catch { }\n\n const metrics: RuntimeMetrics = {\n eventLoop: {\n lagMs: lagInfo.lagMs,\n lagP50Ms: lagInfo.lagP50Ms,\n lagP99Ms: lagInfo.lagP99Ms,\n utilizationPercent: eluPercent,\n },\n gc,\n memory: {\n heapUsedBytes: mem.heapUsed,\n heapTotalBytes: mem.heapTotal,\n externalBytes: mem.external,\n arrayBuffersBytes: mem.arrayBuffers || 0,\n rssBytes: mem.rss,\n heapUsedPercent: mem.heapTotal > 0\n ? Math.round((mem.heapUsed / mem.heapTotal) * 10000) / 100\n : 0,\n },\n process: {\n activeHandles,\n activeRequests,\n cpuUserUs,\n cpuSystemUs,\n uptimeSeconds: Math.floor(process.uptime()),\n },\n };\n\n this.onMetrics({\n timestamp: new Date().toISOString(),\n metrics,\n });\n }\n\n stop() {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n this.gcObserver.stop();\n this.lagMeter.stop();\n this.started = false;\n }\n}\n","import { client } from '../core/client';\nimport { normalizePath } from '../core/normalizer';\nimport { getClientIp } from '../utils/getClientIp';\nimport { generateTraceId } from '../utils/ids';\n\n// ---------------------------------------------------------------------------\n// AWS Lambda Handler Wrapper\n//\n// Provides automatic APM instrumentation for AWS Lambda functions.\n//\n// Features:\n// 1. Cold start detection — tags first invocation per container\n// 2. Lambda context extraction — faas.*, cloud.*, aws.* attributes\n// 3. Trigger-type detection — API Gateway v1/v2, ALB, SQS, SNS,\n// DynamoDB Streams, EventBridge, S3, Scheduled, generic\n// 4. Forced flush before response — ensures telemetry delivery\n// since Lambda freezes the process between invocations\n// 5. Lambda Extensions API registration — registers as internal\n// extension for SHUTDOWN lifecycle event as a safety-net flush\n//\n// Usage:\n// import Senzor from '@anthropic/senzor-node';\n// export const handler = Senzor.wrapLambda(async (event, context) => {\n// return { statusCode: 200, body: 'OK' };\n// });\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Cold start detection\n// ---------------------------------------------------------------------------\n\n/** Module-level flag — true only for the very first invocation in this container. */\nlet isColdStart = true;\n\n// ---------------------------------------------------------------------------\n// Trigger type detection\n// ---------------------------------------------------------------------------\n\ntype LambdaTrigger =\n | 'api-gateway-v1'\n | 'api-gateway-v2'\n | 'alb'\n | 'sqs'\n | 'sns'\n | 'dynamodb-streams'\n | 'eventbridge'\n | 's3'\n | 'scheduled'\n | 'generic';\n\nconst detectTrigger = (event: any): LambdaTrigger => {\n if (!event || typeof event !== 'object') return 'generic';\n\n // API Gateway v2 (HTTP API)\n if (event.requestContext?.http?.method) return 'api-gateway-v2';\n\n // API Gateway v1 (REST API)\n if (event.requestContext?.httpMethod || event.httpMethod) return 'api-gateway-v1';\n\n // ALB (Application Load Balancer)\n if (event.requestContext?.elb) return 'alb';\n\n // SQS\n if (Array.isArray(event.Records) && event.Records[0]?.eventSource === 'aws:sqs') return 'sqs';\n\n // SNS\n if (Array.isArray(event.Records) && event.Records[0]?.EventSource === 'aws:sns') return 'sns';\n\n // DynamoDB Streams\n if (Array.isArray(event.Records) && event.Records[0]?.eventSource === 'aws:dynamodb') return 'dynamodb-streams';\n\n // S3\n if (Array.isArray(event.Records) && event.Records[0]?.eventSource === 'aws:s3') return 's3';\n\n // EventBridge / CloudWatch Events\n if (event.source && event['detail-type'] && event.detail) return 'eventbridge';\n\n // CloudWatch Scheduled Event\n if (event.source === 'aws.events' || event['detail-type'] === 'Scheduled Event') return 'scheduled';\n\n return 'generic';\n};\n\n// ---------------------------------------------------------------------------\n// HTTP event extraction (API Gateway v1/v2, ALB)\n// ---------------------------------------------------------------------------\n\ninterface HttpEventInfo {\n method: string;\n path: string;\n headers: Record<string, string>;\n statusCode?: number;\n}\n\nconst extractHttpEvent = (event: any, trigger: LambdaTrigger): HttpEventInfo | null => {\n if (trigger === 'api-gateway-v2') {\n const http = event.requestContext?.http;\n return {\n method: http?.method || 'GET',\n path: event.rawPath || event.requestContext?.http?.path || '/',\n headers: normalizeHeaders(event.headers),\n };\n }\n\n if (trigger === 'api-gateway-v1') {\n return {\n method: event.httpMethod || event.requestContext?.httpMethod || 'GET',\n path: event.path || event.resource || '/',\n headers: normalizeHeaders(event.headers),\n };\n }\n\n if (trigger === 'alb') {\n return {\n method: event.httpMethod || 'GET',\n path: event.path || '/',\n headers: normalizeHeaders(event.headers),\n };\n }\n\n return null;\n};\n\nconst normalizeHeaders = (headers: any): Record<string, string> => {\n if (!headers || typeof headers !== 'object') return {};\n const normalized: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n normalized[key.toLowerCase()] = String(value);\n }\n return normalized;\n};\n\n// ---------------------------------------------------------------------------\n// Lambda context attribute extraction\n// ---------------------------------------------------------------------------\n\nconst extractLambdaAttributes = (\n event: any,\n context: any,\n trigger: LambdaTrigger,\n coldStart: boolean\n): Record<string, any> => {\n const attrs: Record<string, any> = {\n 'faas.trigger': mapTriggerToFaasTrigger(trigger),\n 'faas.coldstart': coldStart,\n 'cloud.provider': 'aws',\n 'cloud.platform': 'aws_lambda',\n 'firebase.service': undefined, // clear any inherited\n library: 'aws-lambda',\n };\n\n // Lambda context fields\n if (context) {\n if (context.functionName) attrs['faas.name'] = context.functionName;\n if (context.functionVersion) attrs['faas.version'] = context.functionVersion;\n if (context.awsRequestId) attrs['faas.execution'] = context.awsRequestId;\n if (context.invokedFunctionArn) attrs['cloud.resource_id'] = context.invokedFunctionArn;\n if (context.memoryLimitInMB) attrs['faas.max_memory'] = Number(context.memoryLimitInMB);\n if (context.logGroupName) attrs['aws.log.group.names'] = context.logGroupName;\n if (context.logStreamName) attrs['aws.log.stream.names'] = context.logStreamName;\n }\n\n // Region from environment\n const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION;\n if (region) attrs['cloud.region'] = region;\n\n // Account ID from ARN\n if (context?.invokedFunctionArn) {\n const arnParts = context.invokedFunctionArn.split(':');\n if (arnParts.length >= 5) {\n attrs['cloud.account.id'] = arnParts[4];\n }\n }\n\n // Trigger-specific attributes\n switch (trigger) {\n case 'sqs':\n if (Array.isArray(event.Records)) {\n attrs['messaging.system'] = 'aws_sqs';\n attrs['messaging.batch.message_count'] = event.Records.length;\n const arnSrc = event.Records[0]?.eventSourceARN;\n if (arnSrc) attrs['messaging.source.name'] = arnSrc.split(':').pop();\n }\n break;\n\n case 'sns':\n if (Array.isArray(event.Records)) {\n attrs['messaging.system'] = 'aws_sns';\n const topicArn = event.Records[0]?.Sns?.TopicArn;\n if (topicArn) attrs['messaging.source.name'] = topicArn.split(':').pop();\n }\n break;\n\n case 'dynamodb-streams':\n if (Array.isArray(event.Records)) {\n attrs['aws.dynamodb.table_names'] = [\n ...new Set(\n event.Records\n .map((r: any) => r.eventSourceARN?.split('/')[1])\n .filter(Boolean)\n ),\n ];\n attrs['messaging.batch.message_count'] = event.Records.length;\n }\n break;\n\n case 's3':\n if (Array.isArray(event.Records) && event.Records[0]?.s3) {\n attrs['aws.s3.bucket'] = event.Records[0].s3.bucket?.name;\n attrs['aws.s3.key'] = event.Records[0].s3.object?.key;\n }\n break;\n\n case 'eventbridge':\n if (event.source) attrs['aws.eventbridge.source'] = event.source;\n if (event['detail-type']) attrs['aws.eventbridge.detail_type'] = event['detail-type'];\n break;\n }\n\n return attrs;\n};\n\nconst mapTriggerToFaasTrigger = (trigger: LambdaTrigger): string => {\n switch (trigger) {\n case 'api-gateway-v1':\n case 'api-gateway-v2':\n case 'alb':\n return 'http';\n case 'sqs':\n case 'sns':\n return 'pubsub';\n case 'dynamodb-streams':\n return 'datasource';\n case 's3':\n return 'datasource';\n case 'eventbridge':\n case 'scheduled':\n return 'timer';\n default:\n return 'other';\n }\n};\n\n// ---------------------------------------------------------------------------\n// Response status extraction\n// ---------------------------------------------------------------------------\n\nconst extractStatusFromResponse = (result: any, trigger: LambdaTrigger): number => {\n // HTTP triggers: response has statusCode\n if (\n (trigger === 'api-gateway-v1' || trigger === 'api-gateway-v2' || trigger === 'alb') &&\n result &&\n typeof result === 'object'\n ) {\n return typeof result.statusCode === 'number' ? result.statusCode : 200;\n }\n\n // Non-HTTP: success = 200\n return 200;\n};\n\n// ---------------------------------------------------------------------------\n// Lambda Extensions API — internal extension registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register as a Lambda internal extension to receive SHUTDOWN events.\n * This is a safety-net: if the process is about to be terminated,\n * we get a last chance to flush telemetry.\n *\n * Only runs when the Lambda Extensions API is available (runtime >= 2020-01-01).\n * Failures are silently ignored — the wrapper's own forced flush is the primary mechanism.\n */\nconst registerExtension = (() => {\n let registered = false;\n\n return (onShutdown: () => Promise<void>) => {\n if (registered) return;\n registered = true;\n\n const runtimeApi = process.env.AWS_LAMBDA_RUNTIME_API;\n if (!runtimeApi) return;\n\n const extensionName = 'senzor-apm';\n const registerUrl = `http://${runtimeApi}/2020-01-01/extension/register`;\n\n // Fire-and-forget registration\n (async () => {\n try {\n const registerResponse = await fetch(registerUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Lambda-Extension-Name': extensionName,\n },\n body: JSON.stringify({ events: ['SHUTDOWN'] }),\n });\n\n if (!registerResponse.ok) return;\n\n const extensionId = registerResponse.headers.get('Lambda-Extension-Identifier');\n if (!extensionId) return;\n\n // Event loop: wait for SHUTDOWN\n const nextUrl = `http://${runtimeApi}/2020-01-01/extension/event/next`;\n\n // This blocks until Lambda sends SHUTDOWN — runs on a background \"thread\"\n // via the microtask queue; does not block the handler.\n const waitForShutdown = async () => {\n try {\n const eventResponse = await fetch(nextUrl, {\n method: 'GET',\n headers: { 'Lambda-Extension-Identifier': extensionId },\n });\n\n if (eventResponse.ok) {\n const event = await eventResponse.json() as any;\n if (event.eventType === 'SHUTDOWN') {\n await onShutdown();\n }\n }\n } catch {\n // Extension event loop failure — primary flush in handler covers this\n }\n };\n\n // Start the event loop (non-blocking)\n waitForShutdown();\n } catch {\n // Registration failure is expected outside Lambda or in older runtimes\n }\n })();\n };\n})();\n\n// ---------------------------------------------------------------------------\n// Public API: wrapLambda\n// ---------------------------------------------------------------------------\n\ntype LambdaHandler<TEvent = any, TResult = any> = (\n event: TEvent,\n context: any,\n) => Promise<TResult>;\n\n/**\n * Wraps an AWS Lambda handler function with Senzor APM instrumentation.\n *\n * @example\n * ```typescript\n * import Senzor from '@senzor/apm-node';\n *\n * Senzor.init({ apiKey: process.env.SENZOR_API_KEY });\n *\n * export const handler = Senzor.wrapLambda(async (event, context) => {\n * // Your Lambda logic here\n * return { statusCode: 200, body: JSON.stringify({ ok: true }) };\n * });\n * ```\n */\nexport const wrapLambda = <TEvent = any, TResult = any>(\n handler: LambdaHandler<TEvent, TResult>,\n): LambdaHandler<TEvent, TResult> => {\n // Register extension on first wrap (idempotent)\n registerExtension(() => client.flush());\n\n return async (event: TEvent, context: any): Promise<TResult> => {\n const coldStart = isColdStart;\n if (isColdStart) isColdStart = false;\n\n const trigger = detectTrigger(event);\n const lambdaAttrs = extractLambdaAttributes(event, context, trigger, coldStart);\n const httpInfo = extractHttpEvent(event, trigger);\n\n // For HTTP triggers, use proper HTTP trace semantics\n const method = httpInfo?.method || trigger.toUpperCase();\n const path = httpInfo?.path || `/${context?.functionName || 'lambda'}`;\n const route = httpInfo ? normalizePath(httpInfo.path) : context?.functionName || 'lambda';\n const headers = httpInfo?.headers || {};\n\n return client.startTrace(\n {\n method,\n path,\n route,\n ip: httpInfo ? getClientIp({ headers }) : undefined,\n userAgent: headers['user-agent'],\n headers,\n ...lambdaAttrs,\n },\n async () => {\n let status = 500;\n try {\n const result = await handler(event, context);\n status = extractStatusFromResponse(result, trigger);\n return result;\n } catch (err: any) {\n client.captureError(err, {\n 'faas.name': context?.functionName,\n 'faas.execution': context?.awsRequestId,\n trigger,\n });\n throw err;\n } finally {\n client.endTrace(status, {\n route,\n ...lambdaAttrs,\n });\n\n // Force flush before Lambda freezes the execution environment.\n // This is critical: Lambda may freeze or terminate the process\n // immediately after the handler returns.\n await client.flush();\n }\n },\n );\n };\n};\n"],"mappings":"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","names":["SENZOR_INTERNAL_HEADER","init_internal","__esmMin","NaiveStorage","tryResolveALS","LazyStorage","storage","Context","init_context","__esmMin","store","callback","args","prev","result","err","val","mod","als","trace","fn","spanId","span","maxSpans","TRACEPARENT_REGEX","parseTraceparent","generateTraceparent","init_traceContext","__esmMin","header","traceparent","match","traceId","parentSpanId","flags","sampled","spanId","getRandomUUID","generateTraceId","generateSpanId","init_ids","__esmMin","randomUUID","c","r","DEFAULT_MAX_ATTRIBUTES","DEFAULT_MAX_ATTRIBUTE_LENGTH","MAX_DEPTH","MAX_ARRAY_ITEMS","SENSITIVE_KEY_PATTERN","getLimits","truncate","isSensitiveKey","sanitizePrimitive","sanitizeValue","sanitizeAttributes","sanitizeHeaders","normalizeSql","getSqlOperation","init_sanitizer","__esmMin","options","value","maxLength","key","depth","primitive","item","output","count","childKey","childValue","attributes","limits","normalizedOptions","headers","plainHeaders","sql","collapsed","withoutLiterals","startCapturedSpan","runWithCapturedSpan","init_span","__esmMin","init_context","init_sanitizer","init_ids","name","type","meta","options","trace","Context","spanId","generateSpanId","parentSpanId","startTime","startedAt","ended","status","extraMeta","mergedMeta","sanitizeAttributes","span","fn","normalizePath","getRoute","init_normalizer","__esmMin","path","req","fallbackPath","IPV4_PATTERN","IPV6_PATTERN","isIP","stripIPv6Mapped","stripIPv4Port","stripIPv6Brackets","normaliseIP","isPrivateOrLoopback","parseForwardedHeader","parseXForwardedFor","getClientIp","init_getClientIp","__esmMin","ip","lastColon","maybeIP","match","raw","header","parts","part","forMatch","ips","s","req","h","fwd","xff","PATCHES","ORIGINAL","patchMethod","init_patch","__esmMin","target","methodName","patchKey","wrapper","current","existingPatches","original","wrapped","patches","http_exports","__export","instrumentFetch","instrumentHttp","getDebug","isPlainObject","headerValue","hasInternalHeader","shouldIgnoreUrl","cloneHeaders","setHeader","prepareRequestArgs","resolveIncomingRoute","patchIncomingServer","patchOutgoing","init_http","__esmMin","init_context","init_normalizer","init_sanitizer","init_getClientIp","init_internal","init_traceContext","init_patch","init_span","options","value","headers","key","name","normalizedKey","SENZOR_INTERNAL_HEADER","urlString","ingestUrl","url","ingest","cloned","acc","existingKey","header","args","defaultProtocol","nextArgs","optionsIndex","urlFromArg","protocol","hostname","path","method","req","res","getRoute","normalizePath","proto","client","patchMethod","original","event","Context","rawPath","getClientIp","sanitizeHeaders","trace","finalized","finalize","reason","error","moduleRef","patchKeyPrefix","requestWrapper","prepared","span","startCapturedSpan","generateTraceparent","invoke","completed","endSpan","status","extraMeta","statusCode","finish","runWithCapturedSpan","input","init","originalHeaders","nextInit","response","httpMod","httpsMod","getHookRegistry","mod","Module","SENZOR_HOOKS","runHooks","moduleName","exports","registry","hooks","currentExports","hook","nextExports","err","patchLoaderOnce","SENZOR_PATCHED","previousLoad","request","parent","isMain","patchCached","resolved","safeRequire","cached","replacement","tryRequire","retryPatch","attempts","max","timer","hookRequire","init_hook","__esmMin","onRequire","ignoredNextValues","shouldCaptureFrameworkSpan","statusFrom","isPromiseLike","runWithParentOf","copyFunctionProperties","invokeWithFrameworkSpan","wrapFrameworkHandlerWithArity","init_framework","__esmMin","init_context","init_span","type","options","info","fallback","res","value","span","fn","Context","source","target","key","handler","thisArg","args","invokeOptions","startCapturedSpan","ended","cleanup","endSpan","status","meta","clean","onFinish","onClose","callbackIndex","arg","originalCallback","callbackArgs","maybeError","hasError","runWithCapturedSpan","result","error","getInfo","invoke","wrapped","b","c","d","express_exports","__export","instrumentExpress","LAYER_PATCHED","routeMethods","stringifyPath","getLayerPath","getRequestRoute","getLayerType","getRouteMethod","copyEnumerableProperties","patchLayer","patchRouteMethodHandlers","getSafeRouter","patchExpress","init_express","__esmMin","init_normalizer","init_hook","init_patch","init_framework","value","args","arg","path","req","layer","layerPath","routePath","baseUrl","normalizePath","original","forcedType","method","candidate","source","target","key","options","patchMethod","layerType","handlerName","wrapped","err","res","next","route","invokeWithFrameworkSpan","displayRoute","name","result","stack","app","r","expressModule","routerProto","prevStackLength","i","hookRequire","exports","fastify_exports","__export","instrumentFastify","instrumentFastifyInstance","FACTORY_PATCHED","INSTANCE_PATCHED","lifecycleHookNames","routeLifecycleKeys","getRoute","wrapHook","wrapRouteHandler","wrapMaybeArray","patchFastifyInstance","copyFactoryProperties","wrapFastifyFactory","init_fastify","__esmMin","init_hook","init_patch","init_framework","request","fallback","hookName","handler","options","route","wrapFrameworkHandlerWithArity","_thisArg","args","reply","currentRoute","value","wrap","instance","patchMethod","original","routeOptions","nextRouteOptions","key","source","target","factory","wrapped","mutableWrapped","hookRequire","exports","koa_exports","__export","instrumentKoa","routerMethods","stringifyPath","getPathFromArgs","wrapKoaMiddleware","patchKoaApplication","patchKoaRouter","init_koa","__esmMin","init_normalizer","init_hook","init_patch","init_framework","value","args","arg","path","middleware","options","layerPath","layerType","method","wrapFrameworkHandlerWithArity","_thisArg","ctx","route","normalizePath","actualMethod","handlerName","koa","proto","patchMethod","original","routerModule","nextArgs","hookRequire","exports","undici_exports","__export","instrumentUndici","hasInternalHeader","setHeader","getUrlDetails","patchRequestLike","patchUndici","init_undici","__esmMin","init_normalizer","init_internal","init_traceContext","init_hook","init_patch","init_span","headers","key","value","SENZOR_INTERNAL_HEADER","nextHeaders","existingKey","header","input","url","target","methodName","patchKey","options","patchMethod","original","opts","cb","details","method","span","startCapturedSpan","normalizePath","nextOptions","generateTraceparent","wrappedCallback","err","data","runWithCapturedSpan","result","error","undici","proto","index","hookRequire","exports","mongo_exports","__export","instrumentMongo","collectionName","databaseName","cursorCollectionName","patchCollectionMethod","patchCursorMethod","patchMongo","init_mongo","__esmMin","init_hook","init_patch","init_span","collection","cursor","proto","method","options","patchMethod","original","args","span","startCapturedSpan","runWithCapturedSpan","result","value","error","operation","mongodb","collectionProto","FindCursor","AggregationCursor","hookRequire","exports","mongoose_exports","__export","instrumentMongoose","modelName","collectionName","patchExec","patchSave","patchMongoose","init_mongoose","__esmMin","init_hook","init_patch","init_span","target","proto","label","options","patchMethod","original","args","operation","collection","span","startCapturedSpan","runWithCapturedSpan","result","value","error","modelProto","mongoose","hookRequire","exports","pg_exports","__export","instrumentPg","extractSql","wrapQueryMethod","patchPg","init_pg","__esmMin","init_sanitizer","init_hook","init_patch","init_span","args","first","proto","label","options","patchMethod","original","sql","operation","getSqlOperation","span","startCapturedSpan","normalizeSql","callbackIndex","arg","originalCallback","err","result","runWithCapturedSpan","value","error","pg","hookRequire","exports","mysql_exports","__export","instrumentMysql","extractSql","patchSqlMethod","patchKnownPrototypes","patchFactories","patchMysql","init_mysql","__esmMin","init_sanitizer","init_hook","init_patch","init_span","args","first","proto","method","library","options","patchMethod","original","sql","operation","getSqlOperation","span","startCapturedSpan","normalizeSql","callbackIndex","arg","originalCallback","err","rows","runWithCapturedSpan","result","value","error","mysql","factory","client","hookRequire","exports","redis_exports","__export","instrumentRedis","getCommandName","patchSendCommand","patchCreatedClient","patchRedisPackage","patchIORedisPackage","init_redis","__esmMin","init_hook","init_patch","init_span","command","target","label","options","patchMethod","original","args","commandName","span","startCapturedSpan","runWithCapturedSpan","result","value","error","client","redis","factory","ioredis","hookRequire","exports","bullmq_exports","__export","instrumentBullMQ","patchWorker","target","client","debug","proto","original","PATCHED","job","queueDelay","currentAttempt","maxAttempts","isFinal","taskName","result","error","ctx","Context","init_bullmq","__esmMin","init_hook","init_context","hookRequire","exports","cron_exports","__export","instrumentNodeCron","normalizeOptions","options","patchTarget","target","client","debug","schedule","PATCHED","original","wrapped","expression","handler","opts","taskName","wrappedHandler","err","init_cron","__esmMin","init_hook","hookRequire","exports","grpc_exports","__export","instrumentGrpc","GRPC_STATUS_NAMES","grpcStatusToHttp","parseGrpcMethod","TRACEPARENT_KEY","SENZOR_TRACE_KEY","SENZOR_SPAN_KEY","injectMetadata","extractFromMetadata","patchClientMethods","patchServerRegister","init_grpc","__esmMin","init_context","init_hook","init_patch","init_span","init_traceContext","code","fullPath","parts","metadata","traceId","spanId","generateTraceparent","traceparent","tp","parsed","parseTraceparent","parentSpanId","grpc","options","clientProto","patchMethod","original","method","args","trace","Context","service","rpcMethod","span","startCapturedSpan","metadataIdx","callbackIdx","i","originalCallback","err","response","grpcCode","runWithCapturedSpan","call","ended","status","error","client","serverProto","name","handler","serialize","deserialize","type","wrappedHandler","callback","parentCtx","wrappedCallback","trailer","flags","result","endOnce","meta","hookRequire","exports","graphql_exports","__export","instrumentGraphQL","MAX_DOCUMENT_LENGTH","truncateDocument","extractOperationInfo","getSourceText","hasErrors","extractErrorSummary","patchGraphQL","init_graphql","__esmMin","init_hook","init_patch","init_span","source","document","operationName","defaultResult","operationDefs","def","target","named","result","errors","messages","e","graphql","options","patchMethod","original","args","span","startCapturedSpan","runWithCapturedSpan","res","error","opInfo","sourceText","schema","documentAST","hookRequire","exports","dns_exports","__export","instrumentDns","patchDnsMethod","patchDnsPromisesMethod","init_dns","__esmMin","init_patch","init_span","dnsModule","methodName","options","patchMethod","original","args","hostname","span","startCapturedSpan","callbackIdx","arg","idx","originalCallback","err","results","meta","runWithCapturedSpan","error","promises","result","dns","callbackMethods","method","promiseMethods","net_exports","__export","instrumentNet","normalizeConnectArgs","patchSocketConnect","patchNetFactories","init_net","__esmMin","init_patch","init_span","args","first","port","netModule","options","socketProto","patchMethod","original","host","isIPC","spanName","span","startCapturedSpan","runWithCapturedSpan","socket","ended","endOnce","status","meta","err","hadError","net","kafka_exports","__export","instrumentKafka","TRACEPARENT_KEY","SENZOR_TRACE_KEY","SENZOR_SPAN_KEY","injectHeaders","extractHeaders","patchProducer","patchConsumer","patchKafkaClass","init_kafka","__esmMin","init_context","init_hook","init_patch","init_span","init_traceContext","headers","traceId","spanId","h","generateTraceparent","tp","tpStr","parsed","parseTraceparent","producer","options","patchMethod","original","payload","trace","Context","topic","messageCount","span","startCapturedSpan","msg","runWithCapturedSpan","result","res","r","error","topicMessages","topics","tm","totalMessages","sum","consumer","config","wrappedConfig","originalHandler","partition","message","parentCtx","originalBatchHandler","batch","kafkaModule","KafkaClass","args","hookRequire","exports","amqplib_exports","__export","instrumentAmqplib","TRACEPARENT_KEY","SENZOR_TRACE_KEY","SENZOR_SPAN_KEY","injectHeaders","extractHeaders","patchChannel","patchFromInternals","patchConnectionFactory","init_amqplib","__esmMin","init_context","init_hook","init_patch","init_span","init_traceContext","options","traceId","spanId","opts","headers","generateTraceparent","msg","tp","tpStr","parsed","parseTraceparent","channelProto","patchMethod","original","exchange","routingKey","content","publishOptions","trace","Context","destination","span","startCapturedSpan","enrichedOptions","runWithCapturedSpan","result","error","queue","sendOptions","callback","consumeOptions","wrappedCallback","parentCtx","val","amqplib","channelModel","args","connection","origCreate","createArgs","chResult","channel","hookRequire","exports","socketio_exports","__export","instrumentSocketIO","IGNORED_EVENTS","shouldInstrument","patchEmit","patchOn","patchServerSocket","patchClientSocket","init_socketio","__esmMin","init_context","init_hook","init_patch","init_span","event","proto","patchKey","side","options","patchMethod","original","args","Context","namespace","span","startCapturedSpan","lastArg","hasAck","originalAck","ackArgs","runWithCapturedSpan","result","error","listener","wrappedListener","val","socketio","SocketClass","NamespaceClass","clientModule","hookRequire","exports","socketModule","nsModule","nestjs_exports","__export","instrumentNestJS","getControllerName","patchRouterExecutionContext","patchRouterExplorer","init_nestjs","__esmMin","init_hook","init_patch","init_span","instance","nestCore","options","RouterExecutionContext","patchMethod","original","callback","methodName","moduleKey","requestMethod","rest","handler","controllerName","req","res","next","route","span","startCapturedSpan","runWithCapturedSpan","result","val","error","RouterExplorer","router","routeDefinition","instanceWrapper","path","hookRequire","exports","err","hapi_exports","__export","instrumentHapi","METHOD_MAP","normalizeMethod","wrapHandler","processRouteConfig","patchServerRoute","patchServerExt","init_hapi","__esmMin","init_hook","init_patch","init_span","method","handler","routePath","routeMethod","options","request","h","path","span","startCapturedSpan","runWithCapturedSpan","result","val","statusCode","error","config","wrapped","serverProto","patchMethod","original","routeConfig","wrappedConfigs","wrappedConfig","event","extOptions","eventName","originalMethod","wrappedMethod","err","hookRequire","exports","Server","pino_exports","__export","instrumentPino","getTraceFields","patchPinoFactory","init_pino","__esmMin","init_context","init_hook","init_patch","trace","Context","fields","pinoModule","_options","originalPino","tempLogger","proto","writeSymbol","sym","originalWrite","obj","msg","num","traceFields","levels","level","patchMethod","original","args","err","bindings","hookRequire","exports","winston_exports","__export","instrumentWinston","getTraceFields","patchWinstonLogger","patchCreateLogger","init_winston","__esmMin","init_context","init_hook","init_patch","trace","Context","fields","winston","_options","LoggerClass","loggerModule","patchMethod","original","info","traceFields","args","opts","logger","proto","options","hookRequire","exports","bunyan_exports","__export","instrumentBunyan","getTraceFields","patchBunyanLogger","init_bunyan","__esmMin","init_context","init_hook","init_patch","trace","Context","fields","bunyan","_options","LoggerProto","patchMethod","original","rec","noemit","traceFields","options","hookRequire","exports","aws_sdk_exports","__export","instrumentAwsSdk","SERVICE_NAME_MAP","BEDROCK_SYSTEM_MAP","getBedrockSystem","extractBedrockAttributes","isBedrockInvocation","extractBedrockConverseAttributes","getServiceName","getOperationName","getRegion","patchClientSend","AWS_SERVICE_PACKAGES","init_aws_sdk","__esmMin","init_hook","init_patch","init_span","modelId","provider","command","response","meta","input","bodyStr","parsed","operationName","client","ctorName","id","name","region","clientProto","options","patchMethod","original","args","serviceName","spanName","span","startCapturedSpan","runWithCapturedSpan","result","statusCode","endMeta","op","bedrockMeta","error","requestId","hookRequire","exports","Client","pkg","key","knex_exports","__export","instrumentKnex","DIALECT_MAP","getDbSystem","extractTableName","patchKnexClient","patchKnexFactory","init_knex","__esmMin","init_sanitizer","init_hook","init_patch","init_span","client","dialect","normalized","sql","knexModule","options","ClientClass","patchMethod","original","connection","queryObj","method","operation","getSqlOperation","dbSystem","tableName","span","startCapturedSpan","normalizeSql","runWithCapturedSpan","result","value","rowCount","error","stream","streamOptions","hookRequire","exports","tedious_exports","__export","instrumentTedious","getConnectionMeta","patchTediousConnection","wrapTediousRequest","patchMssql","init_tedious","__esmMin","init_sanitizer","init_hook","init_patch","init_span","connection","config","meta","tedious","options","Connection","proto","patchMethod","original","request","sql","operation","getSqlOperation","connMeta","span","startCapturedSpan","normalizeSql","runWithCapturedSpan","procName","bulkLoad","args","tableName","originalCallback","err","rowCount","lastIdx","cb","parameters","rows","ended","mssql","RequestClass","result","value","error","procedure","hookRequire","exports","cassandra_exports","__export","instrumentCassandra","CONSISTENCY_NAMES","getConsistencyName","getClientMeta","extractCqlTable","patchCassandraClient","init_cassandra","__esmMin","init_sanitizer","init_hook","init_patch","init_span","level","client","meta","options","cql","cassandra","Client","proto","patchMethod","original","query","args","operation","getSqlOperation","clientMeta","tableName","queryOptions","a","consistency","pageSize","span","startCapturedSpan","normalizeSql","lastIdx","cb","err","result","runWithCapturedSpan","value","error","queries","batchSize","rowCount","i","finalCb","j","rowCb","n","row","stream","hookRequire","exports","memcached_exports","__export","instrumentMemcached","KEY_VALUE_COMMANDS","KEY_ONLY_COMMANDS","KEY_NUMBER_COMMANDS","CAS_COMMAND","MULTI_KEY_COMMANDS","NO_KEY_COMMANDS","getServerAddress","wrapCommand","patchMemcachedClient","init_memcached","__esmMin","init_hook","init_patch","init_span","client","servers","proto","commandName","getSpanMeta","options","patchMethod","original","args","operation","serverAddress","extraMeta","span","startCapturedSpan","callbackIndex","originalCb","err","results","runWithCapturedSpan","error","Memcached","cmd","hookRequire","exports","generic_pool_exports","__export","instrumentGenericPool","getPoolStats","patchPool","patchCreatePool","init_generic_pool","__esmMin","init_hook","init_patch","init_span","pool","stats","poolProto","options","patchMethod","original","args","poolStats","span","startCapturedSpan","runWithCapturedSpan","result","resource","postStats","error","value","genericPool","factory","config","proto","hookRequire","exports","restify_exports","__export","instrumentRestify","HTTP_METHODS","METHOD_MAP","wrapHandler","patchRestifyServer","init_restify","__esmMin","init_hook","init_patch","init_span","handler","method","path","type","options","wrapped","req","res","next","httpMethod","routePath","spanName","span","startCapturedSpan","runWithCapturedSpan","wrappedNext","args","err","result","val","error","restify","ServerProto","tempServer","patchMethod","original","i","h","hookRequire","exports","connect_exports","__export","instrumentConnect","wrapMiddleware","patchConnectApp","init_connect","__esmMin","init_hook","init_patch","init_span","fn","route","options","middlewareName","isErrorHandler","wrapped","err","req","res","next","span","startCapturedSpan","runWithCapturedSpan","wrappedNext","args","hasError","result","error","connectModule","appProto","app","patchMethod","original","startIdx","i","hookRequire","exports","dataloader_exports","__export","instrumentDataloader","patchDataLoader","init_dataloader","__esmMin","init_hook","init_patch","init_span","DataLoader","options","proto","patchMethod","original","key","loaderName","span","startCapturedSpan","runWithCapturedSpan","result","value","error","keys","keyCount","values","errorCount","v","batchMethodName","args","batchSize","hookRequire","exports","lru_memoizer_exports","__export","instrumentLruMemoizer","wrapMemoizedFunction","patchLruMemoizer","init_lru_memoizer","__esmMin","init_hook","init_span","memoized","loadFnName","options","name","wrapped","args","span","startCapturedSpan","lastIdx","originalCb","err","results","runWithCapturedSpan","error","result","value","key","lruMemoizer","wrappedFactory","memoizerOptions","originalSync","hookRequire","exports","fs_exports","__export","instrumentFs","PATH_OPERATIONS","TWO_PATH_OPERATIONS","sanitizePath","patchFsCallbackMethod","patchFsPromiseMethod","patchFs","init_fs","__esmMin","init_hook","init_patch","init_span","filePath","pathStr","fsModule","methodName","pathArgCount","options","patchMethod","original","args","operation","spanMeta","span","startCapturedSpan","callbackIndex","arg","idx","originalCb","err","results","runWithCapturedSpan","result","error","fsPromises","value","method","promises","fs","hookRequire","exports","openai_exports","__export","instrumentOpenAI","OPERATION_MAP","getOperationName","getRequestModel","patchOpenAIClient","init_openai","__esmMin","init_hook","init_patch","init_span","path","normalized","pattern","name","body","openaiModule","options","OpenAI","proto","httpMethods","method","patchMethod","original","opts","operationName","model","httpMethod","spanName","span","startCapturedSpan","runWithCapturedSpan","result","response","endMeta","error","statusCode","requestOptions","args","hookRequire","exports","anthropic_exports","__export","instrumentAnthropic","OPERATION_MAP","getOperationName","getRequestModel","patchAnthropicClient","init_anthropic","__esmMin","init_hook","init_patch","init_span","path","normalized","pattern","name","body","anthropicModule","options","Anthropic","proto","httpMethods","method","patchMethod","original","opts","operationName","model","httpMethod","spanName","span","startCapturedSpan","runWithCapturedSpan","result","response","endMeta","error","statusCode","requestOptions","args","hookRequire","exports","google_genai_exports","__export","instrumentGoogleGenAI","extractUsage","extractResponseUsage","patchGoogleGenAI","patchVertexAI","init_google_genai","__esmMin","init_hook","init_patch","init_span","response","meta","usage","finishReason","result","genaiModule","options","GenerativeModel","proto","patchMethod","original","request","modelName","span","startCapturedSpan","runWithCapturedSpan","value","error","streamResult","resp","ChatSession","chatProto","method","args","isStream","vertexModule","hookRequire","exports","azure_openai_exports","__export","instrumentAzureOpenAI","METHODS","patchAzureOpenAIClient","init_azure_openai","__esmMin","init_hook","init_patch","init_span","result","meta","azureModule","options","OpenAIClient","proto","methodConfig","patchMethod","original","deploymentName","args","span","startCapturedSpan","runWithCapturedSpan","value","error","hookRequire","exports","cohere_exports","__export","instrumentCohere","METHODS","patchCohereClient","init_cohere","__esmMin","init_hook","init_patch","init_span","args","result","meta","proto","clientName","options","methodConfig","patchMethod","original","model","spanName","span","startCapturedSpan","runWithCapturedSpan","value","error","hookRequire","exports","mistral_exports","__export","instrumentMistral","extractMistralUsage","patchResourceMethod","patchMistralClient","init_mistral","__esmMin","init_hook","init_patch","init_span","result","meta","finishReason","resource","methodName","operation","getModel","extractUsage","patchKey","options","patchMethod","original","args","model","spanName","span","startCapturedSpan","runWithCapturedSpan","value","error","mistralModule","Mistral","proto","httpMethods","method","path","tempClient","chatProto","embedProto","fimProto","hookRequire","exports","firebase_exports","__export","instrumentFirebase","wrapFirestoreMethod","getPath","getCollectionName","patchFirestore","AUTH_METHODS","patchFirebaseAuth","MESSAGING_METHODS","patchFirebaseMessaging","init_firebase","__esmMin","init_hook","init_patch","init_span","proto","methodName","getSpanInfo","patchKey","options","patchMethod","original","args","name","meta","span","startCapturedSpan","runWithCapturedSpan","result","value","endMeta","error","ref","firestoreModule","DocRef","docProto","instance","ColRef","Query","Transaction","method","_instance","WriteBatch","authModule","Auth","messagingModule","Messaging","hookRequire","exports","firestore","lambda_handler_exports","__export","handler","__toCommonJS","init_internal","Transport","config","baseEndpoint","trace","task","error","type","log","payload","queue","item","maxQueueSize","items","totalApm","totalTask","endpoint","controller","timeout","response","SENZOR_INTERNAL_HEADER","apmPayload","taskPayload","sends","failures","result","err","key","proc","flushSyncBestEffort","init_context","_isNode","isNode","getEnv","key","_isNode","package_default","SDK_META","package_default","init_traceContext","init_ids","init_sanitizer","init_span","GC_KINDS","GcObserver","PerformanceObserver","list","entry","kindKey","snapshot","EventLoopLagMeter","monitorEventLoopDelay","now","elapsed","result","EventLoopUtilization","perfHooks","elu2","util","RuntimeMetricsCollector","options","isNode","mem","gc","lagInfo","eluPercent","cpuUserUs","cpuSystemUs","delta","activeHandles","activeRequests","metrics","safeStringify","obj","cache","key","value","SenzorClient","options","endpoint","debug","Transport","name","setting","instrumentFetch","isNode","instrumentHttp","instrumentExpress","instrumentFastify","instrumentKoa","instrumentUndici","instrumentMongo","instrumentMongoose","instrumentPg","instrumentMysql","instrumentRedis","instrumentBullMQ","instrumentNodeCron","instrumentGrpc","instrumentGraphQL","instrumentDns","instrumentNet","instrumentKafka","instrumentAmqplib","instrumentSocketIO","instrumentNestJS","instrumentHapi","instrumentPino","instrumentWinston","instrumentBunyan","instrumentAwsSdk","instrumentKnex","instrumentTedious","instrumentCassandra","instrumentMemcached","instrumentGenericPool","instrumentRestify","instrumentConnect","instrumentDataloader","instrumentLruMemoizer","instrumentFs","instrumentOpenAI","instrumentAnthropic","instrumentGoogleGenAI","instrumentAzureOpenAI","instrumentCohere","instrumentMistral","instrumentFirebase","RuntimeMetricsCollector","payload","levels","originalConsole","isIntercepting","level","args","message","attributes","arg","parsed","sanitizeAttributes","currentTrace","Context","logType","logPayload","getProcessContext","getMemoryContext","mem","safeCapture","error","meta","parsedError","enrichedMeta","SDK_META","internalFailure","reason","warning","type","promise","data","next","existingTrace","inheritedTraceId","inheritedParentSpanId","getHeader","traceparent","parsedContext","parseTraceparent","rawTrace","rawSpan","activeTraceId","generateTraceId","rootSpanId","generateSpanId","trace","status","extraData","duration","currentContext","triggerTraceId","startMemory","startCpu","task","extraMetadata","resourceMetrics","endMemory","cpuDelta","fn","result","context","errPayload","span","startCapturedSpan","client","init_normalizer","init_getClientIp","isColdStart","detectTrigger","event","extractHttpEvent","trigger","normalizeHeaders","headers","normalized","key","value","extractLambdaAttributes","context","coldStart","attrs","mapTriggerToFaasTrigger","region","arnParts","arnSrc","topicArn","r","extractStatusFromResponse","result","registerExtension","registered","onShutdown","runtimeApi","extensionName","registerUrl","registerResponse","extensionId","nextUrl","eventResponse","wrapLambda","handler","client","lambdaAttrs","httpInfo","method","path","route","normalizePath","getClientIp","status","err","path","truthy","value","numberFromEnv","parsed","apiKey","getEnv","endpoint","isLambda","options","client","parseHandlerString","handlerStr","lastSlash","afterSlash","beforeSlash","firstDot","moduleName","fnParts","resolveExport","moduleExports","fnPath","current","part","loadHandlerModule","modulePath","taskRoot","absolutePath","extensions","ext","handlerEnv","wrappedHandler","message","handlerModule","originalHandler","wrapLambda","errorMsg","handler"]}