import { logger } from "@/logger" // 静态资源扩展名列表 const staticExts = [".css", ".js", ".png", ".jpg", ".jpeg", ".gif", ".ico", ".svg", ".map", ".woff", ".woff2", ".ttf", ".eot"] function isStaticResource(path) { return staticExts.some(ext => path.endsWith(ext)) } /** * 响应时间记录中间件 * @param {Object} ctx - Koa上下文对象 * @param {Function} next - Koa中间件链函数 */ export default async (ctx, next) => { if (isStaticResource(ctx.path)) { await next() return } if (!ctx.path.includes("/api")) { const start = Date.now() await next() const ms = Date.now() - start ctx.set("X-Response-Time", `${ms}ms`) if (ms > 500) { logger.info(`${ctx.path} | ⏱️ ${ms}ms`) } return } // API日志记录 const start = Date.now() await next() const ms = Date.now() - start ctx.set("X-Response-Time", `${ms}ms`) const Threshold = 0 if (ms > Threshold) { logger.info("====================[➡️REQ]====================") // 用户信息(假设ctx.state.user存在) const user = ctx.state && ctx.state.user ? ctx.state.user : null // IP const ip = ctx.ip || ctx.request.ip || ctx.headers["x-forwarded-for"] || ctx.req.connection.remoteAddress // 请求参数 const params = { query: ctx.query, body: ctx.request.body, } // 响应状态码 const status = ctx.status // 组装日志对象 const logObj = { method: ctx.method, path: ctx.path, url: ctx.url, user: user ? { id: user.id, username: user.username } : null, ip, params, status, ms, } logger.info(JSON.stringify(logObj, null, 2)) logger.info("====================[⬅️END]====================\n") } }