Callable custom context serialized on object creation instead of logging call
tback opened this issue · 3 comments
In #457 you recommend passing a callable to log the request id.
Is this limited to pure javascript? In typescript it seems I can pass custom strings only. I assume genRequestId
in your example is a function, right? in @types/bunyan custom
is an array of strings.
import bunyan from 'bunyan';
const genRequestId = () => {return 'an-id'}
const logger = bunyan.createLogger({name: 'app', requestId: genRequestId
});
logger.info('hi')
logs this:
{"name":"app","hostname":"xxxx.local","pid":19383,"level":30,"msg":"hi","time":"2021-08-05T14:58:44.999Z","v":0}
(Notice the request id is missing).
Node 12.22.4
Bunyan: 1.8.15 or 2.0.5
macos bigsur
This was initially a comment on #457, but I think it's rather a bug, than a request for support. Also, my comment didn't reopen the issue, so I feared it wouldn't be noticed.
Found out that it's not typescript specific.
Defining a serializer for the field will work around the issue:
var logger = bunyan.createLogger({
name:'app',
serializers: {
requestId: function(f) {
return f()
}
},
requestId: getRequestId
})
Sorry, I've got to reopen this. Changing the title so it matches the problem.
Old title: Callable custom context broken in typescript?
New title: Callable custom context serialized on object creation instead of logging call.
I'm still trying to make bunyan log a request with an id.
Extra fields are serialized only once: When the logger is created. This makes it impossible to use an extra field for my purpose.
You sugessting exactly this strategy in #457 make me question this is an explicit design decision? What do you suggest instead?
I had to make such wrapper to make it work:
{ trace (arg0, ...args) { const ctx = ctxLocalStorage.getStore() if (typeof (arg0) === 'object' && !Array.isArray(arg0)) { arg0.logId = ctx?.logId _log.trace(arg0, ...args) } else { _log.trace({logId: ctx?.logId}, arg0, ...args) } }, debug (arg0, ...args) { const ctx = ctxLocalStorage.getStore() if (typeof (arg0) === 'object' && !Array.isArray(arg0)) { arg0.logId = ctx?.logId _log.debug(arg0, ...args) } else { _log.debug({logId: ctx?.logId}, arg0, ...args) } }, info (arg0, ...args) { const ctx = ctxLocalStorage.getStore() if (typeof (arg0) === 'object' && !Array.isArray(arg0)) { arg0.logId = ctx?.logId _log.info(arg0, ...args) } else { _log.info({logId: ctx?.logId}, arg0, ...args) } }, warn (arg0, ...args) { const ctx = ctxLocalStorage.getStore() if (typeof (arg0) === 'object' && !Array.isArray(arg0)) { arg0.logId = ctx?.logId _log.warn(arg0, ...args) } else { _log.warn({logId: ctx?.logId}, arg0, ...args) } }, error (arg0, ...args) { const ctx = ctxLocalStorage.getStore() if (typeof (arg0) === 'object' && !Array.isArray(arg0)) { arg0.logId = ctx?.logId _log.error(arg0, ...args) } else { _log.error({logId: ctx?.logId}, arg0, ...args) } }, fatal (arg0, ...args) { const ctx = ctxLocalStorage.getStore() if (typeof (arg0) === 'object' && !Array.isArray(arg0)) { arg0.logId = ctx?.logId _log.fatal(arg0, ...args) } else { _log.fatal({logId: ctx?.logId}, arg0, ...args) } }, getLoggerInstance () { return _log // The Bunyan instance } }