先前曾总结了2篇文章(见:《log4js按分类和日期存储为多文件问题》和《使用定时任务解决log4js的按日期存储问题》)描述如何解决log4js
的按日期存储问题,然而,通过日志可以发现,前述方案虽然解决了操作日志的按日期存储问题,却并没有解决通过log4js.connectLogger
中间件方式产生的访问日志的按日期存储问题。
即,下述代码产生的访问日志并没有按日期分开存储:
typescriptCopy code- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
app.use(
log4js.connectLogger(logger, {
level: LogLevel.INFO,
format: (req, res, format) => {
return format(
':remote-addr - :method :status HTTP/:http-version :url - [:response-time ms/:content-length B] ":referrer" ":user-agent"'
);
}
})
);
app.use(
log4js.connectLogger(logger, {
level: LogLevel.INFO,
format: (req, res, format) => {
return format(
':remote-addr - :method :status HTTP/:http-version :url - [:response-time ms/:content-length B] ":referrer" ":user-agent"'
);
}
})
);
查看该中间件的源码可以发现,前述方案的定时任务中每日更新的context
并没有对其生效,也即,访问日志仍是在系统启动时的context
中。因此,解决方案似乎也很清晰了,将logger
对象改为动态获取。如下:
typescriptCopy code- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
getAccessLogger(updateContext = false) {
const logger = this.loggers[LoggerName.ACCESS];
if (updateContext) {
logger.clearContext();
logger.addContext(this.loggerContextKey, moment().format('YYYY-MM-DD'));
}
return logger;
}
getAccessLogger(updateContext = false) {
const logger = this.loggers[LoggerName.ACCESS];
if (updateContext) {
logger.clearContext();
logger.addContext(this.loggerContextKey, moment().format('YYYY-MM-DD'));
}
return logger;
}
然而,事实证明,还是想得太简单了,该方法仍然无效。由此可见,对于通过app.use
方式使用的中间件,仅被“实例化”一次,系统启动后,不会再更新。
因此,需要另想办法……
一个很自然的想法是,为何不直接采用Nest.js方式的中间件呢?于是,有了下述方案: