import type { VextMiddleware } from "../../types/middleware.js"; import type { VextAccessLogConfig } from "../../types/app.js"; import type { VextLogger } from "../../types/app.js"; /** * createAccessLogMiddleware — Access Log 中间件工厂 * * 内置中间件 #6(response-wrapper 之后),职责: * 利用洋葱模型 after-middleware 模式,在 `await next()` 前记录请求开始时间, * 在 `await next()` 后记录请求耗时、HTTP 状态码、方法、路径、客户端 IP。 * * 配置项(config.accessLog): * - enabled: 是否启用(默认 true);false 时直接跳过,零开销 * - level: 日志输出级别(默认 'info');可设为 'debug' 由 logger.level 初始阈值或 setLevel() 统一控制 * - skipPaths: 精确匹配跳过的路径列表(如 ['/health', '/ready']),减少日志噪音 * - skipPathPrefixes: 前缀匹配跳过的路径列表(如 ['/internal']),跳过整个路径树 * - slowThreshold: 慢请求阈值(毫秒),超过时自动提升为 warn 级别并标记 [SLOW] * - warnOn4xx: 是否将 4xx 响应提升为 warn 级别(默认 false) * - logResponseSize: 是否在日志中追加 Content-Length(默认 false) * * 执行位置(中间件链注册顺序): * requestId → cors → body-parser → rateLimit → response-wrapper → 【access-log】 * → 插件全局中间件 → 路由级中间件 → validate → handler * * 时序保证: * - requestId 中间件在 access-log 之前执行,req.requestId 已填充 * - 洋葱回程时 handler 已执行完毕,res.statusCode 已确定 * * 日志格式(紧凑单行): * 开发模式(pretty): * [17:53:26.174] INFO: GET / 200 1ms | 127.0.0.1 * [17:53:28.120] ERROR: POST /api/pay 500 312ms | 10.0.0.5 * [17:53:30.500] WARN: GET /api/reports 200 5231ms | 10.0.0.1 [SLOW] * [17:53:31.200] INFO: GET /api/users 200 3ms | 127.0.0.1 [1.2kB] * 生产模式(JSON): * {"level":30,"time":"...","requestId":"...","msg":"GET / 200 1ms | 127.0.0.1"} * {"level":50,"time":"...","requestId":"...","msg":"POST /api/pay 500 312ms | 10.0.0.5"} * * requestId 由 logger mixin(AsyncLocalStorage)自动注入,无需在此重复传入。 * 这样避免了 pretty 模式下将结构化字段展开为多行的问题。 * * @param config Access Log 配置(从 VextConfig.accessLog 提取) * @param logger VextLogger 实例(框架 app.logger) * @returns VextMiddleware */ export declare function createAccessLogMiddleware(config: VextAccessLogConfig, logger: VextLogger): VextMiddleware;