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