diff --git a/middleware.ts b/middleware.ts index 0a4d53be..44037a7c 100644 --- a/middleware.ts +++ b/middleware.ts @@ -1,13 +1,78 @@ import createMiddleware from 'next-intl/middleware'; - -export default createMiddleware({ +import { NextResponse } from 'next/server'; +import type { NextRequest } from 'next/server'; +import { getServerAppServices } from '@/lib/services/create-services.server'; + +// Create the internationalization middleware +const intlMiddleware = createMiddleware({ // A list of all locales that are supported locales: ['en', 'de'], - + // Used when no locale matches defaultLocale: 'en' }); - + +// Main middleware that logs all requests +export default function middleware(request: NextRequest) { + const startTime = Date.now(); + const { method, url, headers } = request; + const userAgent = headers.get('user-agent') || 'unknown'; + const referer = headers.get('referer') || 'none'; + const ip = headers.get('x-forwarded-for') || headers.get('x-real-ip') || 'unknown'; + + // Get logger service + const services = getServerAppServices(); + const logger = services.logger.child({ middleware: 'request-logger' }); + + // Log incoming request + logger.info('Incoming request', { + method, + url, + userAgent, + referer, + ip, + timestamp: new Date().toISOString(), + }); + + try { + // Apply internationalization middleware + const response = intlMiddleware(request); + const duration = Date.now() - startTime; + + // Log successful response + logger.info('Request completed', { + method, + url, + status: response.status, + duration, + userAgent, + referer, + ip, + timestamp: new Date().toISOString(), + }); + + return response; + } catch (error) { + const duration = Date.now() - startTime; + + // Log error + logger.error('Request failed', { + method, + url, + duration, + userAgent, + referer, + ip, + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + timestamp: new Date().toISOString(), + }); + + // Re-throw the error to let Next.js handle it + throw error; + } +} + export const config = { // Match only internationalized pathnames matcher: ['/((?!api|_next|_vercel|.*\\..*).*)', '/', '/(de|en)/:path*']