azify-logger 1.0.55 → 1.0.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +14 -11
- package/register-http-client-early.js +135 -25
- package/register-otel.js +6 -6
- package/register.js +170 -48
- package/scripts/redis-worker.js +7 -42
- package/server.js +167 -21
- package/utils/sanitizeSensitiveHttpBody.js +222 -0
- package/utils/undiciLogBodies.js +83 -0
package/register.js
CHANGED
|
@@ -25,6 +25,7 @@ try {
|
|
|
25
25
|
const os = require('os')
|
|
26
26
|
|
|
27
27
|
const { shouldSample, markSource, HTTP_CLIENT_MODE } = require('./sampling')
|
|
28
|
+
const { sanitizeOutboundHttpMetaBodies } = require('./utils/sanitizeSensitiveHttpBody')
|
|
28
29
|
|
|
29
30
|
if (process.env.AZIFY_LOGGER_DEBUG === '1') {
|
|
30
31
|
try { process.stderr.write('[azify-logger] REGISTER step1b after requires\n') } catch (_) {}
|
|
@@ -32,13 +33,17 @@ try {
|
|
|
32
33
|
}
|
|
33
34
|
const serviceName = process.env.APP_NAME
|
|
34
35
|
const environment = process.env.NODE_ENV
|
|
35
|
-
const
|
|
36
|
-
|
|
36
|
+
const loggerUrlRaw = (process.env.AZIFY_LOGGER_URL || '').trim()
|
|
37
|
+
if (!loggerUrlRaw) {
|
|
38
|
+
process.stderr.write('[azify-logger] AZIFY_LOGGER_URL não está definida.\n')
|
|
39
|
+
throw new Error('AZIFY_LOGGER_URL is required')
|
|
40
|
+
}
|
|
37
41
|
let loggerEndpoint
|
|
38
42
|
try {
|
|
39
|
-
loggerEndpoint = new URL(
|
|
40
|
-
} catch (
|
|
41
|
-
|
|
43
|
+
loggerEndpoint = new URL(loggerUrlRaw)
|
|
44
|
+
} catch (urlErr) {
|
|
45
|
+
process.stderr.write(`[azify-logger] AZIFY_LOGGER_URL inválida: ${loggerUrlRaw} (${urlErr.message})\n`)
|
|
46
|
+
throw urlErr
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
const loggerUrlString = loggerEndpoint.toString()
|
|
@@ -176,6 +181,9 @@ try {
|
|
|
176
181
|
const fromMsg = extractUrlFromReqResMessage(msgStr)
|
|
177
182
|
meta = fromMsg ? { ...meta, url: fromMsg } : { ...meta, url: OPAQUE_NO_URL }
|
|
178
183
|
}
|
|
184
|
+
try {
|
|
185
|
+
meta = sanitizeOutboundHttpMetaBodies(meta)
|
|
186
|
+
} catch (_) {}
|
|
179
187
|
}
|
|
180
188
|
if (isReqRes && meta && meta.url && isLoggerApiCall({ url: meta.url })) return
|
|
181
189
|
const source = meta && meta.__source
|
|
@@ -445,16 +453,24 @@ try {
|
|
|
445
453
|
const { randomBytes } = require('crypto')
|
|
446
454
|
const { performance } = require('perf_hooks')
|
|
447
455
|
const { getRequestContext, getLastJobContext, toTraceIdHex } = require('./store')
|
|
456
|
+
const {
|
|
457
|
+
resolveUndiciRequestOpts,
|
|
458
|
+
serializeUndiciRequestBody,
|
|
459
|
+
restoreUndiciResponseBodyAfterReadForLog
|
|
460
|
+
} = require('./utils/undiciLogBodies')
|
|
448
461
|
const origRequest = exports.request
|
|
449
462
|
exports.request = function(url, options, callback) {
|
|
450
463
|
const ctx = getRequestContext() || getLastJobContext()
|
|
451
464
|
const otelCtx = getOtelTraceContext()
|
|
452
465
|
const traceCtx = ctx || otelCtx
|
|
453
|
-
const
|
|
466
|
+
const reqOpts = resolveUndiciRequestOpts(url, options)
|
|
467
|
+
const method = (reqOpts.method || options?.method || 'GET').toUpperCase()
|
|
454
468
|
const urlString = typeof url === 'string' ? url : (url && url.toString && url.toString()) || 'unknown'
|
|
455
469
|
const rawTraceId = traceCtx?.traceId || (require('crypto').randomUUID && require('crypto').randomUUID())
|
|
456
470
|
const traceId = typeof rawTraceId === 'string' ? toTraceIdHex(rawTraceId) : rawTraceId
|
|
471
|
+
const requestBodyStr = serializeUndiciRequestBody(reqOpts)
|
|
457
472
|
const requestMeta = { traceId, spanId: traceCtx?.spanId || null, parentSpanId: traceCtx?.parentSpanId || null, requestId: traceCtx?.requestId || null, method, url: urlString }
|
|
473
|
+
if (requestBodyStr != null) requestMeta.requestBody = requestBodyStr
|
|
458
474
|
markSource(requestMeta, 'http-client')
|
|
459
475
|
const startTime = performance.now()
|
|
460
476
|
if (HTTP_CLIENT_MODE !== 'off') {
|
|
@@ -462,20 +478,39 @@ try {
|
|
|
462
478
|
}
|
|
463
479
|
const wrappedCb = callback ? function(err, data) {
|
|
464
480
|
const duration = Number((performance.now() - startTime).toFixed(2))
|
|
465
|
-
if (
|
|
466
|
-
if (
|
|
467
|
-
|
|
481
|
+
if (err) {
|
|
482
|
+
if (HTTP_CLIENT_MODE !== 'off') {
|
|
483
|
+
sendOutboundLog('error', `[RESPONSE] ${method} ${urlString} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
|
|
484
|
+
}
|
|
485
|
+
return callback(err, data)
|
|
468
486
|
}
|
|
469
|
-
return callback(err, data)
|
|
487
|
+
if (!data) return callback(err, data)
|
|
488
|
+
restoreUndiciResponseBodyAfterReadForLog(data).then(({ logStr, data: restored }) => {
|
|
489
|
+
if (HTTP_CLIENT_MODE !== 'off') {
|
|
490
|
+
const meta = { ...requestMeta, statusCode: restored.statusCode, responseTimeMs: duration }
|
|
491
|
+
if (logStr != null) meta.responseBody = logStr
|
|
492
|
+
sendOutboundLog('info', `[RESPONSE] ${method} ${urlString} ${restored.statusCode} ${duration}ms`, meta)
|
|
493
|
+
}
|
|
494
|
+
return callback(null, restored)
|
|
495
|
+
}).catch(() => {
|
|
496
|
+
if (HTTP_CLIENT_MODE !== 'off') {
|
|
497
|
+
sendOutboundLog('info', `[RESPONSE] ${method} ${urlString} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
|
|
498
|
+
}
|
|
499
|
+
return callback(null, data)
|
|
500
|
+
})
|
|
470
501
|
} : undefined
|
|
471
502
|
if (wrappedCb) return origRequest.call(this, url, options, wrappedCb)
|
|
472
503
|
const promise = origRequest.call(this, url, options)
|
|
473
504
|
if (promise && typeof promise.then === 'function') {
|
|
474
505
|
return promise.then(
|
|
475
|
-
(data) => {
|
|
506
|
+
async (data) => {
|
|
476
507
|
const duration = Number((performance.now() - startTime).toFixed(2))
|
|
477
508
|
if (HTTP_CLIENT_MODE !== 'off' && data) {
|
|
478
|
-
|
|
509
|
+
const { logStr, data: restored } = await restoreUndiciResponseBodyAfterReadForLog(data)
|
|
510
|
+
const meta = { ...requestMeta, statusCode: restored.statusCode, responseTimeMs: duration }
|
|
511
|
+
if (logStr != null) meta.responseBody = logStr
|
|
512
|
+
sendOutboundLog('info', `[RESPONSE] ${method} ${urlString} ${restored.statusCode} ${duration}ms`, meta)
|
|
513
|
+
return restored
|
|
479
514
|
}
|
|
480
515
|
return data
|
|
481
516
|
},
|
|
@@ -504,7 +539,9 @@ try {
|
|
|
504
539
|
const urlString = origin ? (origin + (path.startsWith('/') ? path : '/' + path)) : 'unknown'
|
|
505
540
|
const rawTraceId = traceCtx?.traceId || (require('crypto').randomUUID && require('crypto').randomUUID())
|
|
506
541
|
const traceId = typeof rawTraceId === 'string' ? toTraceIdHex(rawTraceId) : rawTraceId
|
|
542
|
+
const requestBodyStr = serializeUndiciRequestBody(opts || {})
|
|
507
543
|
const requestMeta = { traceId, spanId: traceCtx?.spanId || null, parentSpanId: traceCtx?.parentSpanId || null, requestId: traceCtx?.requestId || null, method: methodStr, url: urlString }
|
|
544
|
+
if (requestBodyStr != null) requestMeta.requestBody = requestBodyStr
|
|
508
545
|
markSource(requestMeta, 'http-client')
|
|
509
546
|
const startTime = performance.now()
|
|
510
547
|
if (HTTP_CLIENT_MODE !== 'off') {
|
|
@@ -512,19 +549,38 @@ try {
|
|
|
512
549
|
}
|
|
513
550
|
const wrappedCb = typeof callback === 'function' ? function(err, data) {
|
|
514
551
|
const duration = Number((performance.now() - startTime).toFixed(2))
|
|
515
|
-
if (
|
|
516
|
-
if (
|
|
517
|
-
|
|
552
|
+
if (err) {
|
|
553
|
+
if (HTTP_CLIENT_MODE !== 'off') {
|
|
554
|
+
sendOutboundLog('error', `[RESPONSE] ${methodStr} ${urlString} ERROR ${duration}ms`, { ...requestMeta, error: err && err.message, responseTimeMs: duration })
|
|
555
|
+
}
|
|
556
|
+
return callback(err, data)
|
|
518
557
|
}
|
|
519
|
-
return callback(err, data)
|
|
558
|
+
if (!data) return callback(err, data)
|
|
559
|
+
restoreUndiciResponseBodyAfterReadForLog(data).then(({ logStr, data: restored }) => {
|
|
560
|
+
if (HTTP_CLIENT_MODE !== 'off') {
|
|
561
|
+
const meta = { ...requestMeta, statusCode: restored.statusCode, responseTimeMs: duration }
|
|
562
|
+
if (logStr != null) meta.responseBody = logStr
|
|
563
|
+
sendOutboundLog('info', `[RESPONSE] ${methodStr} ${urlString} ${restored.statusCode} ${duration}ms`, meta)
|
|
564
|
+
}
|
|
565
|
+
return callback(null, restored)
|
|
566
|
+
}).catch(() => {
|
|
567
|
+
if (HTTP_CLIENT_MODE !== 'off') {
|
|
568
|
+
sendOutboundLog('info', `[RESPONSE] ${methodStr} ${urlString} ${data.statusCode} ${duration}ms`, { ...requestMeta, statusCode: data.statusCode, responseTimeMs: duration })
|
|
569
|
+
}
|
|
570
|
+
return callback(null, data)
|
|
571
|
+
})
|
|
520
572
|
} : undefined
|
|
521
573
|
const ret = wrappedCb ? origDispRequest.call(this, opts, wrappedCb) : origDispRequest.call(this, opts)
|
|
522
574
|
if (ret && typeof ret.then === 'function' && !wrappedCb) {
|
|
523
575
|
return ret.then(
|
|
524
|
-
(data) => {
|
|
576
|
+
async (data) => {
|
|
525
577
|
const duration = Number((performance.now() - startTime).toFixed(2))
|
|
526
578
|
if (HTTP_CLIENT_MODE !== 'off' && data) {
|
|
527
|
-
|
|
579
|
+
const { logStr, data: restored } = await restoreUndiciResponseBodyAfterReadForLog(data)
|
|
580
|
+
const meta = { ...requestMeta, statusCode: restored.statusCode, responseTimeMs: duration }
|
|
581
|
+
if (logStr != null) meta.responseBody = logStr
|
|
582
|
+
sendOutboundLog('info', `[RESPONSE] ${methodStr} ${urlString} ${restored.statusCode} ${duration}ms`, meta)
|
|
583
|
+
return restored
|
|
528
584
|
}
|
|
529
585
|
return data
|
|
530
586
|
},
|
|
@@ -1588,6 +1644,35 @@ try {
|
|
|
1588
1644
|
return url
|
|
1589
1645
|
}
|
|
1590
1646
|
|
|
1647
|
+
const MAX_HTTP_BODY_CHARS = Math.min(
|
|
1648
|
+
Math.max(parseInt(String(process.env.AZIFY_LOGGER_HTTP_BODY_MAX_CHARS || '5000'), 10) || 5000, 100),
|
|
1649
|
+
100000
|
|
1650
|
+
)
|
|
1651
|
+
function clipHttpLogString(s) {
|
|
1652
|
+
if (typeof s !== 'string') return s
|
|
1653
|
+
return s.length > MAX_HTTP_BODY_CHARS ? s.slice(0, MAX_HTTP_BODY_CHARS) : s
|
|
1654
|
+
}
|
|
1655
|
+
function stringifyHttpBodyForLog(value) {
|
|
1656
|
+
if (value == null) return null
|
|
1657
|
+
try {
|
|
1658
|
+
if (typeof value === 'string') {
|
|
1659
|
+
return clipHttpLogString(value)
|
|
1660
|
+
}
|
|
1661
|
+
if (Buffer.isBuffer(value)) {
|
|
1662
|
+
return clipHttpLogString(value.toString('utf8'))
|
|
1663
|
+
}
|
|
1664
|
+
if (value && typeof value.pipe === 'function') {
|
|
1665
|
+
return '[Stream]'
|
|
1666
|
+
}
|
|
1667
|
+
if (typeof value === 'object') {
|
|
1668
|
+
return clipHttpLogString(JSON.stringify(value))
|
|
1669
|
+
}
|
|
1670
|
+
return clipHttpLogString(String(value))
|
|
1671
|
+
} catch (_) {
|
|
1672
|
+
return '[unserializable]'
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1591
1676
|
const patchInstance = (instance) => {
|
|
1592
1677
|
if (instance.__azifyLoggerPatched) {
|
|
1593
1678
|
return instance
|
|
@@ -1631,6 +1716,11 @@ try {
|
|
|
1631
1716
|
headers: config.headers
|
|
1632
1717
|
}
|
|
1633
1718
|
|
|
1719
|
+
const requestBodyString = stringifyHttpBodyForLog(config.data)
|
|
1720
|
+
if (requestBodyString != null) {
|
|
1721
|
+
requestMeta.requestBody = requestBodyString
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1634
1724
|
markSource(requestMeta, 'http-client')
|
|
1635
1725
|
config.__azifyLogger = {
|
|
1636
1726
|
meta: requestMeta,
|
|
@@ -1684,12 +1774,15 @@ try {
|
|
|
1684
1774
|
|
|
1685
1775
|
const stringifyBody = (value) => {
|
|
1686
1776
|
if (value == null) return null
|
|
1687
|
-
if (typeof value === 'string') return value
|
|
1777
|
+
if (typeof value === 'string') return clipHttpLogString(value)
|
|
1778
|
+
if (Buffer.isBuffer(value)) {
|
|
1779
|
+
return clipHttpLogString(value.toString('utf8'))
|
|
1780
|
+
}
|
|
1688
1781
|
try {
|
|
1689
|
-
return JSON.stringify(value)
|
|
1782
|
+
return clipHttpLogString(JSON.stringify(value))
|
|
1690
1783
|
} catch (_) {
|
|
1691
1784
|
try {
|
|
1692
|
-
return String(value)
|
|
1785
|
+
return clipHttpLogString(String(value))
|
|
1693
1786
|
} catch (_) {
|
|
1694
1787
|
return null
|
|
1695
1788
|
}
|
|
@@ -1698,17 +1791,16 @@ try {
|
|
|
1698
1791
|
|
|
1699
1792
|
if (marker && marker.meta) {
|
|
1700
1793
|
duration = Number((performance.now() - marker.start).toFixed(2))
|
|
1701
|
-
|
|
1702
|
-
if (typeof responseBodyString === 'string' && responseBodyString.length > 5000) {
|
|
1703
|
-
responseBodyString = responseBodyString.slice(0, 5000)
|
|
1704
|
-
}
|
|
1794
|
+
const responseBodyString = stringifyBody(response.data)
|
|
1705
1795
|
meta = {
|
|
1706
1796
|
...marker.meta,
|
|
1707
1797
|
url: finalUrl,
|
|
1708
1798
|
statusCode: response.status,
|
|
1709
1799
|
responseTimeMs: duration,
|
|
1710
|
-
responseHeaders: response.headers
|
|
1711
|
-
|
|
1800
|
+
responseHeaders: response.headers
|
|
1801
|
+
}
|
|
1802
|
+
if (responseBodyString != null) {
|
|
1803
|
+
meta.responseBody = responseBodyString
|
|
1712
1804
|
}
|
|
1713
1805
|
} else {
|
|
1714
1806
|
const requestHeaders = response.config?.headers || {}
|
|
@@ -1717,10 +1809,7 @@ try {
|
|
|
1717
1809
|
const spanId = requestHeaders['x-span-id'] || requestHeaders['X-Span-ID'] || randomBytes(8).toString('hex')
|
|
1718
1810
|
const parentSpanId = requestHeaders['x-parent-span-id'] || requestHeaders['X-Parent-Span-ID'] || ctx?.spanId || null
|
|
1719
1811
|
const requestId = requestHeaders['x-request-id'] || requestHeaders['X-Request-ID'] || ctx?.requestId || randomUUID()
|
|
1720
|
-
|
|
1721
|
-
if (typeof responseBodyString === 'string' && responseBodyString.length > 5000) {
|
|
1722
|
-
responseBodyString = responseBodyString.slice(0, 5000)
|
|
1723
|
-
}
|
|
1812
|
+
const responseBodyString = stringifyBody(response.data)
|
|
1724
1813
|
|
|
1725
1814
|
meta = {
|
|
1726
1815
|
traceId,
|
|
@@ -1731,8 +1820,10 @@ try {
|
|
|
1731
1820
|
url: finalUrl,
|
|
1732
1821
|
statusCode: response.status,
|
|
1733
1822
|
responseTimeMs: duration,
|
|
1734
|
-
responseHeaders: response.headers
|
|
1735
|
-
|
|
1823
|
+
responseHeaders: response.headers
|
|
1824
|
+
}
|
|
1825
|
+
if (responseBodyString != null) {
|
|
1826
|
+
meta.responseBody = responseBodyString
|
|
1736
1827
|
}
|
|
1737
1828
|
}
|
|
1738
1829
|
|
|
@@ -1931,19 +2022,35 @@ try {
|
|
|
1931
2022
|
} catch (_) {
|
|
1932
2023
|
}
|
|
1933
2024
|
|
|
2025
|
+
const maxFetchBodyChars = Math.min(
|
|
2026
|
+
Math.max(parseInt(String(process.env.AZIFY_LOGGER_HTTP_BODY_MAX_CHARS || '5000'), 10) || 5000, 100),
|
|
2027
|
+
100000
|
|
2028
|
+
)
|
|
2029
|
+
const clipFetchBody = (s) => {
|
|
2030
|
+
if (typeof s !== 'string' || !s.length) return null
|
|
2031
|
+
return s.length > maxFetchBodyChars ? s.slice(0, maxFetchBodyChars) : s
|
|
2032
|
+
}
|
|
2033
|
+
|
|
1934
2034
|
let requestBodyString = null
|
|
1935
|
-
|
|
1936
|
-
|
|
2035
|
+
try {
|
|
2036
|
+
if (init && init.body !== null && init.body !== undefined) {
|
|
1937
2037
|
if (typeof init.body === 'string') {
|
|
1938
|
-
requestBodyString = init.body
|
|
2038
|
+
requestBodyString = clipFetchBody(init.body)
|
|
1939
2039
|
} else if (init.body instanceof FormData || init.body instanceof URLSearchParams) {
|
|
1940
2040
|
requestBodyString = '[FormData/URLSearchParams]'
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
} catch (_) {
|
|
2044
|
+
}
|
|
2045
|
+
if (requestBodyString == null && request.body != null && method !== 'GET' && method !== 'HEAD') {
|
|
2046
|
+
try {
|
|
2047
|
+
const clone = request.clone()
|
|
2048
|
+
const text = await Promise.race([
|
|
2049
|
+
clone.text(),
|
|
2050
|
+
new Promise((resolve) => setTimeout(() => resolve(null), 4000))
|
|
2051
|
+
])
|
|
2052
|
+
if (typeof text === 'string' && text.length) {
|
|
2053
|
+
requestBodyString = clipFetchBody(text)
|
|
1947
2054
|
}
|
|
1948
2055
|
} catch (_) {
|
|
1949
2056
|
}
|
|
@@ -2050,10 +2157,15 @@ try {
|
|
|
2050
2157
|
}
|
|
2051
2158
|
}
|
|
2052
2159
|
|
|
2160
|
+
const responseReadMs = Math.min(
|
|
2161
|
+
Math.max(parseInt(String(process.env.AZIFY_LOGGER_HTTP_RESPONSE_READ_MS || '4000'), 10) || 4000, 200),
|
|
2162
|
+
30000
|
|
2163
|
+
)
|
|
2164
|
+
|
|
2053
2165
|
if (contentType.includes('application/json') || contentType.includes('text/')) {
|
|
2054
2166
|
try {
|
|
2055
2167
|
const clonedResponse = response.clone()
|
|
2056
|
-
const bodyText = await readBodyWithTimeout(clonedResponse,
|
|
2168
|
+
const bodyText = await readBodyWithTimeout(clonedResponse, responseReadMs)
|
|
2057
2169
|
if (bodyText) {
|
|
2058
2170
|
if (contentType.includes('application/json')) {
|
|
2059
2171
|
try {
|
|
@@ -2064,13 +2176,13 @@ try {
|
|
|
2064
2176
|
} else {
|
|
2065
2177
|
responseBodyString = bodyText
|
|
2066
2178
|
}
|
|
2067
|
-
if (typeof responseBodyString === 'string' && responseBodyString.length >
|
|
2068
|
-
responseBodyString = responseBodyString.slice(0,
|
|
2179
|
+
if (typeof responseBodyString === 'string' && responseBodyString.length > maxFetchBodyChars) {
|
|
2180
|
+
responseBodyString = responseBodyString.slice(0, maxFetchBodyChars)
|
|
2069
2181
|
}
|
|
2070
2182
|
}
|
|
2071
2183
|
} catch (_) {
|
|
2072
2184
|
try {
|
|
2073
|
-
const bodyText = await readBodyWithTimeout(response,
|
|
2185
|
+
const bodyText = await readBodyWithTimeout(response, responseReadMs)
|
|
2074
2186
|
if (bodyText) {
|
|
2075
2187
|
if (contentType.includes('application/json')) {
|
|
2076
2188
|
try {
|
|
@@ -2081,13 +2193,23 @@ try {
|
|
|
2081
2193
|
} else {
|
|
2082
2194
|
responseBodyString = bodyText
|
|
2083
2195
|
}
|
|
2084
|
-
if (typeof responseBodyString === 'string' && responseBodyString.length >
|
|
2085
|
-
responseBodyString = responseBodyString.slice(0,
|
|
2196
|
+
if (typeof responseBodyString === 'string' && responseBodyString.length > maxFetchBodyChars) {
|
|
2197
|
+
responseBodyString = responseBodyString.slice(0, maxFetchBodyChars)
|
|
2086
2198
|
}
|
|
2087
2199
|
}
|
|
2088
2200
|
} catch (_) {
|
|
2089
2201
|
}
|
|
2090
2202
|
}
|
|
2203
|
+
} else if (response.status !== 204 && response.status !== 205 && response.status !== 304) {
|
|
2204
|
+
try {
|
|
2205
|
+
const clonedResponse = response.clone()
|
|
2206
|
+
const bodyText = await readBodyWithTimeout(clonedResponse, responseReadMs)
|
|
2207
|
+
if (bodyText && bodyText.length) {
|
|
2208
|
+
responseBodyString =
|
|
2209
|
+
bodyText.length > maxFetchBodyChars ? bodyText.slice(0, maxFetchBodyChars) : bodyText
|
|
2210
|
+
}
|
|
2211
|
+
} catch (_) {
|
|
2212
|
+
}
|
|
2091
2213
|
}
|
|
2092
2214
|
} catch (_) {
|
|
2093
2215
|
}
|
package/scripts/redis-worker.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
const path = require('path')
|
|
3
4
|
const os = require('os')
|
|
4
5
|
const http = require('http')
|
|
5
6
|
const https = require('https')
|
|
@@ -159,24 +160,6 @@ const SENSITIVE_HEADER_KEYS = new Set([
|
|
|
159
160
|
'x-timestamp'
|
|
160
161
|
])
|
|
161
162
|
|
|
162
|
-
const SENSITIVE_BODY_FIELDS = new Set([
|
|
163
|
-
'password',
|
|
164
|
-
'token',
|
|
165
|
-
'secret',
|
|
166
|
-
'apiKey',
|
|
167
|
-
'api_key',
|
|
168
|
-
'accessToken',
|
|
169
|
-
'access_token',
|
|
170
|
-
'refreshToken',
|
|
171
|
-
'refresh_token',
|
|
172
|
-
'clientSecret',
|
|
173
|
-
'client_secret',
|
|
174
|
-
'creditCard',
|
|
175
|
-
'credit_card',
|
|
176
|
-
'cvv',
|
|
177
|
-
'cvc'
|
|
178
|
-
])
|
|
179
|
-
|
|
180
163
|
function sanitizeHeaders(headers) {
|
|
181
164
|
if (!headers || typeof headers !== 'object') {
|
|
182
165
|
return {}
|
|
@@ -195,31 +178,10 @@ function sanitizeHeaders(headers) {
|
|
|
195
178
|
return sanitized
|
|
196
179
|
}
|
|
197
180
|
|
|
181
|
+
const sanitizeBodyJsonValue = require(path.join(__dirname, '..', 'utils', 'sanitizeSensitiveHttpBody')).sanitizeBodyJsonValue
|
|
182
|
+
|
|
198
183
|
function sanitizeBody(body) {
|
|
199
|
-
|
|
200
|
-
return body
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
const sanitized = Array.isArray(body) ? [] : {}
|
|
205
|
-
|
|
206
|
-
for (const key in body) {
|
|
207
|
-
if (!body.hasOwnProperty(key)) continue
|
|
208
|
-
const lower = String(key).toLowerCase()
|
|
209
|
-
|
|
210
|
-
if (SENSITIVE_BODY_FIELDS.has(lower) || lower.includes('password') || lower.includes('secret')) {
|
|
211
|
-
sanitized[key] = '***'
|
|
212
|
-
} else if (typeof body[key] === 'object' && body[key] !== null) {
|
|
213
|
-
sanitized[key] = sanitizeBody(body[key])
|
|
214
|
-
} else {
|
|
215
|
-
sanitized[key] = body[key]
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return sanitized
|
|
220
|
-
} catch (err) {
|
|
221
|
-
return body
|
|
222
|
-
}
|
|
184
|
+
return sanitizeBodyJsonValue(body)
|
|
223
185
|
}
|
|
224
186
|
|
|
225
187
|
function sanitizePayload(payload) {
|
|
@@ -254,6 +216,9 @@ function sanitizePayload(payload) {
|
|
|
254
216
|
if (sanitized.meta.responseBody) {
|
|
255
217
|
sanitized.meta.responseBody = sanitizeBody(sanitized.meta.responseBody)
|
|
256
218
|
}
|
|
219
|
+
if (sanitized.meta.requestBody) {
|
|
220
|
+
sanitized.meta.requestBody = sanitizeBody(sanitized.meta.requestBody)
|
|
221
|
+
}
|
|
257
222
|
}
|
|
258
223
|
|
|
259
224
|
return sanitized
|