Node.js Winston:構建工業級的日誌管理與分析系統
在開發階段我們習慣使用 console.log,但在正式環境,我們需要更專業的解決方案:將紀錄 (Logs) 存入磁碟、區分優先等級、並在檔案過大時自動切割。Winston 是 Node.js 生態系中最穩定且功能最強大的日誌框架。
為什麼不用 console.log?
- 等級分明:Winston 支援標準的 RFC5424 等級(error, warn, info, http, verbose, debug, silly),讓你只需輸出當前環境關心的資訊。
- 多重輸出 (Transports):可以同時將日誌印在控制台、存入本地檔案,甚至即時發送到遠端伺服器 (HTTP)。
- 格式化 (Formatting):能輕鬆將日誌轉為 JSON 格式,方便後續對接 ELK (Elasticsearch/Logstash/Kibana) 等分析系統。
安裝與基礎配置
安裝核心套件:npm install winston。
建立 logger.js:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info', // 僅紀錄 info 及以上等級
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.json() // 正式環境建議使用 JSON
),
transports: [
// 專門儲存 Error
new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
// 儲存所有紀錄
new winston.transports.File({ filename: 'logs/combined.log' }),
],
});
// 開發環境加開彩色控制台輸出
if (process.env.NODE_ENV !== 'production') {
logger.add(
new winston.transports.Console({
format: winston.format.combine(winston.format.colorize(), winston.format.simple()),
})
);
}
module.exports = logger;
自動滾動與清理 (Log Rotation)
為了防止日誌檔案無限制增長導致硬碟爆滿,建議搭配 winston-daily-rotate-file 使用:
npm install winston-daily-rotate-file
const DailyRotateFile = require('winston-daily-rotate-file');
const rotateTransport = new DailyRotateFile({
filename: 'logs/application-%DATE%.log',
datePattern: 'YYYY-MM-DD',
zippedArchive: true, // 自動壓縮舊檔案
maxSize: '20m', // 單個檔案最大 20MB
maxFiles: '14d', // 保留最近 14 天的紀錄
});
logger.add(rotateTransport);
實戰建議:結合 Express 的 Morgan
如果你在開發 Web 應用,可以將 Morgan 的 HTTP 存取日誌導向 Winston,實現日誌大一統:
const morgan = require('morgan');
const logger = require('./logger');
app.use(
morgan('combined', {
stream: { write: (message) => logger.info(message.trim()) },
})
);
總結
- Winston 是產品化應用的必備組件。
- 透過 Transports,你可以讓日誌在正確的時間出現在正確的地方(檔案、Slack、雲端)。
- 務必實作 Rotation (滾動) 策略,這是伺服器維運的基本功。