pino
pino copied to clipboard
Provide support for lazy evaluation
Similar to https://deno.land/[email protected]/log#lazy-log-evaluation & https://www.npmjs.com/package/@northscaler/bunyaner.
In the event that there is an expensive calculation performed in order to log something, and the current log level is such that the log statement wouldn't result in any output, allow the user to pass a function to the log level method. The function would only be evaluated if the log level method would produce output given the current log level. Any log level method that is given a function should return undefined.
Example:
const log = pino()()
log.debug(() => expensiveOperation()) // function only evaluated if current level is at or below debug
NOTE: This feature should not be used with the proposed inline logging feature. In other words, once inline logging is supported, don't do this:
// BAD -- DON'T DO THIS
const log = pino()()
const it = log.debug(() => expensiveOperation()) // function is not evaluated if current level is at or below debug, so you'd get `undefined`
I'm not opposed to this but I'm not entirely for it.
It's essentially a short hand for:
if (log.isLogLevelEnabled('debug')) log.debug(expensiveThing)
Here's the possible down sides:
- it's possible to forget to return from the function wrapper, in that case the log will omit the data AND you'll have the expensive operation. Using a conditional check, that's not going to happen
- while we don't currently log functions (essentially treating them as
undefined) it will put us into a corner where we won't be able to do anything with functions hence forth. For instance, we could go down a route where we log any properties attached to functions, or we could log meta data about the functions since there's many types of functions now (e.g. generator, async, async generator) - as a debug log for a function that's passed to another function this could be a valid case - there is already a way to do it (as noted) so is the research into ambient perf cost of implementation worth a slight ergonomic improvement? Maybe. It fits our primary goal of high perf logging for this specific case but if the implementation for detection and edge cases etc. becomes an issue then we'd reject the idea. But before you even get to acceptance/rejection based on that analysis, is it worth the cost of that analysis in the first place? Again... Maybe.
I think this adds complexity for very little gain. I'm 👎
I'm with @jsumners
One could write a helper function like
logger.debugLazy = (expensiveComputation: () => unknown) => {
if (log.isLogLevelEnabled('debug')) log.debug(expensiveComputation())
}
// types.d.ts
interface Pino {
debugLazy: (expensiveComputation: () => unknown) => void
}
But that would be problematic with child loggers, wouldn't it? As I see, there is no way to patch the Pino's prototype from the end user's side and call isLogLevelEnabled.
It's easy to wrap a Pino instance. There's no need to mess with its prototype.
Closing due to lack of support from maintainers.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.