Skip to content

morgan

[TOC]

索引

General

  • morgan()(format, options?),用于创建一个 HTTP 请求日志中间件,并根据传入的参数配置日志格式、输出方式等行为。

方法/属性

General

morgan()

morgan()(format, options?),用于创建一个 HTTP 请求日志中间件,并根据传入的参数配置日志格式、输出方式等行为。

  • morgan()(format, options),完整语法(指定格式 + 选项)。

  • morgan()(format),简化语法(仅指定格式,使用默认选项)。

  • morgan()(options),特殊情况(仅指定选项,格式使用默认值 'default')。

    • formatstring|Function,用于定义日志格式,支持 字符串函数 两种类型。

      • 字符串:字符串可以是 内置格式名称自定义格式字符串

      • 函数(tokens,req,res)=>string,可传入一个函数动态生成日志内容。

        • tokens:包含所有占位符对应的工具函数(如 tokens.method(req, res) 可获取请求方法)。
    • options?object配置选项,用于控制日志的输出方式、过滤规则等。

      • streamstream.Writable默认:process.stdout(控制台),日志的输出流(如文件流、控制台)。用于将日志写入文件或其他目的地。

      • skip(req,res)=>boolean默认:undefined,过滤函数。

        • 返回 true 则跳过当前请求的日志记录,

        • 返回 false 则记录。

      • immediateboolean默认:false,日志记录时机。

        • 返回 false(默认)在响应发送后记录(可获取响应状态码等);

        • 返回 true 在请求到达时立即记录(无法获取响应信息)。

      • prettifyboolean默认:false,(已废弃)是否美化 JSON 格式日志,最新版本建议手动处理。

  • 返回:

  • middleware(req,res,next)=>void,返回一个 Express 中间件函数

示例

  1. 使用内置的 'dev' 格式

    js
    app.use(morgan('dev'));  // 使用内置的 'dev' 格式
  2. 自定义格式:时间 + 方法 + URL + 状态码 + 响应时间

    js
    // 自定义格式:时间 + 方法 + URL + 状态码 + 响应时间
    app.use(morgan(':date[iso] :method :url :status :response-time ms'));
  3. 自定义函数:根据状态码动态调整日志前缀(成功用绿色,错误用红色)

    js
    // 自定义函数:根据状态码动态调整日志前缀(成功用绿色,错误用红色)
    app.use(morgan((tokens, req, res) => {
      const status = tokens.status(req, res);
      const prefix = status >= 400 ? '\x1b[31m' : '\x1b[32m'; // 红色(错误)/绿色(成功)
      return `${prefix}[${tokens.date(req, res, 'iso')}] ${tokens.method(req, res)} ${tokens.url(req, res)} ${status} \x1b[0m`;
    }));
  4. 将日志写入文件(配置 stream

    js
    const fs = require('fs');
    const logStream = fs.createWriteStream('access.log', { flags: 'a' });
    app.use(morgan('combined', { stream: logStream })); // 日志写入 access.log
  5. 过滤静态资源请求(配置 skip

    js
    app.use(morgan('dev', {
      skip: (req, res) => {
        // 跳过所有静态资源(/public 路径下的请求)
        return req.originalUrl.startsWith('/public');
      }
    }));
  6. 请求到达时立即记录日志(配置 immediate

    javascript
    app.use(morgan('dev', { immediate: true })); // 不等待响应,请求一来就记录

基本使用

介绍 morgan

morgan:是 Express 生态中最常用的 HTTP 请求日志中间件核心作用是自动记录客户端发起的每一次 HTTP 请求细节(如请求方法、URL、响应时间等),帮助开发者调试问题、监控服务运行状态。

核心定位与价值

  1. 调试辅助

    开发阶段,通过日志快速定位请求异常(如 404/500 错误对应的 URL、参数)。

  2. 服务监控

    生产阶段,记录请求量、响应时间、客户端 IP 等数据,用于分析服务负载和用户行为。

安装

在 Express 项目根目录执行命令,安装 morgan:

sh
npm i morgan

基本示例

  1. 在项目入口文件(如 app.js)中引入并使用,默认会将日志输出到 控制台

    js
    // 1. 引入 express 和 morgan
    const express = require('express');
    const morgan = require('morgan');
    const app = express();
    
    // 2. 挂载 morgan 中间件(指定日志格式为 'dev',适合开发环境)
    app.use(morgan('dev'));
    
    // 3. 定义测试路由
    app.get('/', (req, res) => {
      res.send('Hello Morgan!');
    });
    
    // 启动服务
    app.listen(3000, () => {
      console.log('Server running on port 3000');
    });
  2. 启动服务后,访问 http://localhost:3000,控制台会输出类似日志:

    sh
    GET / 200 3.245 ms - 13

日志格式

morgan 支持多种日志格式,可通过参数指定,分为 内置格式自定义格式 两类。

内置格式(常用)

内置格式已预设好日志内容,直接使用即可,适合大多数场景。

格式名称特点适用场景日志示例
dev简洁格式,包含核心信息(方法、URL、状态码、响应时间、响应大小)开发环境GET / 200 3.245 ms - 13
combined完整格式,包含客户端 IP、时间、Referer、User-Agent生产环境(需详细日志)127.0.0.1 - - [10/Oct/2024:10:00:00 +0800] "GET / HTTP/1.1" 200 13 "http://localhost/" "Chrome/118.0.0.0"
common基础格式,比 combined 少 Referer 和 User-Agent生产环境(简化日志)127.0.0.1 - - [10/Oct/2024:10:00:00 +0800] "GET / HTTP/1.1" 200 13
short简短格式,包含客户端 IP、方法、URL、状态码、响应时间、响应大小快速查看关键信息127.0.0.1 GET / 200 13 - 3.245 ms
tiny极简格式,仅包含方法、URL、状态码仅需最基础日志GET / 200

自定义格式

若内置格式不满足需求,可通过 “格式字符串” 自定义日志内容,核心是使用 morgan 提供的 占位符(以 : 开头)。

常用占位符

  • :method:HTTP 请求方法(GET、POST 等)
  • :url:请求的 URL 路径
  • :status:HTTP 响应状态码(200、404、500 等)
  • :response-time:响应时间(单位:毫秒)
  • :remote-addr:客户端 IP 地址
  • :date[format]:请求时间(格式可自定义,如 :date[iso] 为 ISO 标准时间)
  • :res[content-length]:响应体大小

示例:自定义格式

js
// 自定义格式字符串
app.use(morgan(':date[iso] :method :url :status :response-time ms'));

// 输出日志示例
// 2024-10-10T02:00:00.000Z GET / 200 3.245 ms

日志写入文件

默认情况下,morgan 会将日志输出到控制台(process.stdout),但生产环境中通常需要将日志写入文件,或过滤不必要的请求日志(如静态资源请求)。

js
const express = require('express');
const morgan = require('morgan');
const fs = require('fs');
const path = require('path');
const app = express();

// 1. 创建日志写入流(append 模式,避免覆盖历史日志)
const accessLogStream = fs.createWriteStream(
  path.join(__dirname, 'access.log'),  // 日志文件路径
  { flags: 'a' }  // flags: 'a' 表示“追加写入”
);

// 2. 指定日志格式为 'combined',并输出到文件流
app.use(morgan('combined', { stream: accessLogStream }));

// 测试路由
app.get('/', (req, res) => {
  res.send('Log to file!');
});

app.listen(3000);

日志过滤

通过 skip 选项,可跳过不需要记录的请求(如排除静态资源、特定 URL 的请求)。

示例:不记录静态资源

js
app.use(morgan('dev', {
  skip: (req, res) => {
    // 若请求路径以 /public 开头,则跳过日志记录
    return req.originalUrl.startsWith('/public');
  }
}));

按环境切换配置

开发环境中输出到控制台,生产环境中写入文件,可通过 process.env.NODE_ENV 区分环境。

js
const app = express();

if (process.env.NODE_ENV === 'development') {
  // 开发环境:输出到控制台,使用 dev 格式
  app.use(morgan('dev'));
} else {
  // 生产环境:写入文件,使用 combined 格式
  const accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
  app.use(morgan('combined', { stream: accessLogStream }));
}