如何在Node.js中使用log4js在每条日志语句中打印req.user.id
给Express的log4js日志自动添加req.user.id的解决方案
嘿,我来帮你搞定这个需求!先梳理下你当前的使用方式:
你现有的代码结构
路由文件中的用法
var log = require('log4jslogger.js').LOG; log.info('this is log statement');
log4jslogger.js文件内容
var log4js = require('log4js'); log4js.configure(__base + "log4jsconfig.json"); var logger = log4js.getLogger('default'); Object.defineProperty(exports, "LOG", { value : logger, });
log4jsconfig.json配置(补全了缺失的必要部分)
{ "appenders": { "out": { "type": "stdout" }, "default": { "type": "dateFile", "filename": "logs/default", "pattern": "-yyyy-MM-dd.log" } }, "categories": { "default": { "appenders": ["out", "default"], "level": "info" } } }
接下来给你两个实用的方案,按需选择:
方案一:自定义Logger包装器(简单安全)
这个方法不需要修改log4js的全局配置,而是给每个请求创建一个带用户ID的logger实例,完全不用担心请求间的上下文污染。
修改你的log4jslogger.js:
var log4js = require('log4js'); log4js.configure(__base + "log4jsconfig.json"); var baseLogger = log4js.getLogger('default'); // 封装一个创建logger的函数,自动注入当前请求的user id const createLogger = (req) => { // 处理user不存在的情况,给个默认值避免报错 const userId = req?.user?.id || 'unknown-user'; return { info: (message) => baseLogger.info(`[User: ${userId}] ${message}`), warn: (message) => baseLogger.warn(`[User: ${userId}] ${message}`), error: (message) => baseLogger.error(`[User: ${userId}] ${message}`), debug: (message) => baseLogger.debug(`[User: ${userId}] ${message}`) // 如果你用其他日志级别,比如trace、fatal,按需添加即可 }; }; // 保留原有的LOG导出,兼容旧代码 exports.LOG = baseLogger; // 导出新的创建函数供路由使用 exports.createLogger = createLogger;
然后在路由里这样使用:
const { createLogger } = require('./log4jslogger.js'); router.get('/your-path', (req, res) => { const log = createLogger(req); log.info('this is log statement'); // 最终日志输出会是:[User: 123] this is log statement(假设req.user.id是123) res.send('success'); });
方案二:利用log4js上下文(优雅无侵入)
这个方法可以让你完全保留原来的日志写法,通过log4js的上下文功能自动在日志中添加用户ID,适合不想修改现有路由代码的场景。
步骤1:添加Express中间件设置上下文
在你的Express入口文件(比如app.js)里添加一个全局中间件,把当前请求的user id存入log4js的上下文:
const log4js = require('log4js'); // 确保这个中间件在你的认证中间件之后执行,这样req.user才会存在 app.use((req, res, next) => { const userId = req?.user?.id || 'unknown-user'; // 给log4js添加上下文变量userId log4js.addContext('userId', userId); next(); });
步骤2:修改log4js配置文件
更新log4jsconfig.json,在布局pattern中加入%X{userId}来打印上下文里的用户ID:
{ "appenders": { "out": { "type": "stdout", "layout": { "type": "pattern", "pattern": "%d [%p] [User: %X{userId}] %m%n" } }, "default": { "type": "dateFile", "filename": "logs/default", "pattern": "-yyyy-MM-dd.log", "layout": { "type": "pattern", "pattern": "%d [%p] [User: %X{userId}] %m%n" } } }, "categories": { "default": { "appenders": ["out", "default"], "level": "info" } } }
步骤3:继续用原来的方式打日志
不需要修改任何路由代码,直接像以前一样使用:
var log = require('log4jslogger.js').LOG; log.info('this is log statement'); // 日志会自动输出类似:2024-05-20 14:30:00 [INFO] [User: 123] this is log statement
注意点
- 这个方案依赖log4js的异步上下文支持,确保你的log4js版本在2.x及以上(Node.js版本建议8.x+),否则在高并发场景下可能出现用户ID串号的问题。如果担心这个,方案一更稳妥。
内容的提问来源于stack exchange,提问作者Yogesh
相关产品推荐
相关产品推荐

