@senzops/apm-node 1.2.0 → 1.2.2

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.
Files changed (68) hide show
  1. package/.claude/worktrees/infallible-chatelet-f3fb36/.claude/settings.local.json +9 -0
  2. package/.claude/worktrees/infallible-chatelet-f3fb36/CHANGELOG.md +49 -0
  3. package/.claude/worktrees/infallible-chatelet-f3fb36/README.md +398 -0
  4. package/.claude/worktrees/infallible-chatelet-f3fb36/package-lock.json +1494 -0
  5. package/.claude/worktrees/infallible-chatelet-f3fb36/package.json +42 -0
  6. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/client.ts +451 -0
  7. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/context.ts +48 -0
  8. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/normalizer.ts +44 -0
  9. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/sanitizer.ts +203 -0
  10. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/transport.ts +273 -0
  11. package/.claude/worktrees/infallible-chatelet-f3fb36/src/core/types.ts +106 -0
  12. package/.claude/worktrees/infallible-chatelet-f3fb36/src/index.ts +36 -0
  13. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/bullmq.ts +195 -0
  14. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/cron.ts +204 -0
  15. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/express.ts +338 -0
  16. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/fastify.ts +296 -0
  17. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/framework.ts +301 -0
  18. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/hook.ts +134 -0
  19. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/http.ts +530 -0
  20. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/koa.ts +173 -0
  21. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/mongo.ts +202 -0
  22. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/mongoose.ts +156 -0
  23. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/mysql.ts +169 -0
  24. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/patch.ts +56 -0
  25. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/pg.ts +131 -0
  26. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/redis.ts +109 -0
  27. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/span.ts +73 -0
  28. package/.claude/worktrees/infallible-chatelet-f3fb36/src/instrumentation/undici.ts +189 -0
  29. package/.claude/worktrees/infallible-chatelet-f3fb36/src/middleware/express.ts +48 -0
  30. package/.claude/worktrees/infallible-chatelet-f3fb36/src/register.ts +58 -0
  31. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/getClientIp.ts +175 -0
  32. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/ids.ts +7 -0
  33. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/internal.ts +1 -0
  34. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/sdkMeta.ts +6 -0
  35. package/.claude/worktrees/infallible-chatelet-f3fb36/src/utils/traceContext.ts +44 -0
  36. package/.claude/worktrees/infallible-chatelet-f3fb36/src/wrappers/fastify.ts +35 -0
  37. package/.claude/worktrees/infallible-chatelet-f3fb36/src/wrappers/h3.ts +59 -0
  38. package/.claude/worktrees/infallible-chatelet-f3fb36/src/wrappers/next.ts +131 -0
  39. package/.claude/worktrees/infallible-chatelet-f3fb36/tsconfig.json +15 -0
  40. package/.claude/worktrees/infallible-chatelet-f3fb36/tsup.config.ts +21 -0
  41. package/.claude/worktrees/infallible-chatelet-f3fb36/wiki.md +852 -0
  42. package/CHANGELOG.md +8 -0
  43. package/README.md +12 -0
  44. package/dist/index.d.mts +5 -0
  45. package/dist/index.d.ts +5 -0
  46. package/dist/index.global.js +1 -1
  47. package/dist/index.global.js.map +1 -1
  48. package/dist/index.js +1 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/index.mjs +1 -1
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/register.js +1 -1
  53. package/dist/register.js.map +1 -1
  54. package/dist/register.mjs +1 -1
  55. package/dist/register.mjs.map +1 -1
  56. package/package.json +1 -1
  57. package/src/core/client.ts +8 -2
  58. package/src/core/types.ts +5 -0
  59. package/src/instrumentation/express.ts +338 -0
  60. package/src/instrumentation/fastify.ts +296 -0
  61. package/src/instrumentation/framework.ts +301 -0
  62. package/src/instrumentation/hook.ts +79 -192
  63. package/src/instrumentation/koa.ts +173 -0
  64. package/src/register.ts +16 -0
  65. package/src/wrappers/fastify.ts +10 -7
  66. package/src/wrappers/h3.ts +40 -16
  67. package/src/wrappers/next.ts +68 -21
  68. package/wiki.md +8 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/internal.ts","../src/core/transport.ts","../src/core/context.ts","../src/core/client.ts","../src/instrumentation/http.ts","../src/core/normalizer.ts","../src/core/sanitizer.ts","../src/utils/getClientIp.ts","../src/utils/traceContext.ts","../src/instrumentation/patch.ts","../src/utils/ids.ts","../src/instrumentation/span.ts","../src/instrumentation/hook.ts","../src/instrumentation/mongo.ts","../src/instrumentation/pg.ts","../src/instrumentation/undici.ts","../src/instrumentation/redis.ts","../src/instrumentation/mysql.ts","../src/instrumentation/mongoose.ts","../src/instrumentation/bullmq.ts","../src/instrumentation/cron.ts","../package.json","../src/utils/sdkMeta.ts","../src/register.ts"],"sourcesContent":["export const SENZOR_INTERNAL_HEADER = 'x-senzor-sdk-internal';\n","import { SENZOR_INTERNAL_HEADER } from '../utils/internal';\nimport { SenzorOptions, Trace, TaskRun, SenzorError, SenzorLog } from './types';\n\ninterface ApmPayload {\n traces: Trace[];\n errors: SenzorError[];\n logs: SenzorLog[];\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\n private taskQueue: TaskRun[] = [];\n private taskErrorQueue: SenzorError[] = [];\n private taskLogQueue: SenzorLog[] = [];\n\n private timer: NodeJS.Timeout | null = null;\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 if (typeof setInterval !== 'undefined') {\n this.timer = setInterval(\n () => void this.flush(),\n config.flushInterval || 10000\n );\n if (this.timer && typeof this.timer.unref === 'function') {\n this.timer.unref();\n }\n }\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 private enqueue<T>(queue: T[], item: T) {\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 = {\n traces: this.traceQueue,\n errors: this.apmErrorQueue,\n logs: this.apmLogQueue\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 }\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 );\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 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 { AsyncLocalStorage } from 'async_hooks';\nimport { ActiveTrace, Span } from './types';\n\nexport const storage = new AsyncLocalStorage<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.ended) return;\n\n const maxSpans = trace.maxSpans ?? 500;\n if (trace.spans.length >= maxSpans) {\n trace.droppedSpans = (trace.droppedSpans ?? 0) + 1;\n return;\n }\n\n trace.spans.push(span);\n }\n};\n","import { Transport } from './transport';\r\nimport { Context } from './context';\r\nimport { SenzorOptions, ActiveTrace, TaskRun, SenzorLog } from './types';\r\nimport { randomUUID } from 'crypto';\r\nimport { instrumentHttp, instrumentFetch } from '../instrumentation/http';\r\nimport { instrumentMongo } from '../instrumentation/mongo';\r\nimport { instrumentPg } from '../instrumentation/pg';\nimport { instrumentUndici } from '../instrumentation/undici';\nimport { instrumentRedis } from '../instrumentation/redis';\nimport { instrumentMysql } from '../instrumentation/mysql';\nimport { instrumentMongoose } from '../instrumentation/mongoose';\nimport { instrumentBullMQ } from '../instrumentation/bullmq';\nimport { instrumentNodeCron } from '../instrumentation/cron';\nimport { SDK_META } from '../utils/sdkMeta';\nimport { parseTraceparent } from '../utils/traceContext';\nimport { generateSpanId, generateTraceId } from '../utils/ids';\nimport { sanitizeAttributes } from './sanitizer';\nimport { startCapturedSpan } from '../instrumentation/span';\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 {\n private transport: Transport | null = null;\n private options: SenzorOptions | null = null;\n private isInstrumented = false;\n\n public preload(options: Partial<SenzorOptions> = {}) {\n const endpoint = options.endpoint || 'https://api.senzor.dev/api/ingest/apm';\n const debug = options.debug || false;\n\n this.options = {\n apiKey: '',\n ...this.options,\n ...options\n };\n\n this.installNativeInstrumentations(endpoint, debug);\n }\n\n public init(options: SenzorOptions) {\n if (!options.apiKey) {\n console.warn('[Senzor] API Key missing. SDK disabled.');\n return;\n }\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\n this.transport = new Transport({ ...options, endpoint });\n this.installNativeInstrumentations(endpoint, debug);\n }\n\n private isInstrumentationEnabled(name: string): boolean {\n const setting = this.options?.instrumentations;\n if (setting === false) return false;\n if (Array.isArray(setting)) return setting.includes(name);\n return true;\n }\n\n private installNativeInstrumentations(endpoint: string, debug: boolean) {\n if (!this.isInstrumented) {\n this.setupGlobalErrorHandlers();\n this.setupLogInterception(); // Fire up Auto Log Instrumentation\n\n try { if (this.isInstrumentationEnabled('http')) instrumentHttp(this, endpoint, this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('fetch')) instrumentFetch(endpoint, this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('undici')) instrumentUndici(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('mongo')) instrumentMongo(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('mongoose')) instrumentMongoose(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('pg')) instrumentPg(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('mysql')) instrumentMysql(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('redis')) instrumentRedis(this.options || undefined); } catch (e) { }\n\n // Task Integrations \n try { if (this.isInstrumentationEnabled('bullmq')) instrumentBullMQ(this, debug); } catch (e) { }\n try { if (this.isInstrumentationEnabled('cron')) instrumentNodeCron(this, debug); } catch (e) { }\n\n this.isInstrumented = true;\n if (debug) console.log('[Senzor] Auto-instrumentation enabled');\n }\n }\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 {\n // New Relic Style Destructuring: Merge all object keys into `attributes`\n const parsed = JSON.parse(safeStringify(arg));\n attributes = { ...attributes, ...sanitizeAttributes(parsed, this.options || undefined) };\n } catch (e) {\n attributes.unparseableObject = true;\n }\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 ((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 {\n if (!this.transport) return next();\n\n const existingTrace = Context.current();\n if (existingTrace?.contextType === 'apm') {\n existingTrace.data = {\n ...existingTrace.data,\n ...data\n };\n return next();\n }\n\n let inheritedTraceId: string | undefined = undefined;\n let inheritedParentSpanId: string | undefined = undefined;\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();\n const rootSpanId = generateSpanId();\n\n const trace: ActiveTrace = {\n id: activeTraceId,\n contextType: 'apm',\n startTime: performance.now(),\n rootSpanId,\n activeSpanId: rootSpanId,\n data: { ...data, parentTraceId: inheritedTraceId, parentSpanId: inheritedParentSpanId, rootSpanId },\n spans: [],\n maxSpans: this.options?.maxSpansPerTrace ?? 500,\n droppedSpans: 0\n };\n\r\n return Context.run(trace, next);\r\n }\r\n\r\n public endTrace(status: number, extraData: any = {}) {\n const trace = Context.current();\n if (!trace || trace.contextType !== 'apm' || !this.transport) return;\n if (trace.ended) return;\n trace.ended = true;\n const duration = performance.now() - trace.startTime;\n\n const payload = {\n traceId: trace.id,\n parentTraceId: trace.data.parentTraceId,\n parentSpanId: trace.data.parentSpanId,\n rootSpanId: trace.rootSpanId,\n ...trace.data,\n ...extraData,\n status,\n duration,\n spans: trace.spans,\n droppedSpans: trace.droppedSpans,\n timestamp: new Date().toISOString()\n };\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 = process.memoryUsage ? process.memoryUsage().heapUsed : 0;\r\n const startCpu = process.cpuUsage ? process.cpuUsage() : undefined;\r\n\r\n const task: ActiveTrace = {\n id: randomUUID(),\n contextType: 'task',\n startTime: performance.now(),\n rootSpanId: generateSpanId(),\n startMemory,\n startCpu,\n data: { taskName: name, taskType: type, triggerTraceId, ...options },\n spans: [],\n maxSpans: this.options?.maxSpansPerTrace ?? 500,\n droppedSpans: 0\n };\n task.activeSpanId = task.rootSpanId;\n return Context.run(task, next);\n }\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\r\n let resourceMetrics;\r\n if (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.droppedSpans },\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 = {\n errorClass: parsedError.name || 'Error',\n message: parsedError.message,\n stackTrace: parsedError.stack,\n context: sanitizeAttributes(context, this.options || undefined),\n timestamp: new Date().toISOString()\n };\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 }\n\n public track(data: any) {\n this.transport?.addTrace({ traceId: generateTraceId(), ...data, spans: [], timestamp: new Date().toISOString() });\n }\n\n public startSpan(name: string, type: 'db' | 'http' | 'function' | 'custom' = 'custom') {\n const span = startCapturedSpan(name, type, {}, this.options || undefined);\n if (!span) return { end: () => { } };\n return { end: (meta?: any, status?: number) => span.end(status, meta) };\n }\n\r\n public async flush() { if (this.transport) await this.transport.flush(); }\r\n}\r\n\r\nexport const client = new SenzorClient();\n","import http from 'http';\nimport https from 'https';\nimport { URL } from 'url';\nimport 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.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: typeof http | typeof https,\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 patchIncomingServer(http.Server?.prototype, 'http', client, options);\n patchIncomingServer(https.Server?.prototype, 'https', client, options);\n\n patchOutgoing(http, 'http:', ingestUrl, options);\n patchOutgoing(https, 'https:', ingestUrl, options);\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};","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","/**\r\n * getClientIp.ts\r\n *\r\n * Robust, proxy-aware client IP extraction.\r\n *\r\n * Priority order (mirrors Umami + industry best practice):\r\n * 1. ENV-configured custom header (CLIENT_IP_HEADER)\r\n * 2. CF-Connecting-IP (Cloudflare — single trusted IP)\r\n * 3. True-Client-IP (Cloudflare Enterprise / Akamai)\r\n * 4. X-Real-IP (Nginx realip module)\r\n * 5. Forwarded (RFC 7239 — \"for=\" field)\r\n * 6. X-Forwarded-For (De-facto standard — leftmost public IP)\r\n * 7. req.socket.remoteAddress (Direct connection fallback)\r\n *\r\n * Security note: headers 2-6 can be spoofed by clients when your server is\r\n * directly internet-facing. If that is a concern, restrict extraction to the\r\n * header your trusted reverse-proxy injects (CLIENT_IP_HEADER or X-Real-IP).\r\n */\r\n\r\nimport { isIP } from \"net\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Helpers\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Strip IPv4-mapped IPv6 prefix (::ffff:1.2.3.4 → 1.2.3.4) */\r\nconst stripIPv6Mapped = (ip: string): string =>\r\n ip.startsWith(\"::ffff:\") ? ip.slice(7) : ip;\r\n\r\n/** Strip optional port from an IPv4 address (1.2.3.4:5678 → 1.2.3.4). */\r\nconst stripIPv4Port = (ip: string): string => {\r\n const lastColon = ip.lastIndexOf(\":\");\r\n if (lastColon === -1) return ip;\r\n const maybeIP = ip.slice(0, lastColon);\r\n return isIP(maybeIP) === 4 ? maybeIP : ip;\r\n};\r\n\r\n/** Strip brackets + optional port from an IPv6 address ([::1]:5678 → ::1). */\r\nconst stripIPv6Brackets = (ip: string): string => {\r\n const match = ip.match(/^\\[([^\\]]+)\\](?::\\d+)?$/);\r\n return match ? match[1] : ip;\r\n};\r\n\r\n/** Normalise raw IP string into a clean, routable address (or null). */\r\nexport const normaliseIP = (raw: string | undefined | null): string | null => {\r\n if (!raw) return null;\r\n let ip = raw.trim();\r\n if (!ip) return null;\r\n\r\n ip = stripIPv6Brackets(ip);\r\n ip = stripIPv4Port(ip);\r\n ip = stripIPv6Mapped(ip);\r\n\r\n return isIP(ip) !== 0 ? ip : null;\r\n};\r\n\r\n/**\r\n * Returns true for IPs that will never produce a geo result:\r\n * loopback, link-local, private ranges, and unspecified addresses.\r\n */\r\nexport const isPrivateOrLoopback = (ip: string): boolean => {\r\n // IPv4 private / loopback / link-local\r\n if (\r\n ip === \"127.0.0.1\" ||\r\n ip.startsWith(\"10.\") ||\r\n ip.startsWith(\"192.168.\") ||\r\n ip.startsWith(\"169.254.\") || // link-local\r\n /^172\\.(1[6-9]|2\\d|3[01])\\./.test(ip) // 172.16–31\r\n )\r\n return true;\r\n\r\n // IPv6 loopback / unspecified / link-local / unique-local\r\n if (\r\n ip === \"::1\" ||\r\n ip === \"::\" ||\r\n ip.toLowerCase().startsWith(\"fe80:\") || // link-local\r\n ip.toLowerCase().startsWith(\"fc\") || // unique-local\r\n ip.toLowerCase().startsWith(\"fd\") // unique-local\r\n )\r\n return true;\r\n\r\n return false;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// RFC 7239 \"Forwarded\" header parser\r\n// e.g. Forwarded: for=192.0.2.60;proto=http, for=\"[2001:db8::cafe]\"\r\n// ---------------------------------------------------------------------------\r\nconst parseForwardedHeader = (header: string): string | null => {\r\n const parts = header.split(\",\");\r\n for (const part of parts) {\r\n const forMatch = part.match(/for=[\"[]?([^\\]\",;>\\s]+)/i);\r\n if (forMatch) {\r\n const ip = normaliseIP(forMatch[1]);\r\n if (ip && !isPrivateOrLoopback(ip)) return ip;\r\n }\r\n }\r\n return null;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// X-Forwarded-For parser — pick the leftmost *public* IP\r\n// e.g. X-Forwarded-For: client, proxy1, proxy2\r\n// ---------------------------------------------------------------------------\r\nconst parseXForwardedFor = (header: string): string | null => {\r\n const ips = header.split(\",\").map((s) => s.trim());\r\n for (const raw of ips) {\r\n const ip = normaliseIP(raw);\r\n if (ip && !isPrivateOrLoopback(ip)) return ip;\r\n }\r\n // If every hop is private (intranet-only setup) fall back to first valid IP\r\n for (const raw of ips) {\r\n const ip = normaliseIP(raw);\r\n if (ip) return ip;\r\n }\r\n return null;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main export\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Extract the best-available client IP from a request.\r\n *\r\n * Returns `null` if no valid IP can be determined.\r\n */\r\nexport const getClientIp = (req: any): string | null => {\r\n const h = req.headers;\r\n\r\n // 2. Cloudflare single-IP header (most reliable when behind CF)\r\n {\r\n const ip = normaliseIP(h[\"cf-connecting-ip\"] as string);\r\n if (ip) return ip;\r\n }\r\n\r\n // 3. Cloudflare Enterprise / Akamai\r\n {\r\n const ip = normaliseIP(h[\"true-client-ip\"] as string);\r\n if (ip) return ip;\r\n }\r\n\r\n // 4. Nginx realip module (single, already-trusted IP)\r\n {\r\n const ip = normaliseIP(h[\"x-real-ip\"] as string);\r\n if (ip) return ip;\r\n }\r\n\r\n // 5. RFC 7239 Forwarded header\r\n {\r\n const fwd = h[\"forwarded\"] as string;\r\n if (fwd) {\r\n const ip = parseForwardedHeader(fwd);\r\n if (ip) return ip;\r\n }\r\n }\r\n\r\n // 6. De-facto standard XFF\r\n {\r\n const xff = h[\"x-forwarded-for\"] as string;\r\n if (xff) {\r\n const ip = parseXForwardedFor(xff);\r\n if (ip) return ip;\r\n }\r\n }\r\n\r\n // 7. Direct TCP connection (local dev / no proxy)\r\n {\r\n const raw = req.socket?.remoteAddress;\r\n const ip = normaliseIP(raw);\r\n if (ip) return ip;\r\n }\r\n\r\n return null;\r\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 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 { randomUUID } from 'crypto';\n\nexport const generateTraceId = (): string =>\n randomUUID().replace(/-/g, '');\n\nexport const generateSpanId = (): string =>\n randomUUID().replace(/-/g, '').slice(0, 16);\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","import Module from 'module';\r\n\r\nconst SENZOR_PATCHED =\r\n Symbol.for('senzor.require.patched');\r\n\r\nconst SENZOR_HOOKS =\r\n Symbol.for('senzor.require.hooks');\r\n\r\ntype HookFn =\r\n (exports: unknown) => void;\r\n\r\ntype HookMap =\r\n Map<string, HookFn[]>;\r\n\r\nfunction getHookRegistry(): HookMap {\r\n\r\n const mod =\r\n Module as unknown as Record<\r\n symbol,\r\n HookMap\r\n >;\r\n\r\n if (!mod[SENZOR_HOOKS]) {\r\n\r\n Object.defineProperty(\r\n mod,\r\n SENZOR_HOOKS,\r\n {\r\n value: new Map(),\r\n enumerable: false\r\n }\r\n );\r\n\r\n }\r\n\r\n return mod[SENZOR_HOOKS];\r\n\r\n}\r\n\r\nfunction runHooks(\r\n moduleName: string,\r\n exports: unknown\r\n) {\r\n\r\n const registry =\r\n (Module as unknown as Record<\r\n symbol,\r\n HookMap\r\n >)[SENZOR_HOOKS];\r\n\r\n if (!registry) return;\r\n\r\n const hooks =\r\n registry.get(moduleName);\r\n\r\n if (!hooks?.length) return;\r\n\r\n for (const hook of hooks) {\r\n\r\n try {\r\n hook(exports);\r\n }\r\n catch (err) {\r\n\r\n console.error(\r\n `[Senzor] instrumentation failed for ${moduleName}`,\r\n err\r\n );\r\n\r\n }\r\n\r\n }\r\n\r\n}\r\n\r\nfunction patchLoaderOnce() {\r\n\r\n const mod =\r\n Module as unknown as any;\r\n\r\n if (mod[SENZOR_PATCHED]) {\r\n return;\r\n }\r\n\r\n const previousLoad =\r\n mod._load;\r\n\r\n mod._load =\r\n function patchedLoad(\r\n request: string,\r\n parent: unknown,\r\n isMain: boolean\r\n ) {\r\n\r\n const exports =\r\n previousLoad.apply(\r\n this,\r\n arguments\r\n );\r\n\r\n runHooks(\r\n request,\r\n exports\r\n );\r\n\r\n return exports;\r\n\r\n };\r\n\r\n Object.defineProperty(\r\n mod,\r\n SENZOR_PATCHED,\r\n {\r\n value: true,\r\n enumerable: false\r\n }\r\n );\r\n\r\n}\r\n\r\nfunction patchCached(\r\n moduleName: string,\r\n hook: HookFn\r\n) {\r\n\r\n try {\r\n\r\n const resolved =\r\n require.resolve(\r\n moduleName\r\n );\r\n\r\n const cached =\r\n require.cache?.[\r\n resolved\r\n ];\r\n\r\n if (cached?.exports) {\r\n\r\n hook(\r\n cached.exports\r\n );\r\n\r\n }\r\n\r\n }\r\n catch { }\r\n\r\n}\r\n\r\nfunction tryRequire(\r\n moduleName: string,\r\n hook: HookFn\r\n) {\r\n\r\n try {\r\n\r\n const mod =\r\n require(moduleName);\r\n\r\n if (mod) {\r\n hook(mod);\r\n }\r\n\r\n }\r\n catch { }\r\n\r\n}\r\n\r\nfunction retryPatch(\r\n moduleName: string,\r\n hook: HookFn\r\n) {\r\n\r\n let attempts = 0;\r\n\r\n const max = 5;\r\n\r\n const timer =\r\n setInterval(() => {\r\n\r\n attempts++;\r\n\r\n try {\r\n\r\n const mod =\r\n require(moduleName);\r\n\r\n if (mod) {\r\n\r\n hook(mod);\r\n\r\n clearInterval(timer);\r\n\r\n }\r\n\r\n }\r\n catch { }\r\n\r\n if (attempts >= max) {\r\n clearInterval(timer);\r\n }\r\n\r\n }, 200);\r\n\r\n}\r\n\r\nexport const hookRequire =\r\n (\r\n moduleName: string,\r\n onRequire: HookFn\r\n ) => {\r\n\r\n const registry =\r\n getHookRegistry();\r\n\r\n if (!registry.has(moduleName)) {\r\n\r\n registry.set(\r\n moduleName,\r\n []\r\n );\r\n\r\n }\r\n\r\n registry\r\n .get(moduleName)!\r\n .push(onRequire);\r\n\r\n patchLoaderOnce();\r\n\r\n patchCached(\r\n moduleName,\r\n onRequire\r\n );\r\n\r\n tryRequire(\r\n moduleName,\r\n onRequire\r\n );\r\n\r\n retryPatch(\r\n moduleName,\r\n onRequire\r\n );\r\n\r\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 { 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 { 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 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 { 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 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 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 };","{\r\n \"name\": \"@senzops/apm-node\",\r\n \"version\": \"1.2.0\",\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 \"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 },\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 },\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 ],\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 { client } from './core/client';\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 process.env.SENZOR_API_KEY ||\n process.env.SENZOR_APM_API_KEY ||\n process.env.SENZOR_SERVICE_API_KEY;\n\nconst endpoint =\n process.env.SENZOR_ENDPOINT ||\n process.env.SENZOR_APM_ENDPOINT;\n\nconst options = {\n apiKey: apiKey || '',\n endpoint,\n debug: truthy(process.env.SENZOR_DEBUG),\n autoLogs: process.env.SENZOR_AUTO_LOGS === 'false' ? false : undefined,\n batchSize: numberFromEnv(process.env.SENZOR_BATCH_SIZE),\n flushInterval: numberFromEnv(process.env.SENZOR_FLUSH_INTERVAL),\n flushTimeoutMs: numberFromEnv(process.env.SENZOR_FLUSH_TIMEOUT_MS),\n maxQueueSize: numberFromEnv(process.env.SENZOR_MAX_QUEUE_SIZE),\n maxSpansPerTrace: numberFromEnv(process.env.SENZOR_MAX_SPANS_PER_TRACE),\n captureHeaders: truthy(process.env.SENZOR_CAPTURE_HEADERS),\n captureDbStatement:\n process.env.SENZOR_CAPTURE_DB_STATEMENT === 'false'\n ? false\n : undefined\n};\n\nif (apiKey) {\n client.init(options);\n} else {\n client.preload(options);\n}\n"],"mappings":"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","names":["SENZOR_INTERNAL_HEADER","Transport","config","baseEndpoint","trace","task","error","type","log","queue","item","maxQueueSize","items","totalApm","totalTask","payload","endpoint","controller","timeout","response","SENZOR_INTERNAL_HEADER","apmPayload","taskPayload","sends","failures","result","err","key","proc","flushSyncBestEffort","AsyncLocalStorage","storage","Context","trace","fn","spanId","store","span","maxSpans","randomUUID","http","https","URL","normalizePath","path","getRoute","req","fallbackPath","DEFAULT_MAX_ATTRIBUTES","DEFAULT_MAX_ATTRIBUTE_LENGTH","MAX_DEPTH","MAX_ARRAY_ITEMS","SENSITIVE_KEY_PATTERN","getLimits","options","truncate","value","maxLength","isSensitiveKey","key","sanitizePrimitive","sanitizeValue","depth","primitive","item","output","count","childKey","childValue","sanitizeAttributes","attributes","limits","normalizedOptions","sanitizeHeaders","headers","plainHeaders","normalizeSql","sql","collapsed","withoutLiterals","getSqlOperation","isIP","stripIPv6Mapped","ip","stripIPv4Port","lastColon","maybeIP","stripIPv6Brackets","match","normaliseIP","raw","isPrivateOrLoopback","parseForwardedHeader","header","parts","part","forMatch","parseXForwardedFor","ips","s","getClientIp","req","h","fwd","xff","TRACEPARENT_REGEX","parseTraceparent","header","traceparent","match","traceId","parentSpanId","flags","sampled","generateTraceparent","spanId","PATCHES","ORIGINAL","patchMethod","target","methodName","patchKey","wrapper","current","existingPatches","original","wrapped","patches","randomUUID","generateTraceId","generateSpanId","startCapturedSpan","name","type","meta","options","trace","Context","spanId","generateSpanId","parentSpanId","startTime","startedAt","ended","status","extraMeta","mergedMeta","sanitizeAttributes","runWithCapturedSpan","span","fn","getDebug","options","isPlainObject","value","URL","headerValue","headers","key","name","normalizedKey","hasInternalHeader","SENZOR_INTERNAL_HEADER","shouldIgnoreUrl","urlString","ingestUrl","url","ingest","cloneHeaders","cloned","acc","setHeader","existingKey","header","prepareRequestArgs","args","defaultProtocol","nextArgs","optionsIndex","urlFromArg","protocol","hostname","path","method","resolveIncomingRoute","req","res","getRoute","normalizePath","patchIncomingServer","proto","client","patchMethod","original","event","Context","rawPath","getClientIp","sanitizeHeaders","trace","finalized","finalize","reason","error","patchOutgoing","moduleRef","patchKeyPrefix","requestWrapper","prepared","span","startCapturedSpan","generateTraceparent","invoke","completed","endSpan","status","extraMeta","statusCode","finish","runWithCapturedSpan","instrumentFetch","input","init","originalHeaders","nextInit","response","instrumentHttp","http","https","Module","SENZOR_PATCHED","SENZOR_HOOKS","getHookRegistry","mod","Module","runHooks","moduleName","exports","registry","hooks","hook","err","patchLoaderOnce","previousLoad","request","parent","isMain","patchCached","resolved","__require","cached","tryRequire","retryPatch","attempts","max","timer","hookRequire","onRequire","collectionName","collection","databaseName","cursorCollectionName","cursor","patchCollectionMethod","proto","method","options","patchMethod","original","args","span","startCapturedSpan","runWithCapturedSpan","result","value","error","patchCursorMethod","operation","patchMongo","mongodb","collectionProto","FindCursor","AggregationCursor","instrumentMongo","hookRequire","exports","extractSql","args","first","wrapQueryMethod","proto","label","options","patchMethod","original","sql","operation","getSqlOperation","span","startCapturedSpan","normalizeSql","callbackIndex","arg","originalCallback","err","result","runWithCapturedSpan","value","error","patchPg","pg","instrumentPg","hookRequire","exports","hasInternalHeader","headers","key","value","SENZOR_INTERNAL_HEADER","setHeader","nextHeaders","existingKey","header","getUrlDetails","input","url","patchRequestLike","target","methodName","patchKey","options","patchMethod","original","opts","cb","details","method","span","startCapturedSpan","normalizePath","nextOptions","generateTraceparent","wrappedCallback","err","data","runWithCapturedSpan","result","error","patchUndici","undici","proto","index","instrumentUndici","hookRequire","exports","getCommandName","command","patchSendCommand","target","label","options","patchMethod","original","args","commandName","span","startCapturedSpan","runWithCapturedSpan","result","value","error","patchCreatedClient","client","patchRedisPackage","redis","factory","patchIORedisPackage","ioredis","instrumentRedis","hookRequire","exports","extractSql","args","first","patchSqlMethod","proto","method","library","options","patchMethod","original","sql","operation","getSqlOperation","span","startCapturedSpan","normalizeSql","callbackIndex","arg","originalCallback","err","rows","runWithCapturedSpan","result","value","error","patchKnownPrototypes","mysql","patchFactories","factory","client","patchMysql","instrumentMysql","hookRequire","exports","modelName","target","collectionName","patchExec","proto","label","options","patchMethod","original","args","operation","collection","span","startCapturedSpan","runWithCapturedSpan","result","value","error","patchSave","modelProto","patchMongoose","mongoose","instrumentMongoose","hookRequire","exports","PATCHED","patchWorker","target","client","debug","proto","original","job","queueDelay","currentAttempt","maxAttempts","isFinal","taskName","result","error","ctx","Context","instrumentBullMQ","hookRequire","exports","PATCHED","normalizeOptions","options","patchTarget","target","client","debug","schedule","original","wrapped","expression","handler","opts","taskName","wrappedHandler","err","instrumentNodeCron","hookRequire","exports","package_default","SDK_META","package_default","safeStringify","obj","cache","key","value","SenzorClient","options","endpoint","debug","Transport","name","setting","instrumentHttp","instrumentFetch","instrumentUndici","instrumentMongo","instrumentMongoose","instrumentPg","instrumentMysql","instrumentRedis","instrumentBullMQ","instrumentNodeCron","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","payload","currentContext","triggerTraceId","startMemory","startCpu","task","randomUUID","extraMetadata","resourceMetrics","endMemory","cpuDelta","fn","result","context","errPayload","span","startCapturedSpan","client","truthy","value","numberFromEnv","parsed","apiKey","endpoint","options","client"]}
1
+ {"version":3,"sources":["../src/utils/internal.ts","../src/core/transport.ts","../src/core/context.ts","../src/core/client.ts","../src/instrumentation/http.ts","../src/core/normalizer.ts","../src/core/sanitizer.ts","../src/utils/getClientIp.ts","../src/utils/traceContext.ts","../src/instrumentation/patch.ts","../src/utils/ids.ts","../src/instrumentation/span.ts","../src/instrumentation/hook.ts","../src/instrumentation/framework.ts","../src/instrumentation/express.ts","../src/instrumentation/fastify.ts","../src/instrumentation/koa.ts","../src/instrumentation/mongo.ts","../src/instrumentation/pg.ts","../src/instrumentation/undici.ts","../src/instrumentation/redis.ts","../src/instrumentation/mysql.ts","../src/instrumentation/mongoose.ts","../src/instrumentation/bullmq.ts","../src/instrumentation/cron.ts","../package.json","../src/utils/sdkMeta.ts","../src/register.ts"],"sourcesContent":["export const SENZOR_INTERNAL_HEADER = 'x-senzor-sdk-internal';\n","import { SENZOR_INTERNAL_HEADER } from '../utils/internal';\nimport { SenzorOptions, Trace, TaskRun, SenzorError, SenzorLog } from './types';\n\ninterface ApmPayload {\n traces: Trace[];\n errors: SenzorError[];\n logs: SenzorLog[];\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\n private taskQueue: TaskRun[] = [];\n private taskErrorQueue: SenzorError[] = [];\n private taskLogQueue: SenzorLog[] = [];\n\n private timer: NodeJS.Timeout | null = null;\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 if (typeof setInterval !== 'undefined') {\n this.timer = setInterval(\n () => void this.flush(),\n config.flushInterval || 10000\n );\n if (this.timer && typeof this.timer.unref === 'function') {\n this.timer.unref();\n }\n }\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 private enqueue<T>(queue: T[], item: T) {\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 = {\n traces: this.traceQueue,\n errors: this.apmErrorQueue,\n logs: this.apmLogQueue\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 }\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 );\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 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 { AsyncLocalStorage } from 'async_hooks';\nimport { ActiveTrace, Span } from './types';\n\nexport const storage = new AsyncLocalStorage<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.ended) return;\n\n const maxSpans = trace.maxSpans ?? 500;\n if (trace.spans.length >= maxSpans) {\n trace.droppedSpans = (trace.droppedSpans ?? 0) + 1;\n return;\n }\n\n trace.spans.push(span);\n }\n};\n","import { Transport } from './transport';\r\nimport { Context } from './context';\r\nimport { SenzorOptions, ActiveTrace, TaskRun, SenzorLog } from './types';\r\nimport { randomUUID } from 'crypto';\r\nimport { instrumentHttp, instrumentFetch } from '../instrumentation/http';\nimport { instrumentExpress } from '../instrumentation/express';\nimport { instrumentFastify } from '../instrumentation/fastify';\nimport { instrumentKoa } from '../instrumentation/koa';\nimport { instrumentMongo } from '../instrumentation/mongo';\nimport { instrumentPg } from '../instrumentation/pg';\nimport { instrumentUndici } from '../instrumentation/undici';\nimport { instrumentRedis } from '../instrumentation/redis';\nimport { instrumentMysql } from '../instrumentation/mysql';\nimport { instrumentMongoose } from '../instrumentation/mongoose';\nimport { instrumentBullMQ } from '../instrumentation/bullmq';\nimport { instrumentNodeCron } from '../instrumentation/cron';\nimport { SDK_META } from '../utils/sdkMeta';\nimport { parseTraceparent } from '../utils/traceContext';\nimport { generateSpanId, generateTraceId } from '../utils/ids';\nimport { sanitizeAttributes } from './sanitizer';\nimport { startCapturedSpan } from '../instrumentation/span';\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 {\n private transport: Transport | null = null;\n private options: SenzorOptions | null = null;\n private isInstrumented = false;\n\n public preload(options: Partial<SenzorOptions> = {}) {\n const endpoint = options.endpoint || 'https://api.senzor.dev/api/ingest/apm';\n const debug = options.debug || false;\n\n this.options = {\n apiKey: '',\n ...this.options,\n ...options\n };\n\n this.installNativeInstrumentations(endpoint, debug);\n }\n\n public init(options: SenzorOptions) {\n if (!options.apiKey) {\n console.warn('[Senzor] API Key missing. SDK disabled.');\n return;\n }\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\n this.transport = new Transport({ ...options, endpoint });\n this.installNativeInstrumentations(endpoint, debug);\n }\n\n private isInstrumentationEnabled(name: string): boolean {\n const setting = this.options?.instrumentations;\n if (setting === false) return false;\n if (Array.isArray(setting)) return setting.includes(name);\n return true;\n }\n\n private installNativeInstrumentations(endpoint: string, debug: boolean) {\n if (!this.isInstrumented) {\n this.setupGlobalErrorHandlers();\n this.setupLogInterception(); // Fire up Auto Log Instrumentation\n\n try { if (this.isInstrumentationEnabled('http')) instrumentHttp(this, endpoint, this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('express')) instrumentExpress(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('fastify')) instrumentFastify(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('koa')) instrumentKoa(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('fetch')) instrumentFetch(endpoint, this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('undici')) instrumentUndici(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('mongo')) instrumentMongo(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('mongoose')) instrumentMongoose(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('pg')) instrumentPg(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('mysql')) instrumentMysql(this.options || undefined); } catch (e) { }\n try { if (this.isInstrumentationEnabled('redis')) instrumentRedis(this.options || undefined); } catch (e) { }\n\n // Task Integrations \n try { if (this.isInstrumentationEnabled('bullmq')) instrumentBullMQ(this, debug); } catch (e) { }\n try { if (this.isInstrumentationEnabled('cron')) instrumentNodeCron(this, debug); } catch (e) { }\n\n this.isInstrumented = true;\n if (debug) console.log('[Senzor] Auto-instrumentation enabled');\n }\n }\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 {\n // New Relic Style Destructuring: Merge all object keys into `attributes`\n const parsed = JSON.parse(safeStringify(arg));\n attributes = { ...attributes, ...sanitizeAttributes(parsed, this.options || undefined) };\n } catch (e) {\n attributes.unparseableObject = true;\n }\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 ((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 {\n if (!this.transport) return next();\n\n const existingTrace = Context.current();\n if (existingTrace?.contextType === 'apm') {\n existingTrace.data = {\n ...existingTrace.data,\n ...data\n };\n return next();\n }\n\n let inheritedTraceId: string | undefined = undefined;\n let inheritedParentSpanId: string | undefined = undefined;\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();\n const rootSpanId = generateSpanId();\n\n const trace: ActiveTrace = {\n id: activeTraceId,\n contextType: 'apm',\n startTime: performance.now(),\n rootSpanId,\n activeSpanId: rootSpanId,\n data: { ...data, parentTraceId: inheritedTraceId, parentSpanId: inheritedParentSpanId, rootSpanId },\n spans: [],\n maxSpans: this.options?.maxSpansPerTrace ?? 500,\n droppedSpans: 0\n };\n\r\n return Context.run(trace, next);\r\n }\r\n\r\n public endTrace(status: number, extraData: any = {}) {\n const trace = Context.current();\n if (!trace || trace.contextType !== 'apm' || !this.transport) return;\n if (trace.ended) return;\n trace.ended = true;\n const duration = performance.now() - trace.startTime;\n\n const payload = {\n traceId: trace.id,\n parentTraceId: trace.data.parentTraceId,\n parentSpanId: trace.data.parentSpanId,\n rootSpanId: trace.rootSpanId,\n ...trace.data,\n ...extraData,\n status,\n duration,\n spans: trace.spans,\n droppedSpans: trace.droppedSpans,\n timestamp: new Date().toISOString()\n };\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 = process.memoryUsage ? process.memoryUsage().heapUsed : 0;\r\n const startCpu = process.cpuUsage ? process.cpuUsage() : undefined;\r\n\r\n const task: ActiveTrace = {\n id: randomUUID(),\n contextType: 'task',\n startTime: performance.now(),\n rootSpanId: generateSpanId(),\n startMemory,\n startCpu,\n data: { taskName: name, taskType: type, triggerTraceId, ...options },\n spans: [],\n maxSpans: this.options?.maxSpansPerTrace ?? 500,\n droppedSpans: 0\n };\n task.activeSpanId = task.rootSpanId;\n return Context.run(task, next);\n }\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\r\n let resourceMetrics;\r\n if (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.droppedSpans },\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 = {\n errorClass: parsedError.name || 'Error',\n message: parsedError.message,\n stackTrace: parsedError.stack,\n context: sanitizeAttributes(context, this.options || undefined),\n timestamp: new Date().toISOString()\n };\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 }\n\n public track(data: any) {\n this.transport?.addTrace({ traceId: generateTraceId(), ...data, spans: [], timestamp: new Date().toISOString() });\n }\n\n public startSpan(name: string, type: 'db' | 'http' | 'function' | 'custom' = 'custom') {\n const span = startCapturedSpan(name, type, {}, this.options || undefined);\n if (!span) return { end: () => { } };\n return { end: (meta?: any, status?: number) => span.end(status, meta) };\n }\n\r\n public async flush() { if (this.transport) await this.transport.flush(); }\r\n}\r\n\r\nexport const client = new SenzorClient();\n","import http from 'http';\nimport https from 'https';\nimport { URL } from 'url';\nimport 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.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: typeof http | typeof https,\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 patchIncomingServer(http.Server?.prototype, 'http', client, options);\n patchIncomingServer(https.Server?.prototype, 'https', client, options);\n\n patchOutgoing(http, 'http:', ingestUrl, options);\n patchOutgoing(https, 'https:', ingestUrl, options);\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};","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","/**\r\n * getClientIp.ts\r\n *\r\n * Robust, proxy-aware client IP extraction.\r\n *\r\n * Priority order (mirrors Umami + industry best practice):\r\n * 1. ENV-configured custom header (CLIENT_IP_HEADER)\r\n * 2. CF-Connecting-IP (Cloudflare — single trusted IP)\r\n * 3. True-Client-IP (Cloudflare Enterprise / Akamai)\r\n * 4. X-Real-IP (Nginx realip module)\r\n * 5. Forwarded (RFC 7239 — \"for=\" field)\r\n * 6. X-Forwarded-For (De-facto standard — leftmost public IP)\r\n * 7. req.socket.remoteAddress (Direct connection fallback)\r\n *\r\n * Security note: headers 2-6 can be spoofed by clients when your server is\r\n * directly internet-facing. If that is a concern, restrict extraction to the\r\n * header your trusted reverse-proxy injects (CLIENT_IP_HEADER or X-Real-IP).\r\n */\r\n\r\nimport { isIP } from \"net\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Helpers\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Strip IPv4-mapped IPv6 prefix (::ffff:1.2.3.4 → 1.2.3.4) */\r\nconst stripIPv6Mapped = (ip: string): string =>\r\n ip.startsWith(\"::ffff:\") ? ip.slice(7) : ip;\r\n\r\n/** Strip optional port from an IPv4 address (1.2.3.4:5678 → 1.2.3.4). */\r\nconst stripIPv4Port = (ip: string): string => {\r\n const lastColon = ip.lastIndexOf(\":\");\r\n if (lastColon === -1) return ip;\r\n const maybeIP = ip.slice(0, lastColon);\r\n return isIP(maybeIP) === 4 ? maybeIP : ip;\r\n};\r\n\r\n/** Strip brackets + optional port from an IPv6 address ([::1]:5678 → ::1). */\r\nconst stripIPv6Brackets = (ip: string): string => {\r\n const match = ip.match(/^\\[([^\\]]+)\\](?::\\d+)?$/);\r\n return match ? match[1] : ip;\r\n};\r\n\r\n/** Normalise raw IP string into a clean, routable address (or null). */\r\nexport const normaliseIP = (raw: string | undefined | null): string | null => {\r\n if (!raw) return null;\r\n let ip = raw.trim();\r\n if (!ip) return null;\r\n\r\n ip = stripIPv6Brackets(ip);\r\n ip = stripIPv4Port(ip);\r\n ip = stripIPv6Mapped(ip);\r\n\r\n return isIP(ip) !== 0 ? ip : null;\r\n};\r\n\r\n/**\r\n * Returns true for IPs that will never produce a geo result:\r\n * loopback, link-local, private ranges, and unspecified addresses.\r\n */\r\nexport const isPrivateOrLoopback = (ip: string): boolean => {\r\n // IPv4 private / loopback / link-local\r\n if (\r\n ip === \"127.0.0.1\" ||\r\n ip.startsWith(\"10.\") ||\r\n ip.startsWith(\"192.168.\") ||\r\n ip.startsWith(\"169.254.\") || // link-local\r\n /^172\\.(1[6-9]|2\\d|3[01])\\./.test(ip) // 172.16–31\r\n )\r\n return true;\r\n\r\n // IPv6 loopback / unspecified / link-local / unique-local\r\n if (\r\n ip === \"::1\" ||\r\n ip === \"::\" ||\r\n ip.toLowerCase().startsWith(\"fe80:\") || // link-local\r\n ip.toLowerCase().startsWith(\"fc\") || // unique-local\r\n ip.toLowerCase().startsWith(\"fd\") // unique-local\r\n )\r\n return true;\r\n\r\n return false;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// RFC 7239 \"Forwarded\" header parser\r\n// e.g. Forwarded: for=192.0.2.60;proto=http, for=\"[2001:db8::cafe]\"\r\n// ---------------------------------------------------------------------------\r\nconst parseForwardedHeader = (header: string): string | null => {\r\n const parts = header.split(\",\");\r\n for (const part of parts) {\r\n const forMatch = part.match(/for=[\"[]?([^\\]\",;>\\s]+)/i);\r\n if (forMatch) {\r\n const ip = normaliseIP(forMatch[1]);\r\n if (ip && !isPrivateOrLoopback(ip)) return ip;\r\n }\r\n }\r\n return null;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// X-Forwarded-For parser — pick the leftmost *public* IP\r\n// e.g. X-Forwarded-For: client, proxy1, proxy2\r\n// ---------------------------------------------------------------------------\r\nconst parseXForwardedFor = (header: string): string | null => {\r\n const ips = header.split(\",\").map((s) => s.trim());\r\n for (const raw of ips) {\r\n const ip = normaliseIP(raw);\r\n if (ip && !isPrivateOrLoopback(ip)) return ip;\r\n }\r\n // If every hop is private (intranet-only setup) fall back to first valid IP\r\n for (const raw of ips) {\r\n const ip = normaliseIP(raw);\r\n if (ip) return ip;\r\n }\r\n return null;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Main export\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Extract the best-available client IP from a request.\r\n *\r\n * Returns `null` if no valid IP can be determined.\r\n */\r\nexport const getClientIp = (req: any): string | null => {\r\n const h = req.headers;\r\n\r\n // 2. Cloudflare single-IP header (most reliable when behind CF)\r\n {\r\n const ip = normaliseIP(h[\"cf-connecting-ip\"] as string);\r\n if (ip) return ip;\r\n }\r\n\r\n // 3. Cloudflare Enterprise / Akamai\r\n {\r\n const ip = normaliseIP(h[\"true-client-ip\"] as string);\r\n if (ip) return ip;\r\n }\r\n\r\n // 4. Nginx realip module (single, already-trusted IP)\r\n {\r\n const ip = normaliseIP(h[\"x-real-ip\"] as string);\r\n if (ip) return ip;\r\n }\r\n\r\n // 5. RFC 7239 Forwarded header\r\n {\r\n const fwd = h[\"forwarded\"] as string;\r\n if (fwd) {\r\n const ip = parseForwardedHeader(fwd);\r\n if (ip) return ip;\r\n }\r\n }\r\n\r\n // 6. De-facto standard XFF\r\n {\r\n const xff = h[\"x-forwarded-for\"] as string;\r\n if (xff) {\r\n const ip = parseXForwardedFor(xff);\r\n if (ip) return ip;\r\n }\r\n }\r\n\r\n // 7. Direct TCP connection (local dev / no proxy)\r\n {\r\n const raw = req.socket?.remoteAddress;\r\n const ip = normaliseIP(raw);\r\n if (ip) return ip;\r\n }\r\n\r\n return null;\r\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 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 { randomUUID } from 'crypto';\n\nexport const generateTraceId = (): string =>\n randomUUID().replace(/-/g, '');\n\nexport const generateSpanId = (): string =>\n randomUUID().replace(/-/g, '').slice(0, 16);\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","import Module from 'module';\r\n\r\nconst SENZOR_PATCHED = Symbol.for('senzor.require.patched');\r\nconst SENZOR_HOOKS = Symbol.for('senzor.require.hooks');\r\n\r\ntype HookFn = (exports: unknown) => unknown | void;\r\ntype HookMap = Map<string, HookFn[]>;\r\n\r\n// Module.createRequire works in both CJS and ESM contexts,\r\n// unlike bare `require` which is unavailable in ESM builds.\r\nconst safeRequire: NodeRequire = Module.createRequire(\r\n typeof __filename !== 'undefined'\r\n ? __filename\r\n : process.cwd() + '/'\r\n);\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 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 const routePath = stringifyPath(layer?.route?.path);\n if (routePath) {\n const baseUrl = req?.baseUrl || '';\n return `${baseUrl}${routePath}` || routePath;\n }\n\n if (req?.route?.path) {\n return `${req.baseUrl || ''}${req.route.path}`;\n }\n\n if (layerPath) {\n const baseUrl = req?.baseUrl || '';\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 if (layer?.name === 'router' || layer?.handle?.stack || layer?.handle?.name === 'router') {\n return 'router' as const;\n }\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 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\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;\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 patchExpress = (\n expressModule: any,\n options?: SenzorOptions\n) => {\n if (!expressModule) return;\n\n const routerProto =\n typeof expressModule?.Router?.prototype?.route === '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 layer = this?.stack?.[this.stack.length - 1];\n\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 result = original.apply(this, args);\n const layer = this?.stack?.[this.stack.length - 1];\n patchLayer(layer, getLayerPath(args), options);\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 router = this?.router || this?._router;\n const result = original.apply(this, args);\n const activeRouter = this?.router || this?._router || router;\n const layer = activeRouter?.stack?.[activeRouter.stack.length - 1];\n patchLayer(layer, getLayerPath(args), options);\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 { 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 { 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 { 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 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 { 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 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 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 };","{\r\n \"name\": \"@senzops/apm-node\",\r\n \"version\": \"1.2.2\",\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 \"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 },\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 },\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 ],\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 { client } from './core/client';\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 process.env.SENZOR_API_KEY ||\n process.env.SENZOR_APM_API_KEY ||\n process.env.SENZOR_SERVICE_API_KEY;\n\nconst endpoint =\n process.env.SENZOR_ENDPOINT ||\n process.env.SENZOR_APM_ENDPOINT;\n\nconst options = {\n apiKey: apiKey || '',\n endpoint,\n debug: truthy(process.env.SENZOR_DEBUG),\n autoLogs: process.env.SENZOR_AUTO_LOGS === 'false' ? false : undefined,\n batchSize: numberFromEnv(process.env.SENZOR_BATCH_SIZE),\n flushInterval: numberFromEnv(process.env.SENZOR_FLUSH_INTERVAL),\n flushTimeoutMs: numberFromEnv(process.env.SENZOR_FLUSH_TIMEOUT_MS),\n maxQueueSize: numberFromEnv(process.env.SENZOR_MAX_QUEUE_SIZE),\n maxSpansPerTrace: numberFromEnv(process.env.SENZOR_MAX_SPANS_PER_TRACE),\n captureHeaders: truthy(process.env.SENZOR_CAPTURE_HEADERS),\n captureDbStatement:\n process.env.SENZOR_CAPTURE_DB_STATEMENT === 'false'\n ? false\n : undefined,\n frameworkSpans:\n process.env.SENZOR_FRAMEWORK_SPANS === 'false'\n ? false\n : undefined,\n captureMiddlewareSpans:\n process.env.SENZOR_CAPTURE_MIDDLEWARE_SPANS === 'false'\n ? false\n : undefined,\n captureRouterSpans:\n process.env.SENZOR_CAPTURE_ROUTER_SPANS === 'false'\n ? false\n : undefined,\n captureLifecycleHookSpans:\n process.env.SENZOR_CAPTURE_LIFECYCLE_HOOK_SPANS === 'false'\n ? false\n : undefined\n};\n\nif (apiKey) {\n client.init(options);\n} else {\n client.preload(options);\n}\n"],"mappings":"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","names":["SENZOR_INTERNAL_HEADER","Transport","config","baseEndpoint","trace","task","error","type","log","queue","item","maxQueueSize","items","totalApm","totalTask","payload","endpoint","controller","timeout","response","SENZOR_INTERNAL_HEADER","apmPayload","taskPayload","sends","failures","result","err","key","proc","flushSyncBestEffort","AsyncLocalStorage","storage","Context","trace","fn","spanId","store","span","maxSpans","randomUUID","http","https","URL","normalizePath","path","getRoute","req","fallbackPath","DEFAULT_MAX_ATTRIBUTES","DEFAULT_MAX_ATTRIBUTE_LENGTH","MAX_DEPTH","MAX_ARRAY_ITEMS","SENSITIVE_KEY_PATTERN","getLimits","options","truncate","value","maxLength","isSensitiveKey","key","sanitizePrimitive","sanitizeValue","depth","primitive","item","output","count","childKey","childValue","sanitizeAttributes","attributes","limits","normalizedOptions","sanitizeHeaders","headers","plainHeaders","normalizeSql","sql","collapsed","withoutLiterals","getSqlOperation","isIP","stripIPv6Mapped","ip","stripIPv4Port","lastColon","maybeIP","stripIPv6Brackets","match","normaliseIP","raw","isPrivateOrLoopback","parseForwardedHeader","header","parts","part","forMatch","parseXForwardedFor","ips","s","getClientIp","req","h","fwd","xff","TRACEPARENT_REGEX","parseTraceparent","header","traceparent","match","traceId","parentSpanId","flags","sampled","generateTraceparent","spanId","PATCHES","ORIGINAL","patchMethod","target","methodName","patchKey","wrapper","current","existingPatches","original","wrapped","patches","randomUUID","generateTraceId","generateSpanId","startCapturedSpan","name","type","meta","options","trace","Context","spanId","generateSpanId","parentSpanId","startTime","startedAt","ended","status","extraMeta","mergedMeta","sanitizeAttributes","runWithCapturedSpan","span","fn","getDebug","options","isPlainObject","value","URL","headerValue","headers","key","name","normalizedKey","hasInternalHeader","SENZOR_INTERNAL_HEADER","shouldIgnoreUrl","urlString","ingestUrl","url","ingest","cloneHeaders","cloned","acc","setHeader","existingKey","header","prepareRequestArgs","args","defaultProtocol","nextArgs","optionsIndex","urlFromArg","protocol","hostname","path","method","resolveIncomingRoute","req","res","getRoute","normalizePath","patchIncomingServer","proto","client","patchMethod","original","event","Context","rawPath","getClientIp","sanitizeHeaders","trace","finalized","finalize","reason","error","patchOutgoing","moduleRef","patchKeyPrefix","requestWrapper","prepared","span","startCapturedSpan","generateTraceparent","invoke","completed","endSpan","status","extraMeta","statusCode","finish","runWithCapturedSpan","instrumentFetch","input","init","originalHeaders","nextInit","response","instrumentHttp","http","https","Module","SENZOR_PATCHED","SENZOR_HOOKS","safeRequire","getHookRegistry","mod","runHooks","moduleName","exports","registry","hooks","currentExports","hook","nextExports","err","patchLoaderOnce","previousLoad","request","parent","isMain","patchCached","resolved","cached","replacement","tryRequire","retryPatch","attempts","max","timer","hookRequire","onRequire","ignoredNextValues","shouldCaptureFrameworkSpan","type","options","statusFrom","info","fallback","res","isPromiseLike","value","runWithParentOf","span","fn","Context","copyFunctionProperties","source","target","key","invokeWithFrameworkSpan","handler","thisArg","args","invokeOptions","startCapturedSpan","ended","cleanup","endSpan","status","meta","clean","onFinish","onClose","callbackIndex","arg","originalCallback","callbackArgs","maybeError","hasError","runWithCapturedSpan","result","error","wrapFrameworkHandlerWithArity","handler","getInfo","options","invokeOptions","invoke","thisArg","args","invokeWithFrameworkSpan","wrapped","a","b","d","copyFunctionProperties","LAYER_PATCHED","routeMethods","stringifyPath","value","getLayerPath","args","arg","path","getRequestRoute","req","layer","layerPath","routePath","normalizePath","getLayerType","original","forcedType","getRouteMethod","method","candidate","copyEnumerableProperties","source","target","key","patchLayer","options","patchMethod","layerType","handlerName","wrapped","err","res","next","route","invokeWithFrameworkSpan","displayRoute","name","patchRouteMethodHandlers","result","stack","patchExpress","expressModule","routerProto","router","activeRouter","instrumentExpress","hookRequire","exports","FACTORY_PATCHED","INSTANCE_PATCHED","lifecycleHookNames","routeLifecycleKeys","getRoute","request","fallback","wrapHook","hookName","handler","options","route","wrapFrameworkHandlerWithArity","_thisArg","args","reply","currentRoute","wrapRouteHandler","wrapMaybeArray","value","wrap","patchFastifyInstance","instance","patchMethod","original","routeOptions","nextRouteOptions","key","copyFactoryProperties","source","target","wrapFastifyFactory","factory","wrapped","mutableWrapped","instrumentFastify","hookRequire","exports","routerMethods","stringifyPath","value","getPathFromArgs","args","arg","path","wrapKoaMiddleware","middleware","options","layerPath","layerType","method","wrapFrameworkHandlerWithArity","_thisArg","ctx","route","normalizePath","actualMethod","handlerName","patchKoaApplication","koa","proto","patchMethod","original","patchKoaRouter","routerModule","nextArgs","instrumentKoa","hookRequire","exports","collectionName","collection","databaseName","cursorCollectionName","cursor","patchCollectionMethod","proto","method","options","patchMethod","original","args","span","startCapturedSpan","runWithCapturedSpan","result","value","error","patchCursorMethod","operation","patchMongo","mongodb","collectionProto","FindCursor","AggregationCursor","instrumentMongo","hookRequire","exports","extractSql","args","first","wrapQueryMethod","proto","label","options","patchMethod","original","sql","operation","getSqlOperation","span","startCapturedSpan","normalizeSql","callbackIndex","arg","originalCallback","err","result","runWithCapturedSpan","value","error","patchPg","pg","instrumentPg","hookRequire","exports","hasInternalHeader","headers","key","value","SENZOR_INTERNAL_HEADER","setHeader","nextHeaders","existingKey","header","getUrlDetails","input","url","patchRequestLike","target","methodName","patchKey","options","patchMethod","original","opts","cb","details","method","span","startCapturedSpan","normalizePath","nextOptions","generateTraceparent","wrappedCallback","err","data","runWithCapturedSpan","result","error","patchUndici","undici","proto","index","instrumentUndici","hookRequire","exports","getCommandName","command","patchSendCommand","target","label","options","patchMethod","original","args","commandName","span","startCapturedSpan","runWithCapturedSpan","result","value","error","patchCreatedClient","client","patchRedisPackage","redis","factory","patchIORedisPackage","ioredis","instrumentRedis","hookRequire","exports","extractSql","args","first","patchSqlMethod","proto","method","library","options","patchMethod","original","sql","operation","getSqlOperation","span","startCapturedSpan","normalizeSql","callbackIndex","arg","originalCallback","err","rows","runWithCapturedSpan","result","value","error","patchKnownPrototypes","mysql","patchFactories","factory","client","patchMysql","instrumentMysql","hookRequire","exports","modelName","target","collectionName","patchExec","proto","label","options","patchMethod","original","args","operation","collection","span","startCapturedSpan","runWithCapturedSpan","result","value","error","patchSave","modelProto","patchMongoose","mongoose","instrumentMongoose","hookRequire","exports","PATCHED","patchWorker","target","client","debug","proto","original","job","queueDelay","currentAttempt","maxAttempts","isFinal","taskName","result","error","ctx","Context","instrumentBullMQ","hookRequire","exports","PATCHED","normalizeOptions","options","patchTarget","target","client","debug","schedule","original","wrapped","expression","handler","opts","taskName","wrappedHandler","err","instrumentNodeCron","hookRequire","exports","package_default","SDK_META","package_default","safeStringify","obj","cache","key","value","SenzorClient","options","endpoint","debug","Transport","name","setting","instrumentHttp","instrumentExpress","instrumentFastify","instrumentKoa","instrumentFetch","instrumentUndici","instrumentMongo","instrumentMongoose","instrumentPg","instrumentMysql","instrumentRedis","instrumentBullMQ","instrumentNodeCron","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","payload","currentContext","triggerTraceId","startMemory","startCpu","task","randomUUID","extraMetadata","resourceMetrics","endMemory","cpuDelta","fn","result","context","errPayload","span","startCapturedSpan","client","truthy","value","numberFromEnv","parsed","apiKey","endpoint","options","client"]}