Files
juchatz/src/middleware/index.js
2025-06-26 11:58:27 -07:00

53 lines
1.9 KiB
JavaScript

// src/middleware/index.js
import { defineMiddleware } from 'astro:middleware';
import fs from 'fs';
import path from 'path';
const requestLogger = async (context, next) => {
const start = Date.now();
const timestamp = new Date();
// Get client info
const ip = context.request.headers.get('x-forwarded-for') ||
context.request.headers.get('x-real-ip') ||
context.clientAddress || 'unknown';
const method = context.request.method;
const url = context.url.pathname + context.url.search;
const userAgent = context.request.headers.get('user-agent') || '-';
const referer = context.request.headers.get('referer') || '-';
// Process the request
const response = await next();
const duration = Date.now() - start;
const status = response.status;
const contentLength = response.headers.get('content-length') || '-';
// Format timestamp like nginx: [26/Jun/2025:18:19:28 +0000]
const day = timestamp.getDate().toString().padStart(2, '0');
const month = timestamp.toLocaleString('en', { month: 'short' });
const year = timestamp.getFullYear();
const time = timestamp.toTimeString().split(' ')[0];
const formattedTimestamp = `${day}/${month}/${year}:${time} +0000`;
// Create log entry in Combined Log Format (like nginx)
const logEntry = `${ip} - - [${formattedTimestamp}] "${method} ${url} HTTP/1.1" ${status} ${contentLength} "${referer}" "${userAgent}"\n`;
// Skip logging for static assets to reduce noise
const isStaticAsset = /\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|otf|webp|map)$/i.test(url);
if (!isStaticAsset) {
try {
const logFile = '/var/log/astro-access.log';
fs.appendFileSync(logFile, logEntry);
} catch (error) {
console.error('Failed to write access log:', error);
}
}
return response;
};
export const onRequest = defineMiddleware(requestLogger);