文章目录
- 介绍一下`morgan`和`winston`的区别
- morgan
- 功能
- 优势:
- winston
- 功能
- 优势
- 选择
- 代码示例
介绍一下morgan
和winston
的区别
morgan
功能
morgan 是一个 HTTP 请求日志中间件,专门用于记录 Express 应用的 HTTP 请求日志。它简单易用,提供多种预定义的日志格式,能够自动记录每个 HTTP 请求的详细信息,如请求方法、URL、响应时间等。
优势:
- 专注于 HTTP 请求日志:morgan 专门用于记录 HTTP 请求日志,能够自动记录和格式化 HTTP 请求信息。
- 易于集成:morgan 是 Express 的中间件,集成非常方便。
- 标准化输出:morgan 提供的多种日志格式(如 combined, common, dev 等)标准化了日志输出,使其易于阅读和分析。
winston
功能
winston 是一个通用的日志库,支持灵活的配置和多种传输方式(如控制台输出、文件存储、HTTP 传输等)。它适用于记录应用程序的各种日志,包括信息日志、错误日志、调试日志等。
优势
- 通用日志记录:winston 适用于记录各种类型的日志,不限于 HTTP 请求日志。
- 灵活配置:winston 支持自定义格式、不同级别的日志、多个传输方式等,灵活性很高。
- 日志管理:通过配置 DailyRotateFile 等插件,winston 可以实现日志文件的自动轮换、压缩和删除,便于日志管理。
选择
morgan
:专注于 HTTP 请求日志,简单易用,适合作为 Express 中间件记录请求日志winston
: 提供灵活的日志记录和管理功能,适用于记录应用程序的各种日志- 所以结合使用才是最佳解
代码示例
安装3个依赖
npm install morgan winston winston-daily-rotate-file
这里还有一个winston-daily-rotate-file
目的是为了将每天的日志放入不同的文件,防止文件过大,并且会将老日志进行打包压缩
const express = require("express");
const morgan = require("morgan");
const path = require("path");
const fsExtra = require("fs-extra");
const winston = require("winston");
const DailyRotateFile = require("winston-daily-rotate-file");const app = express();// 日志目录路径
const logDirectory = path.join(__dirname, "logs");// 确保日志目录存在
fsExtra.ensureDirSync(logDirectory);// 配置 winston
const logger = winston.createLogger({level: "info",format: winston.format.combine(winston.format.timestamp(),winston.format.json()),transports: [new winston.transports.Console(),new DailyRotateFile({filename: path.join(logDirectory, "application-%DATE%.log"),datePattern: "YYYY-MM-DD",zippedArchive: true,maxSize: "20m",maxFiles: "14d",}),],
});// 使用 morgan 记录 HTTP 请求到日志文件,并重定向到 winston
app.use(morgan("combined", {stream: {write: (message) => logger.info(message.trim()),},})
);// 示例路由
app.get("/", (req, res) => {res.send("Hello, world!");
});// 错误处理
app.use(function (err, req, res, next) {// set locals, only providing error in developmentres.locals.message = err.message;res.locals.error = req.app.get("env") === "development" ? err : {};logger.error({url: req.url,body: req.body,error: err.message,stack: err.stack,});// render the error pageres.status(err.status || 500);res.send({code: 500,msg: err.message,});
});// 启动服务器
const port = 3000;
app.listen(port, () => {logger.info(`Server is running on port ${port}`);
});
注意
:如果记录 http 请求的话,需要把日志部分的注册放到路由拦截之前