You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

63 lines
1.9 KiB

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")
}
}