Access Log 中间件
VextJS 内置 Access Log 中间件,自动记录每个 HTTP 请求的方法、路径、状态码、响应时间和客户端 IP。该中间件基于洋葱模型(after-middleware 模式),在请求处理完成后输出一行紧凑的访问日志。
基本行为
Access Log 中间件默认启用,无需任何配置即可工作:
请求完成后,终端输出类似:
日志格式
Access Log 采用紧凑单行格式,在开发和生产环境下呈现不同的输出样式:
开发模式(Pretty)
当 logger.pretty 为 true(开发环境默认值)时,pino-pretty 会对日志进行着色和格式化:
日志消息本身始终是紧凑的单行文本,格式为:
生产模式(JSON)
当 logger.pretty 为 false(生产环境默认值)时,pino 输出结构化 JSON:
每条日志是一行完整的 JSON 对象,便于 ELK、Loki 等日志收集系统解析。
注意:
requestId字段由 pino mixin + AsyncLocalStorage 自动注入(见下文),无需在 access-log 中间件中手动传入。
requestId 自动注入
工作原理
VextJS 使用 AsyncLocalStorage(Node.js 内置的异步上下文传播机制)为每个请求维护独立的上下文。requestId 中间件在请求进入时生成唯一 ID 并存入 AsyncLocalStorage,后续所有日志输出都会自动携带该 ID。
跨服务追踪
在微服务架构中,requestId 可以通过 HTTP 头传递,实现跨服务的请求链路追踪:
中间件执行位置
Access Log 位于内置中间件链的第 6 位(response-wrapper 之后),确保:
requestId已在之前的中间件中生成(req.requestId可用)- 洋葱回程时 handler 已执行完毕(
res.statusCode已确定)
配置项
通过 config.accessLog 进行配置:
enabled
设为 false 时,中间件直接调用 next(),零开销跳过。
level
设为 'debug' 后,可以在生产环境通过 logger.level 统一控制是否输出访问日志。当 autoLevelUpgrade 启用时,此配置作为基础级别,4xx/5xx 请求会自动提升。
skipPaths
内部使用 Set 实现 O(1) 查找(精确匹配模式)或前缀扫描(前缀匹配模式),不影响性能。
常见用途:排除健康检查、Kubernetes 探针、Prometheus metrics 等高频路径:
skipMode
'exact':路径必须完全匹配(如'/health'只跳过/health,不跳过/health/detail)'prefix':路径前缀匹配(如'/api/internal'会跳过/api/internal、/api/internal/status等)
slowThreshold
响应时间超过此阈值的请求,日志级别自动提升为 warn,并在消息中追加 [SLOW] 标记:
logResponseSize
启用后,日志消息会在 IP 之后追加 Content-Length(如果响应头中存在):
autoLevelUpgrade
启用后的级别映射:
这对生产环境的告警监控非常有用——可以在日志系统中针对 error 级别设置告警规则,自动捕获 5xx 错误。
性能优化
Access Log 中间件在内部做了多项性能优化:
- Set 预计算 —
skipPaths在初始化时转换为Set,查找复杂度 O(1) - 方法预绑定 —
logger.info.bind(logger)在初始化时绑定,避免每次请求的动态查找 - 快速跳过 —
enabled: false时立即return next(),无任何额外开销 - 单行消息 — 使用字符串拼接而非结构化对象,避免 pino-pretty 将字段展开为多行
TypeScript 类型
与日志存储的关系
Access Log 的输出走框架统一的 app.logger(基于 pino),因此所有在 日志文档 中描述的存储方案都适用:
- pino-roll — 按大小/时间轮转到
logs/access.log - Filebeat → ELK — 采集 JSON 日志到 Elasticsearch
- pino-elasticsearch — 直连 Elasticsearch
- Docker → Loki — 容器日志驱动
- stdout → Cloud — 云原生日志管道
如需将 access log 单独存储到独立文件,可使用 pino 多目标 transport 配合日志级别过滤。
下一步
- 了解 日志系统 的完整配置和存储方案
- 查看 配置文档 了解环境覆盖机制
- 了解 requestId 与请求上下文 的工作原理