- Parse Caddy access logs every 30s into traffic_events SQLite table - GeoIP country lookup via maxmind (GeoLite2-Country.mmdb) - 90-day retention with automatic purge - Analytics page with interval (24h/7d/30d) and per-host filtering: - Stats cards: total requests, unique IPs, blocked count, block rate - Requests-over-time area chart (ApexCharts) - SVG world choropleth map (d3-geo + topojson-client, React 19 compatible) - Top countries table with flag emojis - HTTP protocol donut chart - Top user agents horizontal bar chart - Recent blocked requests table with pagination - Traffic (24h) summary card on Overview page linking to analytics - 7 authenticated API routes under /api/analytics/ - Share caddy-logs volume with web container (read-only) - group_add caddy GID to web container for log file read access Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
14 lines
574 B
TypeScript
14 lines
574 B
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { requireUser } from '@/src/lib/auth';
|
|
import { getAnalyticsBlocked, type Interval } from '@/src/lib/analytics-db';
|
|
|
|
export async function GET(req: NextRequest) {
|
|
await requireUser();
|
|
const { searchParams } = req.nextUrl;
|
|
const interval = (searchParams.get('interval') ?? '24h') as Interval;
|
|
const host = searchParams.get('host') ?? 'all';
|
|
const page = parseInt(searchParams.get('page') ?? '1', 10);
|
|
const data = await getAnalyticsBlocked(interval, host, page);
|
|
return NextResponse.json(data);
|
|
}
|