Node.js中Morgan与Winston日志如何打印文件方法及行号
实现Node.js中类似log4j格式的日志(含文件、方法、行号)
要实现包含文件、方法和行号的日志输出,核心是解析Node.js的调用栈信息,再结合日志库自定义格式。以下是具体实现方案:
1. 安装依赖
使用winston作为日志核心库,执行安装命令:
npm install winston
2. 编写日志工具类
创建logger.js文件,实现调用栈解析和日志格式化:
const winston = require('winston'); // 解析调用栈,提取调用方的文件、方法、行号 function getCallerDetails() { const stackLines = new Error().stack.split('\n'); // 跳过当前函数、winston内部调用,定位到业务代码调用层(索引需根据实际测试调整) const targetLine = stackLines[3]; if (!targetLine) return { file: 'unknown', method: 'unknown', line: '0' }; // 匹配调用栈行的格式:at [方法名] ([文件路径]:行号:列号) const matchResult = targetLine.match(/at\s+(.*?)\s+\((.*?):(\d+):\d+\)/); if (!matchResult) return { file: 'unknown', method: 'unknown', line: '0' }; return { method: matchResult[1], file: matchResult[2].split('/').pop(), // 仅保留文件名,去掉全路径 line: matchResult[3] }; } // 配置winston日志实例 const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.printf(({ timestamp, level, message }) => { const { file, method, line } = getCallerDetails(); return `${timestamp} [${level.toUpperCase()}] ${file}:${line} - ${method} - ${message}`; }) ), transports: [ new winston.transports.Console(), // 控制台输出 // 可选:添加文件日志输出 // new winston.transports.File({ filename: 'app.log', maxsize: 5242880 }) ] }); module.exports = logger;
3. 使用日志工具
在业务代码中引入并调用:
const logger = require('./logger'); function userLogin(userId) { logger.info(`用户 ${userId} 登录成功`); } userLogin('12345');
运行后会输出类似:
2024-05-20 14:30:00 [INFO] app.js:8 - userLogin - 用户 12345 登录成功
注意事项
- 调用栈索引:
stackLines[3]的索引可能因环境(比如是否用ES模块、日志库版本)变化,若获取不到正确信息,可尝试调整为stackLines[2]或stackLines[4]。 - 若结合express-morgan-winston使用,需调整
getCallerDetails中的栈索引,因为morgan的调用层级会增加,需要多跳过几层栈信息。 - 性能考虑:解析调用栈会有一定性能开销,生产环境若对性能敏感,可仅在debug级别启用行号输出。
内容的提问来源于stack exchange,提问作者dinu0101
相关产品推荐
相关产品推荐

