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.
@@ -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
- const password = overrides.redisPassword ?? (overrides.redis && overrides.redis.password) ?? process.env.AZIFY_LOGGER_REDIS_PASSWORD
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
- void flushQueue()
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, payload, {
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
- void flushQueue()
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 && record.traceId) {
48
- traceId = record.traceId
49
- spanId = record.spanId
50
- parentSpanId = record.parentSpanId
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
- if (!shouldSample(level, 'logger')) {
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
- transport.enqueue(payload, headers)
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
  }