Files
record-app-next/lib/middleware/api-logger.ts
2025-07-31 17:05:07 +08:00

99 lines
2.2 KiB
TypeScript

import { NextRequest, NextResponse } from "next/server";
import { logger } from "../utils/logger";
export interface ApiLoggerOptions {
logRequests?: boolean;
logResponses?: boolean;
logErrors?: boolean;
excludePaths?: string[];
}
export class ApiLogger {
static async logRequest(
request: NextRequest,
response: NextResponse,
duration: number,
options: ApiLoggerOptions = {}
): Promise<void> {
const {
logRequests = true,
logResponses = true,
logErrors = true,
excludePaths = [],
} = options;
const url = new URL(request.url);
const path = url.pathname;
// 跳过排除的路径
if (excludePaths.some((excludePath) => path.startsWith(excludePath))) {
return;
}
const method = request.method;
const statusCode = response.status;
const userAgent = request.headers.get("user-agent") || "Unknown";
const ip =
request.headers.get("x-forwarded-for") ||
request.headers.get("x-real-ip") ||
"Unknown";
// 记录请求
if (logRequests) {
logger.logApiRequest(method, path, statusCode, duration);
}
// 记录错误
if (logErrors && statusCode >= 400) {
logger.error("API Error", {
method,
path,
statusCode,
duration,
userAgent,
ip,
});
}
// 记录响应统计
if (logResponses) {
logger.info("API Response", {
method,
path,
statusCode,
duration,
userAgent,
ip,
});
}
}
static createMiddleware(options: ApiLoggerOptions = {}) {
return async (
request: NextRequest,
handler: () => Promise<NextResponse>
) => {
const startTime = Date.now();
try {
const response = await handler();
const duration = Date.now() - startTime;
await this.logRequest(request, response, duration, options);
return response;
} catch (error) {
const duration = Date.now() - startTime;
const errorResponse = NextResponse.json(
{ error: "Internal Server Error" },
{ status: 500 }
);
await this.logRequest(request, errorResponse, duration, options);
throw error;
}
};
}
}