Node.js中如何实现不同环境的日志分级输出?

Air-保霞 阅读 21

最近在维护一个Node.js项目,需要根据环境(dev/test/prod)动态调整日志级别。之前用硬编码的if判断环境变量,发现代码重复严重,而且生产环境偶尔会漏掉敏感日志。

尝试用winston库配置了多transport,但遇到问题:UnhandledPromiseRejectionWarning: Error: Invalid transport configuration。我的配置是这样的:


const env = process.env.NODE_ENV || 'development';
const logger = winston.createLogger({
  level: env === 'production' ? 'error' : 'debug',
  transports: [
    new winston.transports.Console({
      level: env === 'test' ? 'info' : level  // 这里可能出错了?
    })
  ]
});

调试时发现测试环境的日志级别没有生效,生产环境却输出了debug信息。有没有更好的实践方法来管理不同环境的日志配置?

我来解答 赞 10 收藏
二维码
手机扫码查看
1 条解答
小紫瑶
小紫瑶 Lv1
你这个问题主要是配置方式不够清晰,而且动态调整日志级别的逻辑有点混乱。我们可以通过更结构化的方式来管理不同环境的日志配置。

首先说一下问题所在:你在transports.Console里用了level变量,但这个变量根本没有定义,导致配置无效。另外,直接在代码里写一堆条件判断会让维护变得很麻烦,建议把环境相关的配置抽离出来。

一个更好的实践是用单独的配置对象来管理不同环境的日志级别,然后根据环境变量动态加载对应的配置。下面是改进后的代码:

const winston = require('winston');

// 定义不同环境的日志配置
const logConfig = {
development: {
consoleLevel: 'debug'
},
test: {
consoleLevel: 'info'
},
production: {
consoleLevel: 'error'
}
};

// 获取当前环境,默认是development
const env = process.env.NODE_ENV || 'development';

// 创建logger实例
const logger = winston.createLogger({
level: 'debug', // 这里设置为最低级别,具体控制交给transport
transports: [
new winston.transports.Console({
level: logConfig[env].consoleLevel // 动态加载对应环境的级别
})
]
});

module.exports = logger;


这样做的好处是:
1. 配置集中管理,以后如果要改日志级别,只需要调整logConfig对象即可。
2. 避免了硬编码和重复的条件判断,代码更清晰。
3. level字段明确指定了每个环境的日志输出规则,不会再出现生产环境漏敏感日志的问题。

如果你还需要支持文件日志或者其他transport,可以继续扩展logConfig。比如:

const logConfig = {
development: {
consoleLevel: 'debug',
fileLevel: 'info'
},
test: {
consoleLevel: 'info',
fileLevel: 'warn'
},
production: {
consoleLevel: 'error',
fileLevel: 'error'
}
};

const logger = winston.createLogger({
level: 'debug',
transports: [
new winston.transports.Console({
level: logConfig[env].consoleLevel
}),
new winston.transports.File({
filename: 'app.log',
level: logConfig[env].fileLevel
})
]
});


最后提醒一下,服务端的日志管理一定要注意性能开销,尤其是生产环境。不要把所有日志都输出到文件或者远程服务,分级输出是个好习惯。另外记得定期清理日志文件,不然服务器磁盘迟早会被撑爆。

希望这能解决你的问题,有问题再讨论。
点赞 4
2026-02-15 15:00