Node系列 · ORM:log4js 日志记录

发布时间:2026/8/29 20:15:23
Node系列 · ORM:log4js 日志记录 Node系列 · ORMlog4js 日志记录生产环境不能用console.log——它没法分级别、没法分类、没法按大小切分文件、没法自动清理。本章讲清楚log4js的核心概念和按环境配置的实战。一、为什么不用console.log维度console.loglog4js级别控制❌✅ trace / debug / info / warn / error / fatal分类❌✅ category按模块拆分日志输出目标仅 stdout✅ 控制台 / 文件 / 网络 / 数据库文件切分❌✅ 按大小 / 日期自动清理❌✅log4js自动管理性能阻塞 stdout异步缓冲不阻塞事件循环::: tipconsole.log永远不是生产日志方案。它没法分类、没法分级、还会在高并发下阻塞事件循环stdout 同步写入。:::二、log4js 三大核心概念2.1 级别level从低到高级别用途trace最详细的调试信息一般关闭debug调试信息info正常运行日志warn警告潜在问题error错误功能受影响fatal致命进程退出设置level: warn后只有 warn / error / fatal 会输出。2.2 分类category按模块 / 功能划分的日志命名空间log4js.getLogger(http); // HTTP 请求日志 log4js.getLogger(db); // 数据库日志 log4js.getLogger(user); // 用户模块日志 log4js.getLogger(default); // 默认日志不分类时用每个 category 可以单独配置级别和输出目标。2.3 输出源appender日志写到哪里appender 类型输出目标console控制台 stdout / stderrfile单个文件dateFile按日期切分如app.2024-08-15.logfileSync同步写文件启动期用tcp远程日志服务器gelfGraylog 扩展日志格式每个 appender 还可指定layout输出格式layout格式pattern自定义模板字符串colored带 ANSI 颜色开发用jsonJSON 格式机器解析三、安装与基础使用npminstalllog4jsconst log4js require(log4js); log4js.configure({ appenders: { console: { type: console } }, categories: { default: { appenders: [console], level: info } }, }); const logger log4js.getLogger(); logger.info(服务启动); logger.warn(配置项缺失); logger.error(请求失败, err);$nodeapp.js[2024-08-15T14:30:00.000][INFO]default - 服务启动四、按环境配置4.1 配置代码const path require(path); const log4js require(log4js); const isDev process.env.NODE_ENV ! production; log4js.configure({ appenders: { // 控制台开发期彩色 consoleOut: { type: console, layout: { type: colored }, }, // 按日期切分文件 appFile: { type: dateFile, filename: path.join(logs, app.log), pattern: yyyy-MM-dd, // 文件名格式app.2024-08-15.log compress: true, }, // 错误单独一个文件 errorFile: { type: file, filename: path.join(logs, error.log), // 旧文件超 10MB 自动备份 maxLogSize: 10 * 1024 * 1024, backups: 5, }, }, categories: { default: { appenders: isDev ? [consoleOut] : [appFile, errorFile], level: isDev ? debug : info, }, http: { appenders: [appFile], level: info, }, db: { appenders: [appFile], level: warn, }, }, }); module.exports log4js;4.2 各级别模块用不同 loggerconst log4js require(log4js); const httpLogger log4js.getLogger(http); const dbLogger log4js.getLogger(db); httpLogger.info(GET /api/users 200); dbLogger.warn(慢查询耗时 1200ms);五、Express 中间件log4js提供 Express 中间件自动记录请求const log4js require(log4js); const express require(express); const app express(); // 自动记录每个 HTTP 请求 app.use(log4js.connectLogger(log4js.getLogger(http), { level: auto, // 5xx → error4xx → warn其他 → info format: (req, res, format) format( :remote-addr - :method :url :status :res[content-length] - :response-time ms ), })); app.get(/api/users, (req, res) { res.json({ users: [] }); });输出示例[INFO] http - 127.0.0.1 - GET /api/users 200 42 - 12 ms [ERROR] http - 127.0.0.1 - POST /api/users 500 89 - 234 ms六、关闭与刷新// 应用退出前优雅关闭 process.on(SIGTERM, () { log4js.shutdown(() { console.log(日志系统已关闭); process.exit(0); }); });shutdown()等待所有缓冲日志写完再回调——避免最后几条日志丢失。七、配置模板// config/log4js.js const path require(path); const log4js require(log4js); const LOG_DIR path.resolve(__dirname, ../logs); const isDev process.env.NODE_ENV ! production; log4js.configure({ appenders: { // 开发期控制台彩色输出 devConsole: { type: console, layout: { type: colored }, }, // 生产期分文件 错误单独 prodAll: { type: dateFile, filename: path.join(LOG_DIR, app.log), pattern: yyyy-MM-dd, compress: true, }, prodError: { type: levelFilter, // level: error 之后的级别都写这个文件 appender: { type: file, filename: path.join(LOG_DIR, error.log), maxLogSize: 10 * 1024 * 1024, backups: 5, }, level: error, }, }, categories: { default: { appenders: isDev ? [devConsole] : [prodAll, prodError], level: isDev ? debug : info, }, http: { appenders: isDev ? [devConsole] : [prodAll], level: info, }, db: { appenders: isDev ? [devConsole] : [prodAll], level: warn, }, }, }); module.exports log4js;八、最佳实践场景推荐开发期控制台 level: debug生产期文件 错误单独 level: infoHTTP 请求connectLogger自动记录慢查询 / 错误单独 category level: warn敏感字段日志前脱敏密码、token、手机号中间四位应用退出log4js.shutdown刷写缓冲文件清理dateFilecompress: true自动管理::: warning永远不要把密码、token、完整手机号、身份证号写日志。即使是错误日志也要先脱敏logger.info(登录失败, { email: user.email, ip: req.ip }); // ❌ logger.info(登录失败, { password }); // 永远不要:::九、与其他日志库对比库风格性能适合log4js配置式中同步阻塞风险用 stream 解决传统项目 / 文件输出pinoJSON 输出极快异步性能敏感 / 日志聚合winston配置式中老牌项目bunyanJSON 输出快微服务 / 日志聚合::: tip新项目推荐 pino——JSON 输出 异步 不阻塞事件循环 易聚合到 ELK / Loki。但 log4js 在国内中小项目里依然主流本文按 log4js 展开。:::十、小结生产环境永远用日志库不用console.log三大核心level级别/ category分类/ appender输出源dateFileappender 按日期切分日志filemaxLogSize按大小按环境配置开发期控制台 debug生产期文件 infoExpress 用connectLogger自动记录请求日志敏感字段永远不写日志密码、token 等应用退出前log4js.shutdown()刷写缓冲