azify-logger 1.0.44 → 1.0.46
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/index.js +84 -7
- package/init.js +21 -11
- package/middleware-express.js +46 -44
- package/middleware-pino.js +19 -10
- package/package.json +10 -3
- package/preload.js +15 -0
- package/register-http-client-early.js +816 -0
- package/register.js +1232 -366
- package/sampling.js +1 -1
- package/server.js +192 -16
- package/store.d.ts +68 -0
- package/store.js +190 -11
- package/streams/httpQueue.js +24 -12
- package/streams/pino.js +45 -10
package/streams/httpQueue.js
CHANGED
|
@@ -84,7 +84,7 @@ function resolveRedisConfig (overrides = {}) {
|
|
|
84
84
|
(overrides.redis && overrides.redis.url) ||
|
|
85
85
|
process.env.AZIFY_LOGGER_REDIS_URL ||
|
|
86
86
|
DEFAULT_REDIS_URL
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
if (!redisUrl) {
|
|
89
89
|
return null
|
|
90
90
|
}
|
|
@@ -108,11 +108,13 @@ function createHttpLoggerTransport (loggerUrl, overrides) {
|
|
|
108
108
|
if (!loggerUrl) {
|
|
109
109
|
return noopTransport
|
|
110
110
|
}
|
|
111
|
+
overrides = overrides || {}
|
|
111
112
|
|
|
112
113
|
const options = resolveOptions(overrides)
|
|
113
114
|
const redisConfig = resolveRedisConfig(overrides)
|
|
115
|
+
const hasRedisPassword = redisConfig && redisConfig.password != null && String(redisConfig.password).trim() !== ''
|
|
114
116
|
|
|
115
|
-
if (redisConfig) {
|
|
117
|
+
if (redisConfig && hasRedisPassword) {
|
|
116
118
|
try {
|
|
117
119
|
return createRedisStreamTransport(loggerUrl, options, redisConfig)
|
|
118
120
|
} catch (err) {
|
|
@@ -124,9 +126,7 @@ function createHttpLoggerTransport (loggerUrl, overrides) {
|
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
const redisUrl = overrides.redisUrl || (overrides.redis && overrides.redis.url) || process.env.AZIFY_LOGGER_REDIS_URL || DEFAULT_REDIS_URL
|
|
127
|
-
|
|
128
|
-
const pass = password != null && String(password).trim() !== '' ? String(password).trim() : undefined
|
|
129
|
-
if (redisUrl && !pass) {
|
|
129
|
+
if (redisUrl && !hasRedisPassword) {
|
|
130
130
|
if (typeof global.__azifyLoggerRedisPasswordWarned === 'undefined') {
|
|
131
131
|
global.__azifyLoggerRedisPasswordWarned = true
|
|
132
132
|
process.stderr.write('[azify-logger] ⚠️ Redis requires a password. No password set. Using direct HTTP (no Redis). Set AZIFY_LOGGER_REDIS_PASSWORD to use Redis.\n')
|
|
@@ -250,7 +250,7 @@ function buildInlineTransport (loggerUrl, options) {
|
|
|
250
250
|
|
|
251
251
|
flushTimer = setTimeout(() => {
|
|
252
252
|
flushTimer = null
|
|
253
|
-
|
|
253
|
+
flushQueue().catch(() => {})
|
|
254
254
|
}, delay)
|
|
255
255
|
|
|
256
256
|
if (typeof flushTimer.unref === 'function') {
|
|
@@ -278,9 +278,15 @@ function buildInlineTransport (loggerUrl, options) {
|
|
|
278
278
|
try {
|
|
279
279
|
for (let i = 0; i < batch.length; i += 1) {
|
|
280
280
|
const { payload, headers } = batch[i]
|
|
281
|
+
let body
|
|
282
|
+
try {
|
|
283
|
+
body = typeof payload === 'string' ? payload : JSON.stringify(payload)
|
|
284
|
+
} catch (_) {
|
|
285
|
+
continue
|
|
286
|
+
}
|
|
281
287
|
try {
|
|
282
|
-
await axios.post(loggerUrl,
|
|
283
|
-
headers,
|
|
288
|
+
await axios.post(loggerUrl, body, {
|
|
289
|
+
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
284
290
|
timeout: options.timeout,
|
|
285
291
|
httpAgent,
|
|
286
292
|
httpsAgent,
|
|
@@ -298,11 +304,9 @@ function buildInlineTransport (loggerUrl, options) {
|
|
|
298
304
|
if (remaining.length) {
|
|
299
305
|
queue.unshift(...remaining)
|
|
300
306
|
}
|
|
301
|
-
|
|
302
|
-
throw error
|
|
303
307
|
}
|
|
304
308
|
}
|
|
305
|
-
} catch (
|
|
309
|
+
} catch (e) {
|
|
306
310
|
} finally {
|
|
307
311
|
flushing = false
|
|
308
312
|
if (queue.length) {
|
|
@@ -311,6 +315,12 @@ function buildInlineTransport (loggerUrl, options) {
|
|
|
311
315
|
}
|
|
312
316
|
}
|
|
313
317
|
|
|
318
|
+
const isRequestOrResponsePayload = (p) => {
|
|
319
|
+
if (!p || typeof p !== 'object') return false
|
|
320
|
+
const msg = typeof p.message === 'string' ? p.message : ''
|
|
321
|
+
return msg.includes('[REQUEST]') || msg.includes('[RESPONSE]')
|
|
322
|
+
}
|
|
323
|
+
|
|
314
324
|
const enqueue = (payload, headers = {}) => {
|
|
315
325
|
if (queue.length >= options.maxQueueSize) {
|
|
316
326
|
queue.shift()
|
|
@@ -319,7 +329,9 @@ function buildInlineTransport (loggerUrl, options) {
|
|
|
319
329
|
queue.push({ payload, headers })
|
|
320
330
|
|
|
321
331
|
if (queue.length >= options.batchSize) {
|
|
322
|
-
|
|
332
|
+
flushQueue().catch(() => {})
|
|
333
|
+
} else if (isRequestOrResponsePayload(payload)) {
|
|
334
|
+
scheduleFlush(0)
|
|
323
335
|
} else {
|
|
324
336
|
scheduleFlush()
|
|
325
337
|
}
|
package/streams/pino.js
CHANGED
|
@@ -36,26 +36,49 @@ function createPinoStream(options = {}) {
|
|
|
36
36
|
|
|
37
37
|
let traceId, spanId, parentSpanId
|
|
38
38
|
try {
|
|
39
|
-
const { getRequestContext } = require('../store')
|
|
39
|
+
const { getRequestContext, getLastJobContext, toTraceIdHex } = require('../store')
|
|
40
40
|
const ctx = getRequestContext()
|
|
41
41
|
if (ctx && ctx.traceId) {
|
|
42
42
|
traceId = ctx.traceId
|
|
43
43
|
spanId = ctx.spanId
|
|
44
44
|
parentSpanId = ctx.parentSpanId
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
if (!traceId
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
|
|
47
|
+
if (!traceId) {
|
|
48
|
+
const jobCtx = getLastJobContext()
|
|
49
|
+
if (jobCtx && jobCtx.traceId) {
|
|
50
|
+
traceId = jobCtx.traceId
|
|
51
|
+
spanId = jobCtx.spanId
|
|
52
|
+
parentSpanId = jobCtx.parentSpanId
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!traceId && (record.traceId || (record.data && record.data.traceId))) {
|
|
57
|
+
traceId = record.traceId || (record.data && record.data.traceId)
|
|
58
|
+
spanId = record.spanId != null ? record.spanId : (record.data && record.data.spanId)
|
|
59
|
+
parentSpanId = record.parentSpanId != null ? record.parentSpanId : (record.data && record.data.parentSpanId)
|
|
51
60
|
}
|
|
52
|
-
|
|
61
|
+
|
|
53
62
|
if (!traceId && record.req && record.req.traceId) {
|
|
54
63
|
traceId = record.req.traceId
|
|
55
64
|
spanId = record.req.spanId
|
|
56
65
|
parentSpanId = record.req.parentSpanId
|
|
57
66
|
}
|
|
58
|
-
|
|
67
|
+
|
|
68
|
+
if (!traceId) {
|
|
69
|
+
const msgStr = record.msg || record.message || ''
|
|
70
|
+
if (typeof msgStr === 'string' && /traceId/i.test(msgStr)) {
|
|
71
|
+
const m = msgStr.match(/"traceId"\s*:\s*"([^"]+)"/)
|
|
72
|
+
if (m) {
|
|
73
|
+
traceId = m[1]
|
|
74
|
+
const s = msgStr.match(/"spanId"\s*:\s*"([^"]+)"/)
|
|
75
|
+
spanId = s ? s[1] : null
|
|
76
|
+
const p = msgStr.match(/"parentSpanId"\s*:\s*"([^"]*)"/)
|
|
77
|
+
parentSpanId = (p && p[1]) ? p[1] : null
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
59
82
|
if (!traceId) {
|
|
60
83
|
const span = trace.getSpan(context.active())
|
|
61
84
|
const spanContext = span && span.spanContext()
|
|
@@ -65,6 +88,11 @@ function createPinoStream(options = {}) {
|
|
|
65
88
|
parentSpanId = spanContext.parentSpanId
|
|
66
89
|
}
|
|
67
90
|
}
|
|
91
|
+
|
|
92
|
+
if (traceId && typeof traceId === 'string') {
|
|
93
|
+
traceId = toTraceIdHex(traceId)
|
|
94
|
+
if (spanId != null) spanId = String(spanId).slice(0, 16)
|
|
95
|
+
}
|
|
68
96
|
} catch (_) {}
|
|
69
97
|
|
|
70
98
|
const headers = {}
|
|
@@ -90,12 +118,19 @@ function createPinoStream(options = {}) {
|
|
|
90
118
|
...(parentSpanId && { parentSpanId })
|
|
91
119
|
}
|
|
92
120
|
|
|
93
|
-
|
|
121
|
+
const isErrorOrWarn = level === 'error' || level === 'fatal' || level === 'warn'
|
|
122
|
+
if (!isErrorOrWarn && !shouldSample(level, 'logger')) {
|
|
94
123
|
return
|
|
95
124
|
}
|
|
96
125
|
|
|
97
126
|
const payload = { level, message: record.msg || record.message || 'log', meta }
|
|
98
|
-
|
|
127
|
+
try {
|
|
128
|
+
transport.enqueue(payload, headers)
|
|
129
|
+
} catch (err) {
|
|
130
|
+
if (process.env.AZIFY_LOGGER_DEBUG === '1') {
|
|
131
|
+
process.stderr.write(`[azify-logger] pino stream enqueue error: ${err && err.message}\n`)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
99
134
|
}
|
|
100
135
|
}
|
|
101
136
|
}
|