azify-logger 1.0.44 → 1.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,816 @@
1
+ 'use strict'
2
+ if (process.env.AZIFY_LOGGER_DISABLE === '1') return
3
+ try {
4
+ const HTTP_DEBUG = process.env.AZIFY_LOGGER_HTTP_DEBUG === '1' || process.env.AZIFY_LOGGER_DEBUG === '1'
5
+ function httpLog(msg) {
6
+ if (HTTP_DEBUG) try { process.stderr.write('[AZIFY-HTTP] ' + msg + '\n') } catch (_) {}
7
+ }
8
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
9
+ try { process.stderr.write('[azify-logger] register-http-client-early: module loading\n') } catch (_) {}
10
+ }
11
+ const Module = require('module')
12
+ const path = require('path')
13
+ const EARLY_DIR = __dirname
14
+
15
+ function getOtelTraceContext() {
16
+ try {
17
+ const otelApi = require('@opentelemetry/api')
18
+ const span = otelApi.trace.getSpan(otelApi.context.active())
19
+ if (!span) return null
20
+ const ctx = span.spanContext()
21
+ return ctx && ctx.traceId ? { traceId: ctx.traceId, spanId: ctx.spanId, parentSpanId: ctx.parentSpanId || null } : null
22
+ } catch (_) {
23
+ return null
24
+ }
25
+ }
26
+
27
+ const HTTP_VERBOSE = process.env.AZIFY_LOGGER_HTTP_VERBOSE === '1'
28
+ const MAX_EARLY_LOG_QUEUE = 2000
29
+ const earlyLogQueue = []
30
+
31
+ function isLoggerUrl(urlStr) {
32
+ const loggerUrl = process.env.AZIFY_LOGGER_URL
33
+ if (!loggerUrl || typeof urlStr !== 'string' || !urlStr.trim()) return false
34
+ const a = String(urlStr).trim().toLowerCase().replace(/\/+$/, '')
35
+ const b = String(loggerUrl).trim().toLowerCase().replace(/\/+$/, '')
36
+ if (!b) return false
37
+ return a === b || a.startsWith(b + '/')
38
+ }
39
+
40
+ function send(level, message, meta) {
41
+ try {
42
+ const msgStr = String(message)
43
+ const isReqRes = msgStr.indexOf('[REQUEST]') !== -1 || msgStr.indexOf('[RESPONSE]') !== -1
44
+ if (HTTP_VERBOSE && isReqRes) {
45
+ try { process.stderr.write('[AZIFY] HTTP send ' + msgStr.slice(0, 70) + ' global=' + (typeof global.__AZIFY_SEND_OUTBOUND_LOG === 'function') + '\n') } catch (_) {}
46
+ }
47
+ const fn = typeof global.__AZIFY_SEND_OUTBOUND_LOG === 'function' ? global.__AZIFY_SEND_OUTBOUND_LOG : null
48
+ if (isReqRes && (HTTP_VERBOSE || process.env.AZIFY_LOGGER_DEBUG === '1')) {
49
+ try { process.stderr.write('[AZIFY-DBG] early.send ' + msgStr.slice(0, 50) + ' hasFn=' + !!fn + ' queueLen=' + earlyLogQueue.length + '\n') } catch (_) {}
50
+ }
51
+ if (fn) {
52
+ if (meta && meta.__source === 'http-client') {
53
+ httpLog('SEND -> ' + msgStr.slice(0, 90))
54
+ }
55
+ fn(level, message, meta)
56
+ } else {
57
+ if (meta && meta.__source === 'http-client') httpLog('SEND_QUEUED (no global yet) ' + msgStr.slice(0, 60))
58
+ if (earlyLogQueue.length >= MAX_EARLY_LOG_QUEUE) earlyLogQueue.shift()
59
+ earlyLogQueue.push({ level, message, meta })
60
+ }
61
+ } catch (_) {}
62
+ }
63
+ function flushEarlyLogQueue() {
64
+ const fn = typeof global.__AZIFY_SEND_OUTBOUND_LOG === 'function' ? global.__AZIFY_SEND_OUTBOUND_LOG : null
65
+ if (!fn || !earlyLogQueue.length) return
66
+ const n = earlyLogQueue.length
67
+ httpLog('FLUSH_QUEUE n=' + n)
68
+ while (earlyLogQueue.length) {
69
+ const entry = earlyLogQueue.shift()
70
+ try { fn(entry.level, entry.message, entry.meta) } catch (_) {}
71
+ }
72
+ }
73
+
74
+ let storeSamplingLoaded = null
75
+ function loadStoreAndSampling() {
76
+ if (storeSamplingLoaded !== null) return storeSamplingLoaded
77
+ try {
78
+ const store = require(path.join(EARLY_DIR, 'store'))
79
+ const sampling = require(path.join(EARLY_DIR, 'sampling'))
80
+ storeSamplingLoaded = {
81
+ getRequestContext: store.getRequestContext,
82
+ getLastJobContext: store.getLastJobContext,
83
+ toTraceIdHex: store.toTraceIdHex,
84
+ markSource: sampling.markSource,
85
+ HTTP_CLIENT_MODE: sampling.HTTP_CLIENT_MODE
86
+ }
87
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
88
+ try { process.stderr.write('[azify-logger] register-http-client-early: HTTP_CLIENT_MODE=' + storeSamplingLoaded.HTTP_CLIENT_MODE + '\n') } catch (_) {}
89
+ }
90
+ return storeSamplingLoaded
91
+ } catch (e) {
92
+ storeSamplingLoaded = false
93
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
94
+ try { process.stderr.write('[azify-logger] register-http-client-early: loadStoreAndSampling failed: ' + (e && e.message) + '\n') } catch (_) {}
95
+ }
96
+ return false
97
+ }
98
+ }
99
+
100
+ function patchUndiciExports(exports) {
101
+ const hasRequest = exports && typeof exports.request === 'function' && !exports.request.__azifyPatched
102
+ const hasFetch = exports && typeof exports.fetch === 'function' && !exports.fetch.__azifyPatched
103
+ if (!exports || (!hasRequest && !hasFetch)) return
104
+ const deps = loadStoreAndSampling()
105
+ const noDeps = !deps
106
+ if (noDeps && process.env.AZIFY_LOGGER_DEBUG === '1') {
107
+ try { process.stderr.write('[azify-logger] register-http-client-early: patching undici without deps (minimal wrapper)\n') } catch (_) {}
108
+ }
109
+ const getRequestContext = deps ? deps.getRequestContext : () => null
110
+ const getLastJobContext = deps ? deps.getLastJobContext : () => null
111
+ const toTraceIdHex = deps ? deps.toTraceIdHex : (x) => (typeof x === 'string' ? x : (x && String(x)) || '')
112
+ const markSource = deps ? deps.markSource : () => {}
113
+ const HTTP_CLIENT_MODE = deps ? deps.HTTP_CLIENT_MODE : 'all'
114
+ httpLog('PATCH_EXPORTS request=' + !!hasRequest + ' fetch=' + !!hasFetch + (noDeps ? ' noDeps=1' : ''))
115
+ if (HTTP_DEBUG) try { process.stderr.write('[AZIFY] undici PATCHED (request=' + !!hasRequest + ' fetch=' + !!hasFetch + ')\n') } catch (_) {}
116
+ if (hasRequest) {
117
+ const origRequest = exports.request
118
+ exports.request = function (url, options, callback) {
119
+ const opts = (typeof url === 'object' && url !== null && !(url instanceof URL)) ? url : options
120
+ const method = ((opts && opts.method) || 'GET').toUpperCase()
121
+ let urlStr = 'unknown'
122
+ const urlArg = (typeof url === 'string' || (url && (url.href || url instanceof URL))) ? url : (opts && (opts.url || opts.uri))
123
+ if (typeof urlArg === 'string') urlStr = urlArg
124
+ else if (urlArg && typeof urlArg.href === 'string') urlStr = urlArg.href
125
+ else if (urlArg && typeof urlArg.toString === 'function') urlStr = urlArg.toString()
126
+ else if (opts && typeof opts.origin === 'string' && opts.path != null) urlStr = opts.origin + (String(opts.path).startsWith('/') ? '' : '/') + String(opts.path)
127
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') { try { process.stderr.write('[AZIFY-PATCH] undici.request ' + method + ' ' + urlStr.slice(0, 80) + '\n') } catch (_) {} }
128
+ const _ep = process.env.AZIFY_DEBUG_LOG_PATH
129
+ if (_ep) { try { require('fs').appendFileSync(_ep, new Date().toISOString() + ' [AZIFY] WRAPPER exports.request ' + method + ' ' + urlStr.slice(0, 100) + '\n') } catch (_) {} }
130
+ if (HTTP_VERBOSE || HTTP_DEBUG) {
131
+ try { process.stderr.write('[AZIFY] HTTP wrapper undici.request ' + method + ' ' + urlStr.slice(0, 80) + '\n') } catch (_) {}
132
+ }
133
+ httpLog('WRAPPER undici.request ' + method + ' ' + urlStr.slice(0, 80))
134
+ const ctx = getRequestContext() || getLastJobContext()
135
+ const otelCtx = getOtelTraceContext()
136
+ const traceCtx = ctx || otelCtx
137
+ const rawTraceId = traceCtx && traceCtx.traceId || (require('crypto').randomUUID && require('crypto').randomUUID())
138
+ const traceId = typeof rawTraceId === 'string' ? toTraceIdHex(rawTraceId) : rawTraceId
139
+ const requestMeta = { traceId, spanId: (traceCtx && traceCtx.spanId) || null, parentSpanId: (traceCtx && traceCtx.parentSpanId) || null, requestId: (traceCtx && traceCtx.requestId) || null, method, url: urlStr }
140
+ markSource(requestMeta, 'http-client')
141
+ const start = require('perf_hooks').performance.now()
142
+ const skipLog = isLoggerUrl(urlStr)
143
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('info', `[REQUEST] ${method} ${urlStr}`, requestMeta)
144
+ const wrappedCb = callback ? function (err, data) {
145
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
146
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) {
147
+ if (err) send('error', `[RESPONSE] ${method} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
148
+ else if (data) send('info', `[RESPONSE] ${method} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
149
+ }
150
+ return callback(err, data)
151
+ } : undefined
152
+ if (wrappedCb) return origRequest.call(this, url, options, wrappedCb)
153
+ const p = origRequest.call(this, url, options)
154
+ if (p && typeof p.then === 'function') {
155
+ return p.then(
156
+ (data) => {
157
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
158
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog && data) send('info', `[RESPONSE] ${method} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
159
+ return data
160
+ },
161
+ (err) => {
162
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
163
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('error', `[RESPONSE] ${method} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
164
+ throw err
165
+ }
166
+ )
167
+ }
168
+ return p
169
+ }
170
+ exports.request.__azifyPatched = true
171
+ }
172
+ if (exports.Dispatcher && exports.Dispatcher.prototype && typeof exports.Dispatcher.prototype.request === 'function' && !exports.Dispatcher.prototype.request.__azifyPatched) {
173
+ const proto = exports.Dispatcher.prototype
174
+ const origDisp = proto.request
175
+ proto.request = function (opts, callback) {
176
+ const methodStr = String((opts && opts.method) || 'GET').toUpperCase()
177
+ const origin = (opts && opts.origin) || ''
178
+ const path = (opts && opts.path) != null ? opts.path : '/'
179
+ const urlStr = origin ? (origin + (path.startsWith('/') ? path : '/' + path)) : 'unknown'
180
+ httpLog('WRAPPER Dispatcher.request ' + methodStr + ' ' + urlStr.slice(0, 80))
181
+ const ctx = getRequestContext() || getLastJobContext()
182
+ const otelCtx = getOtelTraceContext()
183
+ const traceCtx = ctx || otelCtx
184
+ const rawTraceId = (traceCtx && traceCtx.traceId) || (require('crypto').randomUUID && require('crypto').randomUUID())
185
+ const traceId = typeof rawTraceId === 'string' ? toTraceIdHex(rawTraceId) : rawTraceId
186
+ const requestMeta = { traceId, spanId: (traceCtx && traceCtx.spanId) || null, parentSpanId: (traceCtx && traceCtx.parentSpanId) || null, requestId: (traceCtx && traceCtx.requestId) || null, method: methodStr, url: urlStr }
187
+ markSource(requestMeta, 'http-client')
188
+ const start = require('perf_hooks').performance.now()
189
+ const skipLog = isLoggerUrl(urlStr)
190
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('info', `[REQUEST] ${methodStr} ${urlStr}`, requestMeta)
191
+ const wrappedCb = typeof callback === 'function' ? function (err, data) {
192
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
193
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) {
194
+ if (err) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
195
+ else if (data) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
196
+ }
197
+ return callback(err, data)
198
+ } : undefined
199
+ const ret = wrappedCb ? origDisp.call(this, opts, wrappedCb) : origDisp.call(this, opts)
200
+ if (ret && typeof ret.then === 'function' && !wrappedCb) {
201
+ return ret.then(
202
+ (data) => {
203
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
204
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog && data) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
205
+ return data
206
+ },
207
+ (err) => {
208
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
209
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
210
+ throw err
211
+ }
212
+ )
213
+ }
214
+ return ret
215
+ }
216
+ proto.request.__azifyPatched = true
217
+ }
218
+ if (typeof exports.fetch === 'function' && !exports.fetch.__azifyPatched && deps) {
219
+ const origFetch = exports.fetch
220
+ exports.fetch = function (input, init) {
221
+ const methodStr = String((init && init.method) || 'GET').toUpperCase()
222
+ const urlStr = typeof input === 'string' ? input : (input && (input.url || input.href)) ? String(input.url || input.href) : String(input)
223
+ httpLog('WRAPPER undici.fetch ' + methodStr + ' ' + urlStr.slice(0, 80))
224
+ const ctx = getRequestContext() || getLastJobContext()
225
+ const otelCtx = getOtelTraceContext()
226
+ const traceCtx = ctx || otelCtx
227
+ const rawTraceId = traceCtx && traceCtx.traceId || (require('crypto').randomUUID && require('crypto').randomUUID())
228
+ const traceId = typeof rawTraceId === 'string' ? toTraceIdHex(rawTraceId) : rawTraceId
229
+ const requestMeta = { traceId, spanId: (traceCtx && traceCtx.spanId) || null, parentSpanId: (traceCtx && traceCtx.parentSpanId) || null, requestId: (traceCtx && traceCtx.requestId) || null, method: methodStr, url: urlStr }
230
+ markSource(requestMeta, 'http-client')
231
+ const start = require('perf_hooks').performance.now()
232
+ const skipLog = isLoggerUrl(urlStr)
233
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('info', `[REQUEST] ${methodStr} ${urlStr}`, requestMeta)
234
+ return origFetch.apply(this, arguments).then(
235
+ function (response) {
236
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
237
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog && response) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${response.status} ${duration}ms`, { ...requestMeta, statusCode: response.status, responseTimeMs: duration })
238
+ return response
239
+ },
240
+ function (err) {
241
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
242
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
243
+ throw err
244
+ }
245
+ )
246
+ }
247
+ exports.fetch.__azifyPatched = true
248
+ }
249
+ if (exports.getGlobalDispatcher && typeof exports.getGlobalDispatcher === 'function' && !exports.getGlobalDispatcher.__azifyPatched) {
250
+ const origGetGlobal = exports.getGlobalDispatcher
251
+ exports.getGlobalDispatcher = function getGlobalDispatcherPatched() {
252
+ const d = origGetGlobal.call(this)
253
+ if (!d || (d.request && d.request.__azifyPatched)) return d
254
+ const origReq = d.request
255
+ if (typeof origReq !== 'function') return d
256
+ d.request = function (opts, callback) {
257
+ const methodStr = String((opts && opts.method) || 'GET').toUpperCase()
258
+ const origin = (opts && opts.origin) || ''
259
+ const pathPart = (opts && opts.path) != null ? opts.path : '/'
260
+ const urlStr = origin ? (origin + (pathPart.startsWith('/') ? pathPart : '/' + pathPart)) : 'unknown'
261
+ httpLog('WRAPPER getGlobalDispatcher().request ' + methodStr + ' ' + urlStr.slice(0, 80))
262
+ const ctx = getRequestContext ? getRequestContext() : (getLastJobContext ? getLastJobContext() : null)
263
+ const otelCtx = getOtelTraceContext()
264
+ const traceCtx = ctx || otelCtx
265
+ const rawTraceId = (traceCtx && traceCtx.traceId) || (require('crypto').randomUUID && require('crypto').randomUUID())
266
+ const traceId = typeof rawTraceId === 'string' ? (toTraceIdHex ? toTraceIdHex(rawTraceId) : rawTraceId) : rawTraceId
267
+ const requestMeta = { traceId, spanId: (traceCtx && traceCtx.spanId) || null, parentSpanId: (traceCtx && traceCtx.parentSpanId) || null, requestId: (traceCtx && traceCtx.requestId) || null, method: methodStr, url: urlStr }
268
+ if (markSource) markSource(requestMeta, 'http-client')
269
+ const start = require('perf_hooks').performance.now()
270
+ const skipLog = isLoggerUrl(urlStr)
271
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('info', `[REQUEST] ${methodStr} ${urlStr}`, requestMeta)
272
+ const wrappedCb = typeof callback === 'function' ? function (err, data) {
273
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
274
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) {
275
+ if (err) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
276
+ else if (data) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
277
+ }
278
+ return callback(err, data)
279
+ } : undefined
280
+ const ret = wrappedCb ? origReq.call(this, opts, wrappedCb) : origReq.call(this, opts)
281
+ if (ret && typeof ret.then === 'function' && !wrappedCb) {
282
+ return ret.then(
283
+ (data) => {
284
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
285
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog && data) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
286
+ return data
287
+ },
288
+ (err) => {
289
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
290
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
291
+ throw err
292
+ }
293
+ )
294
+ }
295
+ return ret
296
+ }
297
+ d.request.__azifyPatched = true
298
+ return d
299
+ }
300
+ exports.getGlobalDispatcher.__azifyPatched = true
301
+ httpLog('PATCH_EXPORTS getGlobalDispatcher wrapped')
302
+ }
303
+ patchGlobalDispatcherInPlace()
304
+ }
305
+ let _globalDispatcherCheckTicks = 0
306
+ function patchGlobalDispatcherInPlace() {
307
+ try {
308
+ const sym = Symbol.for('undici.globalDispatcher.1')
309
+ const d = typeof globalThis !== 'undefined' && globalThis[sym]
310
+ _globalDispatcherCheckTicks++
311
+ if (HTTP_DEBUG && (_globalDispatcherCheckTicks <= 3 || _globalDispatcherCheckTicks % 20 === 0)) {
312
+ try {
313
+ const reqFromProto = d && Object.getPrototypeOf(d) && Object.getPrototypeOf(d).request
314
+ process.stderr.write('[AZIFY] GLOBAL_DISPATCHER_CHECK tick=' + _globalDispatcherCheckTicks + ' hasD=' + !!d + ' hasRequest=' + !!(d && typeof d.request === 'function') + ' protoRequest=' + (typeof reqFromProto === 'function') + ' alreadyPatched=' + !!(d && d.request && d.request.__azifyGlobalPatched) + '\n')
315
+ } catch (_) {}
316
+ }
317
+ if (!d) return
318
+ let origReq = null
319
+ if (typeof d.request === 'function') origReq = d.request
320
+ else {
321
+ let proto = Object.getPrototypeOf(d)
322
+ while (proto) {
323
+ if (typeof proto.request === 'function') { origReq = proto.request; break }
324
+ proto = Object.getPrototypeOf(proto)
325
+ }
326
+ }
327
+ if (!origReq || origReq.__azifyGlobalPatched) return
328
+ const deps = loadStoreAndSampling()
329
+ const getRequestContext = deps ? deps.getRequestContext : () => null
330
+ const getLastJobContext = deps ? deps.getLastJobContext : () => null
331
+ const toTraceIdHex = deps ? deps.toTraceIdHex : (x) => (typeof x === 'string' ? x : (x && String(x)) || '')
332
+ const markSource = deps ? deps.markSource : () => {}
333
+ const HTTP_CLIENT_MODE = deps ? deps.HTTP_CLIENT_MODE : 'all'
334
+ d.request = function (opts, callback) {
335
+ const methodStr = String((opts && opts.method) || 'GET').toUpperCase()
336
+ const origin = (opts && opts.origin) || ''
337
+ const pathPart = (opts && opts.path) != null ? opts.path : '/'
338
+ const urlStr = origin ? (origin + (pathPart.startsWith('/') ? pathPart : '/' + pathPart)) : 'unknown'
339
+ httpLog('WRAPPER globalThis.dispatcher.request ' + methodStr + ' ' + urlStr.slice(0, 80))
340
+ const _dp = process.env.AZIFY_DEBUG_LOG_PATH
341
+ if (_dp) { try { require('fs').appendFileSync(_dp, new Date().toISOString() + ' [AZIFY] WRAPPER globalDispatcher.request ' + methodStr + ' ' + urlStr.slice(0, 100) + '\n') } catch (_) {} }
342
+ const ctx = getRequestContext ? getRequestContext() : (getLastJobContext ? getLastJobContext() : null)
343
+ const otelCtx = getOtelTraceContext()
344
+ const traceCtx = ctx || otelCtx
345
+ const rawTraceId = (traceCtx && traceCtx.traceId) || (require('crypto').randomUUID && require('crypto').randomUUID())
346
+ const traceId = typeof rawTraceId === 'string' ? (toTraceIdHex ? toTraceIdHex(rawTraceId) : rawTraceId) : rawTraceId
347
+ const requestMeta = { traceId, spanId: (traceCtx && traceCtx.spanId) || null, parentSpanId: (traceCtx && traceCtx.parentSpanId) || null, requestId: (traceCtx && traceCtx.requestId) || null, method: methodStr, url: urlStr }
348
+ if (markSource) markSource(requestMeta, 'http-client')
349
+ const start = require('perf_hooks').performance.now()
350
+ const skipLog = isLoggerUrl(urlStr)
351
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('info', `[REQUEST] ${methodStr} ${urlStr}`, requestMeta)
352
+ const wrappedCb = typeof callback === 'function' ? function (err, data) {
353
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
354
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) {
355
+ if (err) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
356
+ else if (data) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
357
+ }
358
+ return callback(err, data)
359
+ } : undefined
360
+ const ret = wrappedCb ? origReq.call(this, opts, wrappedCb) : origReq.call(this, opts)
361
+ if (ret && typeof ret.then === 'function' && !wrappedCb) {
362
+ return ret.then(
363
+ (data) => {
364
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
365
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog && data) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
366
+ return data
367
+ },
368
+ (err) => {
369
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
370
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
371
+ throw err
372
+ }
373
+ )
374
+ }
375
+ return ret
376
+ }
377
+ d.request.__azifyGlobalPatched = true
378
+ httpLog('PATCH_EXPORTS globalThis.dispatcher.request wrapped')
379
+ try { process.stderr.write('[AZIFY] global dispatcher.request patchado — requests serão logados\n') } catch (_) {}
380
+ const debugLogPath = process.env.AZIFY_DEBUG_LOG_PATH
381
+ if (debugLogPath) {
382
+ try { require('fs').appendFileSync(debugLogPath, new Date().toISOString() + ' [AZIFY] global dispatcher patchado\n') } catch (_) {}
383
+ }
384
+ } catch (e) {
385
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
386
+ try { process.stderr.write('[azify-logger] register-http-client-early: patch globalThis dispatcher: ' + (e && e.message) + '\n') } catch (_) {}
387
+ }
388
+ }
389
+ }
390
+
391
+ function isMainUndiciCacheKey(key) {
392
+ if (!key || typeof key !== 'string') return false
393
+ const k = key.replace(/\\/g, '/')
394
+ return k.indexOf('undici') !== -1 && k.indexOf('undici-package') === -1 && k.indexOf('undici/lib') === -1 && (k.endsWith('undici/index.js') || k.endsWith('undici.js'))
395
+ }
396
+
397
+ let patchedUndiciSingleton = null
398
+ function tryPatchAndProxyUndici(result, logLabel) {
399
+ if (!result || typeof result !== 'object') return null
400
+ if (result.request && result.request.__azifyPatched) {
401
+ patchedUndiciSingleton = result
402
+ return result
403
+ }
404
+ if (!result.request && !result.fetch) return null
405
+ const needsPatch = (typeof result.request === 'function' && !result.request.__azifyPatched) || (typeof result.fetch === 'function' && !result.fetch.__azifyPatched)
406
+ if (!needsPatch) return result
407
+ try {
408
+ patchUndiciExports(result)
409
+ } catch (e) {
410
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
411
+ try { process.stderr.write('[azify-logger] register-http-client-early: ' + logLabel + ' patch threw: ' + (e && e.message) + '\n') } catch (_) {}
412
+ }
413
+ return result
414
+ }
415
+ patchedUndiciSingleton = result
416
+ if (HTTP_DEBUG) try { process.stderr.write('[AZIFY-DBG] undici PATCHED (first load) label=' + (logLabel || 'REQUIRE') + '\n') } catch (_) {}
417
+ try {
418
+ const cache = require.cache
419
+ if (cache && typeof cache === 'object') {
420
+ for (const key of Object.keys(cache)) {
421
+ if (isMainUndiciCacheKey(key) && cache[key].exports !== result) {
422
+ cache[key].exports = result
423
+ httpLog('REQUIRE first-load sync cache -> singleton key=' + String(key).slice(-55))
424
+ }
425
+ }
426
+ }
427
+ } catch (_) {}
428
+ httpLog((logLabel || 'REQUIRE') + ' patched in place (no proxy)')
429
+ return result
430
+ }
431
+
432
+ const origRequire = Module.prototype.require
433
+ if (typeof origRequire === 'function' && !Module.prototype.require.__azifyEarlyPatched) {
434
+ Module.prototype.require = function (id) {
435
+ const idStr = typeof id === 'string' ? id : ''
436
+ const isUndiciId = idStr === 'undici' || (idStr.indexOf('undici') !== -1 && idStr.indexOf('undici-package') === -1)
437
+ let result
438
+ if (HTTP_DEBUG && isUndiciId && idStr) {
439
+ const caller = (this && typeof this.filename === 'string') ? this.filename : (this && this.id) || 'unknown'
440
+ try { process.stderr.write('[AZIFY] require("undici") caller=' + String(caller).replace(/\\/g, '/').slice(-100) + ' singleton=' + !!patchedUndiciSingleton + '\n') } catch (_) {}
441
+ }
442
+ if (HTTP_DEBUG && idStr && (idStr === 'undici' || idStr.includes('undici'))) {
443
+ const caller = (this && typeof this.filename === 'string') ? this.filename : (this && this.id) || 'unknown'
444
+ try { process.stderr.write('[AZIFY-DBG] require("' + idStr.slice(-70) + '") caller=' + String(caller).slice(-90) + ' singleton=' + !!patchedUndiciSingleton + '\n') } catch (_) {}
445
+ }
446
+ if (isUndiciId && patchedUndiciSingleton) {
447
+ try {
448
+ const cache = require.cache
449
+ if (cache && typeof cache === 'object') {
450
+ for (const key of Object.keys(cache)) {
451
+ if (isMainUndiciCacheKey(key) && cache[key].exports !== patchedUndiciSingleton) {
452
+ cache[key].exports = patchedUndiciSingleton
453
+ httpLog('REQUIRE undici cache[all main] -> singleton key=' + String(key).slice(-60))
454
+ }
455
+ }
456
+ try {
457
+ const resolvedPath = Module._resolveFilename(idStr, this, false)
458
+ if (resolvedPath && cache[resolvedPath]) cache[resolvedPath].exports = patchedUndiciSingleton
459
+ } catch (_) {}
460
+ }
461
+ if (typeof patchedUndiciSingleton.request === 'function' && !patchedUndiciSingleton.request.__azifyPatched) {
462
+ patchUndiciExports(patchedUndiciSingleton)
463
+ }
464
+ patchGlobalDispatcherInPlace()
465
+ return patchedUndiciSingleton
466
+ } catch (_) {}
467
+ }
468
+
469
+ result = origRequire.apply(this, arguments)
470
+ if (result && typeof result === 'object' && patchedUndiciSingleton && result !== patchedUndiciSingleton) {
471
+ const hasRequest = typeof result.request === 'function'
472
+ const hasDispatcher = result.Dispatcher && result.Dispatcher.prototype
473
+ if (hasRequest && hasDispatcher && (result.fetch || result.Pool)) {
474
+ try {
475
+ const cache = require.cache
476
+ if (cache && typeof cache === 'object') {
477
+ for (const key of Object.keys(cache)) {
478
+ if (cache[key].exports === result) {
479
+ cache[key].exports = patchedUndiciSingleton
480
+ httpLog('REQUIRE by-result -> singleton key=' + String(key).slice(-55))
481
+ break
482
+ }
483
+ }
484
+ }
485
+ } catch (_) {}
486
+ return patchedUndiciSingleton
487
+ }
488
+ }
489
+ if (!isUndiciId) {
490
+ return result
491
+ }
492
+ httpLog('REQUIRE undici id=' + idStr.slice(-60) + ' singleton=' + !!patchedUndiciSingleton)
493
+ if (patchedUndiciSingleton && result !== patchedUndiciSingleton) {
494
+ try {
495
+ const cache = require.cache
496
+ if (cache && typeof cache === 'object') {
497
+ let resolvedPath
498
+ try { resolvedPath = Module._resolveFilename(idStr, this, false) } catch (_) {}
499
+ if (resolvedPath && cache[resolvedPath]) cache[resolvedPath].exports = patchedUndiciSingleton
500
+ for (const key of Object.keys(cache)) {
501
+ if (cache[key].exports === result) {
502
+ cache[key].exports = patchedUndiciSingleton
503
+ httpLog('REQUIRE undici cache -> singleton key=' + String(key).slice(-60))
504
+ break
505
+ }
506
+ }
507
+ }
508
+ if (typeof patchedUndiciSingleton.request === 'function' && !patchedUndiciSingleton.request.__azifyPatched) {
509
+ patchUndiciExports(patchedUndiciSingleton)
510
+ }
511
+ patchGlobalDispatcherInPlace()
512
+ } catch (_) {}
513
+ return patchedUndiciSingleton
514
+ }
515
+ if (result && (result.request || result.fetch) && !result.request?.__azifyPatched) {
516
+ const prox = tryPatchAndProxyUndici(result, 'REQUIRE')
517
+ if (prox) return prox
518
+ }
519
+ let cacheKeyUndici = null
520
+ if (result && typeof result === 'object') {
521
+ try {
522
+ const cache = require.cache
523
+ if (cache && typeof cache === 'object') {
524
+ for (const key of Object.keys(cache)) {
525
+ const mod = cache[key]
526
+ if (mod && mod.exports === result && typeof key === 'string') {
527
+ const k = key.replace(/\\/g, '/')
528
+ if (k.indexOf('undici') !== -1 && k.indexOf('undici-package') === -1) {
529
+ cacheKeyUndici = key
530
+ break
531
+ }
532
+ }
533
+ }
534
+ }
535
+ } catch (_) {}
536
+ }
537
+ if (cacheKeyUndici && isUndiciShaped(result)) {
538
+ const kNorm = cacheKeyUndici.replace(/\\/g, '/')
539
+ const isMainUndiciEntry = (kNorm.endsWith('undici/index.js') || kNorm.endsWith('undici.js')) && kNorm.indexOf('undici/lib') === -1
540
+ if (isMainUndiciEntry && patchedUndiciSingleton) {
541
+ try {
542
+ const cache = require.cache
543
+ const mod = cache[cacheKeyUndici]
544
+ if (mod && mod.exports === result) {
545
+ mod.exports = patchedUndiciSingleton
546
+ httpLog('REQUIRE undici by path -> singleton id=' + idStr.slice(-50))
547
+ }
548
+ } catch (_) {}
549
+ return patchedUndiciSingleton
550
+ }
551
+ if (isMainUndiciEntry) {
552
+ const prox = tryPatchAndProxyUndici(result, 'REQUIRE(path)')
553
+ if (prox) {
554
+ httpLog('REQUIRE undici by path id=' + idStr.slice(-50))
555
+ return prox
556
+ }
557
+ }
558
+ }
559
+ return result
560
+ }
561
+ Module.prototype.require.__azifyEarlyPatched = true
562
+ }
563
+
564
+ const origLoad = Module._load
565
+ if (typeof origLoad === 'function' && !Module._load.__azifyEarlyPatched) {
566
+ Module._load = function (request, parent, isMain) {
567
+ const pathStr = typeof request === 'string' ? request.replace(/\\/g, '/') : ''
568
+ const isUndici = pathStr === 'undici' || (pathStr.indexOf('undici') !== -1 && pathStr.indexOf('undici-package') === -1)
569
+ if (HTTP_DEBUG && isUndici) {
570
+ try { process.stderr.write('[AZIFY] _LOAD undici path=' + pathStr.replace(/\\/g, '/').slice(-90) + ' parent=' + (parent && parent.filename ? String(parent.filename).replace(/\\/g, '/').slice(-80) : '') + '\n') } catch (_) {}
571
+ }
572
+ const isMainUndici = isUndici && pathStr.indexOf('undici/lib') === -1 && (pathStr === 'undici' || pathStr.endsWith('undici/index.js') || pathStr.endsWith('/undici.js'))
573
+ if (isUndici && patchedUndiciSingleton) {
574
+ const result = origLoad.apply(this, arguments)
575
+ try {
576
+ const cache = require.cache
577
+ if (cache && typeof cache === 'object' && result && typeof result === 'object') {
578
+ for (const key of Object.keys(cache)) {
579
+ const mod = cache[key]
580
+ if (mod && mod.exports === result) {
581
+ mod.exports = patchedUndiciSingleton
582
+ httpLog('_LOAD undici cache -> singleton key=' + String(key).slice(-60))
583
+ break
584
+ }
585
+ }
586
+ }
587
+ } catch (_) {}
588
+ return patchedUndiciSingleton
589
+ }
590
+ const result = origLoad.apply(this, arguments)
591
+ let returnValue = result
592
+ try {
593
+ let resolvedPath = pathStr
594
+ if (parent && parent.filename && typeof request === 'string') {
595
+ try { resolvedPath = Module._resolveFilename(request, parent, false) } catch (_) {}
596
+ }
597
+ const resolvedNorm = String(resolvedPath).replace(/\\/g, '/')
598
+ if (resolvedNorm.indexOf('undici') !== -1 && resolvedNorm.indexOf('api-request') !== -1 && resolvedNorm.indexOf('undici-package') === -1) {
599
+ const mod = require.cache[resolvedPath]
600
+ if (mod && mod.exports && typeof mod.exports === 'function' && !mod.exports.__azifyApiRequestPatched) {
601
+ const deps = loadStoreAndSampling()
602
+ const getRequestContext = deps ? deps.getRequestContext : () => null
603
+ const getLastJobContext = deps ? deps.getLastJobContext : () => null
604
+ const toTraceIdHex = deps ? deps.toTraceIdHex : (x) => (typeof x === 'string' ? x : (x && String(x)) || '')
605
+ const markSource = deps ? deps.markSource : () => {}
606
+ const HTTP_CLIENT_MODE = deps ? deps.HTTP_CLIENT_MODE : 'all'
607
+ const origRequest = mod.exports
608
+ const RequestHandler = mod.exports.RequestHandler
609
+ mod.exports = function wrappedApiRequest(opts, callback) {
610
+ const methodStr = String((opts && opts.method) || 'GET').toUpperCase()
611
+ const urlPart = (opts && opts.origin) ? String(opts.origin).slice(0, 80) : (opts && opts.path) || ''
612
+ if (HTTP_DEBUG) try { process.stderr.write('[AZIFY-PATCH] api-request ' + methodStr + ' ' + urlPart + '\n') } catch (_) {}
613
+ if (HTTP_VERBOSE || HTTP_DEBUG) {
614
+ try { process.stderr.write('[AZIFY] HTTP wrapper api-request ' + methodStr + ' ' + urlPart + '\n') } catch (_) {}
615
+ }
616
+ const origin = (opts && opts.origin) || ''
617
+ const pathPart = (opts && opts.path) != null ? opts.path : '/'
618
+ const urlStr = origin ? (origin + (pathPart.startsWith('/') ? pathPart : '/' + pathPart)) : 'unknown'
619
+ httpLog('WRAPPER api-request ' + methodStr + ' ' + urlStr.slice(0, 80))
620
+ const ctx = getRequestContext() || getLastJobContext()
621
+ const otelCtx = getOtelTraceContext()
622
+ const traceCtx = ctx || otelCtx
623
+ const rawTraceId = (traceCtx && traceCtx.traceId) || (require('crypto').randomUUID && require('crypto').randomUUID())
624
+ const traceId = typeof rawTraceId === 'string' ? (toTraceIdHex ? toTraceIdHex(rawTraceId) : rawTraceId) : rawTraceId
625
+ const requestMeta = { traceId, spanId: (traceCtx && traceCtx.spanId) || null, parentSpanId: (traceCtx && traceCtx.parentSpanId) || null, requestId: (traceCtx && traceCtx.requestId) || null, method: methodStr, url: urlStr }
626
+ if (markSource) markSource(requestMeta, 'http-client')
627
+ const start = require('perf_hooks').performance.now()
628
+ const skipLog = isLoggerUrl(urlStr)
629
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('info', `[REQUEST] ${methodStr} ${urlStr}`, requestMeta)
630
+ const wrappedCb = typeof callback === 'function' ? function (err, data) {
631
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
632
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) {
633
+ if (err) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
634
+ else if (data) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
635
+ }
636
+ return callback(err, data)
637
+ } : undefined
638
+ const ret = wrappedCb ? origRequest.call(this, opts, wrappedCb) : origRequest.call(this, opts)
639
+ if (ret && typeof ret.then === 'function' && !wrappedCb) {
640
+ return ret.then(
641
+ (data) => {
642
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
643
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog && data) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
644
+ return data
645
+ },
646
+ (err) => {
647
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
648
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
649
+ throw err
650
+ }
651
+ )
652
+ }
653
+ return ret
654
+ }
655
+ mod.exports.RequestHandler = RequestHandler
656
+ mod.exports.__azifyApiRequestPatched = true
657
+ returnValue = mod.exports
658
+ if (parent && parent.exports && typeof parent.exports === 'object') {
659
+ parent.exports.request = mod.exports
660
+ httpLog('_LOAD undici api-request.js: parent.exports.request = wrapper')
661
+ }
662
+ httpLog('_LOAD undici api-request.js patched (returning wrapper)')
663
+ }
664
+ }
665
+ } catch (e) {
666
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
667
+ try { process.stderr.write('[azify-logger] register-http-client-early: patch api-request: ' + (e && e.message) + '\n') } catch (_) {}
668
+ }
669
+ }
670
+ if (isUndici) {
671
+ httpLog('_LOAD undici path=' + pathStr.slice(-90))
672
+ try {
673
+ if (result && typeof result === 'object' && (result.request || result.fetch)) {
674
+ patchUndiciExports(result)
675
+ patchedUndiciSingleton = result
676
+ httpLog('_LOAD undici patched in place (no proxy)')
677
+ }
678
+ } catch (e) {
679
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
680
+ try { process.stderr.write('[azify-logger] register-http-client-early: patchUndiciExports threw: ' + (e && e.message) + '\n') } catch (_) {}
681
+ }
682
+ }
683
+ }
684
+ return returnValue
685
+ }
686
+ Module._load.__azifyEarlyPatched = true
687
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
688
+ try { process.stderr.write('[azify-logger] register-http-client-early: Module._load hook installed\n') } catch (_) {}
689
+ }
690
+ }
691
+
692
+ function patchGlobalFetch() {
693
+ try {
694
+ if (typeof globalThis.fetch !== 'function') return
695
+ if (globalThis.fetch.__azifyPatched) return
696
+ const deps = loadStoreAndSampling()
697
+ if (!deps || deps.HTTP_CLIENT_MODE === 'off') return
698
+ const { getRequestContext, getLastJobContext, toTraceIdHex, markSource, HTTP_CLIENT_MODE } = deps
699
+ const origFetch = globalThis.fetch
700
+ globalThis.fetch = function (input, init) {
701
+ const method = (init && init.method) || (input && input.method) || 'GET'
702
+ const methodStr = String(method).toUpperCase()
703
+ const urlStr = typeof input === 'string' ? input : (input && (input.url || input.href)) ? String(input.url || input.href) : String(input)
704
+ httpLog('WRAPPER globalFetch ' + methodStr + ' ' + urlStr.slice(0, 80))
705
+ const ctx = getRequestContext() || getLastJobContext()
706
+ const otelCtx = getOtelTraceContext()
707
+ const traceCtx = ctx || otelCtx
708
+ const rawTraceId = traceCtx && traceCtx.traceId || (require('crypto').randomUUID && require('crypto').randomUUID())
709
+ const traceId = typeof rawTraceId === 'string' ? toTraceIdHex(rawTraceId) : rawTraceId
710
+ const requestMeta = { traceId, spanId: (traceCtx && traceCtx.spanId) || null, parentSpanId: (traceCtx && traceCtx.parentSpanId) || null, requestId: (traceCtx && traceCtx.requestId) || null, method: methodStr, url: urlStr }
711
+ markSource(requestMeta, 'http-client')
712
+ const start = require('perf_hooks').performance.now()
713
+ const skipLog = isLoggerUrl(urlStr)
714
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('info', `[REQUEST] ${methodStr} ${urlStr}`, requestMeta)
715
+ return origFetch.apply(this, arguments).then(
716
+ function (response) {
717
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
718
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog && response) send('info', `[RESPONSE] ${methodStr} ${urlStr} ${response.status} ${duration}ms`, { ...requestMeta, statusCode: response.status, responseTimeMs: duration })
719
+ return response
720
+ },
721
+ function (err) {
722
+ const duration = Number((require('perf_hooks').performance.now() - start).toFixed(2))
723
+ if (HTTP_CLIENT_MODE !== 'off' && !skipLog) send('error', `[RESPONSE] ${methodStr} ${urlStr} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
724
+ throw err
725
+ }
726
+ )
727
+ }
728
+ globalThis.fetch.__azifyPatched = true
729
+ if (process.env.AZIFY_LOGGER_DEBUG === '1') {
730
+ try { process.stderr.write('[azify-logger] register-http-client-early: global fetch patched\n') } catch (_) {}
731
+ }
732
+ } catch (_) {}
733
+ }
734
+
735
+ function isUndiciShaped(exports) {
736
+ if (!exports || typeof exports !== 'object') return false
737
+ const hasRequest = typeof exports.request === 'function'
738
+ const hasFetch = typeof exports.fetch === 'function'
739
+ const hasDispatcher = exports.Dispatcher && typeof exports.Dispatcher.prototype === 'object' && typeof exports.Dispatcher.prototype.request === 'function'
740
+ return hasRequest || hasFetch || hasDispatcher
741
+ }
742
+
743
+ function getPatchedUndiciSingleton() {
744
+ return patchedUndiciSingleton
745
+ }
746
+
747
+ function patchUndiciInCache() {
748
+ try {
749
+ patchGlobalFetch()
750
+ const cache = require.cache
751
+ if (!cache || typeof cache !== 'object') return
752
+ const singleton = patchedUndiciSingleton
753
+ let patched = 0
754
+ let byPath = 0
755
+ let byShape = 0
756
+ let apiRequestWrapper = null
757
+ for (const key of Object.keys(cache)) {
758
+ if (typeof key !== 'string') continue
759
+ const p = key.replace(/\\/g, '/')
760
+ if (p.indexOf('undici') !== -1 && p.indexOf('api-request') !== -1 && p.indexOf('undici-package') === -1) {
761
+ const mod = cache[key]
762
+ if (mod && mod.exports && typeof mod.exports === 'function' && mod.exports.__azifyApiRequestPatched) {
763
+ apiRequestWrapper = mod.exports
764
+ break
765
+ }
766
+ }
767
+ }
768
+ for (const key of Object.keys(cache)) {
769
+ if (typeof key !== 'string') continue
770
+ const mod = cache[key]
771
+ if (!mod || !mod.exports) continue
772
+ const ex = mod.exports
773
+ const p = key.replace(/\\/g, '/')
774
+ const pathHasUndici = p.indexOf('undici') !== -1 && !p.includes('undici-package')
775
+ const shapeMatch = isUndiciShaped(ex)
776
+ if (!pathHasUndici && !shapeMatch) continue
777
+ if (pathHasUndici) byPath++
778
+ if (shapeMatch && !pathHasUndici) byShape++
779
+ if (apiRequestWrapper && pathHasUndici && p.indexOf('undici/lib/api') !== -1 && (p.endsWith('api/index.js') || p.endsWith('lib/api.js'))) {
780
+ if (ex && typeof ex.request !== 'undefined' && ex.request !== apiRequestWrapper) {
781
+ ex.request = apiRequestWrapper
782
+ httpLog('CACHE_SCAN lib/api.request -> wrapper key=' + String(key).slice(-60))
783
+ }
784
+ }
785
+ const isMainUndici = pathHasUndici && (p.endsWith('undici/index.js') || p.endsWith('undici.js')) && p.indexOf('undici/lib') === -1
786
+ const beforeRequest = ex && ex.request && ex.request.__azifyPatched
787
+ const beforeFetch = ex && ex.fetch && ex.fetch.__azifyPatched
788
+ patchUndiciExports(mod.exports)
789
+ const afterRequest = ex && ex.request && ex.request.__azifyPatched
790
+ const afterFetch = ex && ex.fetch && ex.fetch.__azifyPatched
791
+ if ((afterRequest && !beforeRequest) || (afterFetch && !beforeFetch)) patched++
792
+ if (isMainUndici && singleton) {
793
+ if (ex && ex !== singleton && typeof ex.request === 'function' && singleton.request && singleton.request.__azifyPatched) {
794
+ ex.request = singleton.request
795
+ httpLog('CACHE_SCAN main undici mutate in place key=' + String(key).slice(-60))
796
+ }
797
+ mod.exports = singleton
798
+ httpLog('CACHE_SCAN main undici -> singleton key=' + String(key).slice(-70))
799
+ }
800
+ }
801
+ httpLog('CACHE_SCAN byPath=' + byPath + ' byShape=' + byShape + ' patched=' + patched)
802
+ if (HTTP_DEBUG) try {
803
+ process.stderr.write('[AZIFY] patchUndiciInCache byPath=' + byPath + ' byShape=' + byShape + ' patched=' + patched + '\n')
804
+ if (byPath > 0 || patched > 0) {
805
+ process.stderr.write('[AZIFY] undici no cache foi patchado — ao disparar job, espere [AZIFY-PATCH] e REQUEST/RESPONSE enqueued\n')
806
+ }
807
+ } catch (_) {}
808
+ patchGlobalDispatcherInPlace()
809
+ } catch (_) {}
810
+ }
811
+
812
+ patchGlobalFetch()
813
+ module.exports = { patchUndiciExports, patchUndiciInCache, patchGlobalFetch, patchGlobalDispatcherInPlace, flushEarlyLogQueue, getPatchedUndiciSingleton }
814
+ } catch (_) {
815
+ module.exports = { patchUndiciExports: function () {}, patchUndiciInCache: function () {}, patchGlobalFetch: function () {}, patchGlobalDispatcherInPlace: function () {}, flushEarlyLogQueue: function () {}, getPatchedUndiciSingleton: function () { return null } }
816
+ }