Node系列 · Express:log4js 日志记录
Express 项目接 log4js 的最小可用配置——HTTP 请求自动日志、按环境差异化(开发控制台 / 生产文件)、错误单独归档。
一、安装与最简配置
bash
npm install log4jsjavascript
const log4js = require('log4js');
log4js.configure({
appenders: { console: { type: 'console' } },
categories: { default: { appenders: ['console'], level: 'debug' } },
});
const logger = log4js.getLogger();
logger.info('Express 服务启动');二、HTTP 请求日志:connectLogger
javascript
const log4js = require('log4js');
log4js.configure({
appenders: {
httpAccess: {
type: 'console',
layout: { type: 'colored' },
},
},
categories: {
http: { appenders: ['httpAccess'], level: 'info' },
default: { appenders: ['httpAccess'], level: 'info' },
},
});
app.use(log4js.connectLogger(log4js.getLogger('http'), {
level: 'auto', // 5xx → error;4xx → warn;其他 → info
}));输出示例:
[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 mslevel | 行为 |
|---|---|
auto | 自动按 HTTP 状态码分级 |
info | 全部 info |
warn | 仅 warn / error |
三、生产环境完整配置
javascript
const path = require('path');
const log4js = require('log4js');
const isDev = process.env.NODE_ENV !== 'production';
const LOG_DIR = path.resolve(__dirname, '../logs');
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,
keepFileExt: true,
},
// 生产:错误单独归档(按大小轮转)
prodError: {
type: 'logLevelFilter',
level: 'error',
appender: {
type: 'file',
filename: path.join(LOG_DIR, 'error.log'),
maxLogSize: 10 * 1024 * 1024, // 10MB
backups: 5, // 保留 5 个备份
},
},
},
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',
},
auth: {
appenders: isDev ? ['devConsole'] : ['prodAll', 'prodError'],
level: 'info',
},
},
});
module.exports = log4js;四、按模块用不同 logger
javascript
const log4js = require('./config/log4js');
const httpLogger = log4js.getLogger('http');
const dbLogger = log4js.getLogger('db');
const authLogger = log4js.getLogger('auth');
httpLogger.info('GET /api/users 200');
dbLogger.warn('慢查询:耗时 1200ms');
authLogger.info('用户登录', { userId: 1, ip: req.ip });不同 category 写到不同文件 / 不同级别,方便按模块排查问题。
五、错误日志单独归档
生产环境建议错误单独写一个文件,方便快速排查:
javascript
// appenders.prodError 的 level: 'error' 表示只接收 error 及以上级别
// 普通 info / warn 不会写到 error.log,只在 app.log
logger.error('数据库连接失败', err); // 写到 app.log + error.log
logger.info('用户登录成功'); // 只写到 app.log六、应用退出时优雅关闭
javascript
// 应用退出前刷写所有缓冲日志
process.on('SIGTERM', () => {
log4js.shutdown(() => {
console.log('日志系统已关闭');
process.exit(0);
});
});不调 shutdown() 可能丢失最后几条日志——尤其用了 fileSync / 异步 appender 时。
七、自定义日志格式
javascript
log4js.configure({
appenders: {
custom: {
type: 'console',
layout: {
type: 'pattern',
pattern: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%p] %c - %m%n',
},
},
},
categories: { default: { appenders: ['custom'], level: 'info' } },
});| 占位符 | 含义 |
|---|---|
%d | 时间戳 |
%p | 级别(INFO / ERROR) |
%c | 分类 |
%m | 消息 |
%n | 换行 |
%x | 自定义上下文(如请求 ID) |
八、最佳实践
| 场景 | 推荐 |
|---|---|
| 开发 | 控制台彩色 + level: 'debug' |
| 生产 | 文件按日期切分 + 错误单独 + level: 'info' |
| HTTP 请求 | connectLogger + level auto |
| 多模块 | 按 category 拆分(http / db / auth) |
| 敏感字段 | 永远不记密码、token、身份证号 |
| 应用退出 | log4js.shutdown() 刷写缓冲 |
| 日志归档 | dateFile + compress: true 自动管理 |
九、小结
- Express 接 log4js:
configure()+app.use(connectLogger()) - 按环境分:开发控制台 + debug;生产文件 + info
- 错误单独归档:
logLevelFilter+level: 'error' - 按模块 category 拆分日志(
http/db/auth) - 应用退出
log4js.shutdown()刷写缓冲 - 敏感字段(密码 / token)永远不记日志
