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.
84 lines
2.2 KiB
84 lines
2.2 KiB
/**
|
|
* 响应时间统计中间件
|
|
* 记录请求响应时间并进行日志记录
|
|
*/
|
|
|
|
import LoggerProvider from '../../../app/providers/LoggerProvider.js'
|
|
|
|
const logger = LoggerProvider.getLogger('request')
|
|
|
|
// 静态资源扩展名列表
|
|
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))
|
|
}
|
|
|
|
/**
|
|
* 格式化请求日志
|
|
*/
|
|
function formatRequestLog(ctx, ms) {
|
|
const user = ctx.state?.user || null
|
|
const ip = ctx.ip || ctx.request.ip || ctx.headers["x-forwarded-for"] || ctx.req.connection.remoteAddress
|
|
|
|
return {
|
|
timestamp: new Date().toISOString(),
|
|
method: ctx.method,
|
|
path: ctx.path,
|
|
url: ctx.url,
|
|
userAgent: ctx.headers['user-agent'],
|
|
user: user ? { id: user.id, username: user.username } : null,
|
|
ip,
|
|
params: {
|
|
query: ctx.query,
|
|
body: ctx.request.body
|
|
},
|
|
status: ctx.status,
|
|
responseTime: `${ms}ms`,
|
|
contentLength: ctx.length || 0
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 响应时间记录中间件
|
|
*/
|
|
export default async function responseTime(ctx, next) {
|
|
// 跳过静态资源
|
|
if (isStaticResource(ctx.path)) {
|
|
await next()
|
|
return
|
|
}
|
|
|
|
const start = Date.now()
|
|
|
|
try {
|
|
await next()
|
|
} finally {
|
|
const ms = Date.now() - start
|
|
|
|
// 设置响应头
|
|
ctx.set("X-Response-Time", `${ms}ms`)
|
|
|
|
// 页面请求简单记录
|
|
if (!ctx.path.includes("/api")) {
|
|
if (ms > 500) {
|
|
logger.warn(`Slow page request: ${ctx.path} | ${ms}ms`)
|
|
}
|
|
return
|
|
}
|
|
|
|
// API 请求详细记录
|
|
const logLevel = ms > 1000 ? 'warn' : ms > 500 ? 'info' : 'debug'
|
|
const slowFlag = ms > 500 ? '🐌' : '⚡'
|
|
|
|
logger[logLevel](`${slowFlag} API Request:`, formatRequestLog(ctx, ms))
|
|
|
|
// 如果是慢请求,额外记录
|
|
if (ms > 1000) {
|
|
logger.error(`Very slow API request detected: ${ctx.method} ${ctx.path} took ${ms}ms`)
|
|
}
|
|
}
|
|
}
|