在 Debian 上部署 Node.js 服务后,日志往往很快就会从“能看”变成“难查”:控制台输出混在一起,错误信息不集中,开发环境和生产环境的记录需求也不一样。下面用 winston 做一个最小可用的分类方案,把日志按级别和环境拆开存储,同时保留可继续扩展的配置方式,便于你判断这套做法是否适合当前项目。
为什么要先做日志分类
在 Debian 环境下跑 Node.js 应用时,日志不仅用于实时观察程序状态,还关系到后续排错、问题追踪和日常运维。如果所有内容都混在标准输出里,定位一次错误往往要翻很长一段记录。
更常见的情况是,不同环境对日志的需求并不一样:开发环境希望看到更多上下文,方便调试;生产环境则更强调稳定留档和快速筛查。因此,与其等日志量上来后再补救,不如一开始就把输出目标和记录级别分清楚。
这类需求通常会交给第三方日志库处理,Node.js 里常见的方案就是 winston 或 pino。这里以 winston 为例,因为它对多传输器、多文件输出和格式定制支持比较直接,适合做清晰的分类日志配置。
先准备环境并安装 winston
开始之前,先确认 Debian 系统里已经装好了 Node.js 和 npm。原文里给出的前置条件很简单:如果本机还没有安装,直接从 Node.js 官网完成安装即可。
项目依赖安装命令如下:
npm install winston
这一步完成后,就可以在项目中单独建立一个日志模块,把日志规则集中维护,而不是分散写在业务代码里。
如何配置 logger.js 做到分级和分文件输出
核心做法是创建一个 logger.js 文件,在里面统一定义日志级别、输出格式和传输器。这样主程序只负责调用,不需要关心日志最终写到哪里。

const { createLogger, format, transports } = require('winston');
const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.printf(({ timestamp, level, message }) => {
return `[${timestamp}] ${level.toUpperCase()}: ${message}`;
})
),
transports: [
new transports.Console(),
new transports.File({ filename: 'error.log', level: 'error' }),
new transports.File({ filename: 'combined.log' }),
],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new transports.File({ filename: 'development.log' }));
}
module.exports = logger;
这段配置里有几个关键点:
统一日志级别
level: 'info' 表示记录器默认从 info 级别开始处理日志。实际项目里,这个级别可以继续按需求调整,但这里已经足够覆盖常见的信息和错误输出。

统一日志格式
通过 format.timestamp() 和 format.printf(),每条日志都会带上时间戳、日志级别和消息正文,最终输出格式为:
[时间戳] 级别: 消息内容
这种格式的好处是直接、稳定,既适合开发时阅读,也方便后续按时间线回溯问题。
按目标拆分输出
传输器 transports 决定日志写到哪里。这里一共配置了三个基础输出目标:
new transports.Console():输出到控制台,适合运行时即时查看。new transports.File({ filename: 'error.log', level: 'error' }):只把错误级别日志写入error.log。new transports.File({ filename: 'combined.log' }):把综合日志写入combined.log。
这样一来,错误日志不会再淹没在普通输出中,而综合日志又能保留完整记录,方便后续排查。
按环境增加开发日志
下面这段判断进一步区分了开发环境和生产环境:
if (process.env.NODE_ENV !== 'production') {
logger.add(new transports.File({ filename: 'development.log' }));
}
它的含义很明确:只要当前不是 production,就额外写入一个 development.log。因此,生产环境下保留的是错误日志和综合日志;开发环境则会多出一份开发日志文件,用来承接更完整的调试信息。
在应用里调用并验证日志是否生效
配置完成后,在主应用代码中直接引入这个日志模块即可使用:
const logger = require('./logger');
logger.info('This is an info message');
logger.error('This is an error message');
这种写法的优势在于,业务代码只需要关心记录什么,不需要重复处理时间格式、文件路径或输出分类。日志策略一旦调整,也只需要改 logger.js 一处。
接着运行应用:
node app.js
运行后可以重点检查几件事:
- 控制台是否能看到实时输出;
error.log是否只记录错误日志;combined.log是否保存了综合日志;- 在非生产环境下,是否额外生成了
development.log。
如果这几项都符合预期,就说明 Debian 下的 Node.js 日志分类已经基本搭好了。
这套方案适合什么场景,还能怎么调整
这套配置的价值,不在于功能复杂,而在于先把日志管理从“全都打出来”提升到“能区分、能归档、能扩展”。对于中小型 Node.js 服务来说,这已经能明显改善排错体验。
后续如果项目继续增长,还可以沿着原文提到的几个方向调整:
- 修改日志格式,让字段更适合团队排查习惯;
- 增加或减少输出目标,按需拆分不同文件;
- 调整级别过滤规则,让生产和开发环境的日志粒度更贴合实际需求。
如果你当前的 Debian 部署还停留在简单控制台输出阶段,那么先用 winston 建立这套分类规则,通常就是成本最低、见效也最快的一步。







