winston 以不同方式格式化信息对象

winston format info objects differently

我正在使用 winston 日志库。我有一些要记录的对象,在记录它们之前我想做一些转换。我可以在将它们放入记录器之前手动进行转换,但我想避免在所选日志级别低于这些转换将出现的级别时进行这些转换。如果有办法 format each individual info object,那么我不会浪费 cpu 进行额外的转换。

这里是我的记录器的粗略class来理解我的意思:

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' }])

scala-logging 这样的库使用宏来做这种事情。我希望我能在 javascript.

中写出同样高效的东西

我有同样的情况,但有指标。我开发了一些基于代理的陷阱。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

我实际上最终用 bunyan logger. Bunyan lets you define specific transformations on specific object keys (they refer to them as serializers 解决了我的问题。我可以定义某些序列化程序,如果我以高于所选日志级别的级别登录,它将忽略该序列化程序。

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')

这会产生一行输出:

{"name":"root","hostname":"myhostname","pid":100,"level":30,"valuesWithIds":["a","b"],"msg":"loaded values","time":"2019-01-14T00:05:04.800Z","v":0}