I am using the winston
logging library. I have some objects that I want to log, and before logging them I want to do some transformations. I can manually do the transformations before putting them into the logger, but I want to avoid doing those transformations when the chosen log level is lower than the level that those transformations would appear on. If there is a way to format each individual info object, then I would not waste cpu on extra transformations.
Here is roughly my logger class to understand what I mean:
import * as winston from 'winston'
class Logger {
constructor(logLevel) {
this.logger = createLogger({ level: logLevel })
}
newValues = (valuesWithIds) => {
this.logger.info(valuesWithIds.map(v => v.value))
}
selectedCachedValues = (valuesWithIds) => {
this.logger.info(valuesWithIds.map(v => v.value))
}
downloadComplete = (url, queue) => {
this.logger.info(`${url} complete, ${queue.length} items remaining`)
}
}
const logger = new Logger('error')
// this performs an array map operation that doesnt need to be ran.
logger.newValues([{ id: 1, value: 'a' }, { id: 1, value: 'b' }])
libraries like scala-logging do this sort of thing with macros. I am hoping I can write something as efficient in javascript.
I actually ended up solving my problem with bunyan logger. Bunyan lets you define specific transformations on specific object keys (they refer to them as serializers). I can define certain serializers, and if I log at a level that is above the chosen log level, it will ignore that serializer.
const bunyan = require('bunyan')
const serializers = {
valuesWithIds: vals => vals.map(v => v.value)
}
const logger = bunyan.createLogger({ name: 'root', level: 'error' })
const valuesWithIds = [{ id: 1, value: 'a' }, { id: 1, value: 'b' }]
// logs nothing, doesnt execute the serializer
logger.info({ valuesWithIds }, 'loaded values')
// logs to console, runs the serializer
logger.error({ valuesWithIds }, loaded values')
this produces one line of output:
{"name":"root","hostname":"myhostname","pid":100,"level":30,"valuesWithIds":["a","b"],"msg":"loaded values","time":"2019-01-14T00:05:04.800Z","v":0}