feat(PROJ-40,PROJ-41): Prometheus Metriken + Dashboard Zeitreihe
- PROJ-40: /api/health mit Version+Uptime, /metrics Prometheus-Format (mails_last_60min/24h/7d/30d, mails_total, storage_bytes, tenants_total, users_total, uptime_seconds) — Token-Schutz optional konfigurierbar - PROJ-41: GET /api/admin/stats/timeseries (30-Tage tagesgenau, Tenant-scoped) + SVG-Balkendiagramm im Dashboard (Mail-Eingang letzte 30 Tage) - storage.DBQueryRow() Helper für Metrics-Queries ohne Pool-Exposition - config.MetricsConfig (enabled, token) in config.go Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
4f366a3634
commit
9298216ce0
@@ -17,6 +17,7 @@ import {
|
||||
getServices,
|
||||
serviceAction,
|
||||
getSystemStats,
|
||||
getMailTimeseries,
|
||||
uploadMailFiles,
|
||||
getUploadProgress,
|
||||
getSecurityAudit,
|
||||
@@ -39,6 +40,7 @@ import {
|
||||
type StorageStats,
|
||||
type ServiceStatus,
|
||||
type SystemStats,
|
||||
type TimeseriesPoint,
|
||||
type UploadJob,
|
||||
type SecurityAuditResult,
|
||||
type Tenant,
|
||||
@@ -82,6 +84,7 @@ export default function AdminPage() {
|
||||
const [smtpStatus, setSmtpStatus] = useState<SMTPStatus | null>(null);
|
||||
const [storageStats, setStorageStats] = useState<StorageStats | null>(null);
|
||||
const [systemStats, setSystemStats] = useState<SystemStats | null>(null);
|
||||
const [timeseries, setTimeseries] = useState<TimeseriesPoint[]>([]);
|
||||
const [apiOnline, setApiOnline] = useState<boolean | null>(null);
|
||||
const [dashLoading, setDashLoading] = useState(true);
|
||||
const [dashRefreshed, setDashRefreshed] = useState<Date | null>(null);
|
||||
@@ -248,16 +251,18 @@ export default function AdminPage() {
|
||||
const loadDashboard = useCallback(async () => {
|
||||
setDashLoading(true);
|
||||
try {
|
||||
const [smtp, health, storage, sysStats] = await Promise.allSettled([
|
||||
const [smtp, health, storage, sysStats, ts] = await Promise.allSettled([
|
||||
getSMTPStatus(),
|
||||
getHealth(),
|
||||
getStorageStats(),
|
||||
getSystemStats(),
|
||||
getMailTimeseries(30),
|
||||
]);
|
||||
setSmtpStatus(smtp.status === "fulfilled" ? smtp.value : null);
|
||||
setApiOnline(health.status === "fulfilled" && health.value.status === "ok");
|
||||
setStorageStats(storage.status === "fulfilled" ? storage.value : null);
|
||||
setSystemStats(sysStats.status === "fulfilled" ? sysStats.value : null);
|
||||
setTimeseries(ts.status === "fulfilled" ? ts.value.points : []);
|
||||
setDashRefreshed(new Date());
|
||||
} finally {
|
||||
setDashLoading(false);
|
||||
@@ -718,6 +723,7 @@ export default function AdminPage() {
|
||||
smtpStatus={smtpStatus}
|
||||
storageStats={storageStats}
|
||||
systemStats={systemStats}
|
||||
timeseries={timeseries}
|
||||
apiOnline={apiOnline}
|
||||
dashLoading={dashLoading}
|
||||
dashRefreshed={dashRefreshed}
|
||||
|
||||
Reference in New Issue
Block a user