99 lines
2.2 KiB
TypeScript
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;
|
|
}
|
|
};
|
|
}
|
|
}
|