我有一个函数,它使用传递给它的bunyan记录器进行日志记录。
全局日志记录器在整个应用程序中使用,为许多组件提供日志记录工具。这样我们就有了一个集中的日志。大多数情况下,我们只是将这个全局记录器传递给所有需要它的函数。
然而,在某些情况下,当我调用上述函数时,我希望能够访问由该函数调用编写的日志,但同时我希望保持标准的日志记录行为(例如,将日志写入集中式日志),因此我不能只是将一个新的记录器实例传递给它。
用bunyan解决这个问题的最好方法是什么?
代码应该看起来像这样:
const funcCallLogger = globalLogger.cloneSomehow();
doSomeWork(funcCallLogger).then(() => {
const logs = funcCallLogger.getWritenLogs();
// logs should be an array of all logs written to funcCallLogger
// at the same time all logs written to funcCallLogger must also be
// reflected in globalLogger
});
function doSomeWork (logger) {
logger.info('Doing some work...');
await ...
}我在考虑创建子日志记录器,并为其分配一个自定义流以进行日志收集,但我不确定这是否是最好的解决方案。
发布于 2018-01-10 07:54:20
我决定创建子日志记录器,并将其配置为使用自定义可写流,以便收集和处理写入其中的所有日志条目。这样,子日志记录器中的所有日志都会流向全局日志记录器(所以这不会破坏正常的日志记录行为),同时我还可以收集流向这个自定义实例的日志。
以下是示例代码:
import * as stream from 'stream';
export class LogAccumulatingStream extends stream.Writable {
private logs: string[] = [];
public _write (chunk: any, encoding: string, callback: Function): void {
this.logs.push(chunk.toString());
callback();
}
public getLogs (): string[] {
return this.logs;
}
}下面是我如何运行它:
const childLogger = globalLogger.child({
component: 'SomeWorker'
});
const logsAccumulator = new LogAccumulatingStream();
const stream = new PrettyStream({ useColor: false });
stream.pipe(logsAccumulator);
childLogger.addStream({
level: 'debug',
type: 'raw',
stream
});
await someWorker.run(childLogger);
const workerLogs = logsAccumulator.getLogs();我使用PrettyStream将日志格式化为字符串,然后通过管道将其传送到我的LogAccumulatingStream,但如果需要,您可以直接使用LogAccumulatingStream,只需重写它来处理对象而不是字符串。
我不确定这是否是最好的解决方案,所以非常欢迎评论和进一步的回答。
https://stackoverflow.com/questions/48176633
复制相似问题