first commit

This commit is contained in:
2026-07-30 16:26:21 +02:00
commit 9e32a4d786
33 changed files with 3475 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
<?php
use SyslogDash\SyslogQuery;
use SyslogDash\GeoIP;
$sq = new SyslogQuery();
$kpi = $sq->getKPIStats(30);
$daily = $sq->getDailyStats(30);
$hostStats = $sq->getHostStats(30);
$sevStats = $sq->getSeverityStats(30);
$tagStats = $sq->getTagStats(30);
$topCountry = $kpi['topCountry'];
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="mb-0"><i class="bi bi-speedometer2 me-2"></i>Dashboard</h2>
<span class="text-muted small">Laatste 30 dagen</span>
</div>
<div class="row g-4 mb-4">
<div class="col-md-3">
<div class="stat-card">
<div class="stat-icon bg-primary-subtle text-primary"><i class="bi bi-envelope"></i></div>
<div class="stat-body">
<div class="stat-value"><?= number_format($kpi['total'], 0, ',', '.') ?></div>
<div class="stat-label">Log berichten</div>
<small class="text-muted"><?= number_format($kpi['avgPerDay'], 0, ',', '.') ?>/dag</small>
</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<div class="stat-icon bg-success-subtle text-success"><i class="bi bi-hdd-network"></i></div>
<div class="stat-body">
<div class="stat-value"><?= $kpi['uniqueHosts'] ?></div>
<div class="stat-label">Unieke hosts</div>
<small class="text-muted">apparaten</small>
</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<div class="stat-icon bg-info-subtle text-info"><i class="bi bi-globe"></i></div>
<div class="stat-body">
<div class="stat-value"><?php if ($topCountry): ?><?= GeoIP::getCountryFlagEmoji($topCountry['code']) ?> <?= GeoIP::getCountryName($topCountry['code']) ?><?php else: ?>—<?php endif; ?></div>
<div class="stat-label">Grootste land</div>
<small class="text-muted"><?= $topCountry ? number_format($topCountry['count'], 0, ',', '.') . ' berichten' : '' ?></small>
</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card">
<div class="stat-icon bg-warning-subtle text-warning"><i class="bi bi-clock-history"></i></div>
<div class="stat-body">
<div class="stat-value"><?= number_format($kpi['totalAll'], 0, ',', '.') ?></div>
<div class="stat-label">Totaal (all-time)</div>
<small class="text-muted">sinds begin</small>
</div>
</div>
</div>
</div>
<div class="row g-4 mb-4">
<div class="col-lg-8">
<div class="card shadow-sm h-100">
<div class="card-header bg-white d-flex justify-content-between align-items-center">
<span><i class="bi bi-graph-up me-2"></i>Berichten per dag</span>
</div>
<div class="card-body">
<canvas id="dailyChart" height="200"></canvas>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card shadow-sm h-100">
<div class="card-header bg-white"><i class="bi bi-pie-chart me-2"></i>Severity</div>
<div class="card-body">
<canvas id="sevChart" height="200"></canvas>
</div>
</div>
</div>
</div>
<div class="row g-4">
<div class="col-md-6">
<div class="card shadow-sm">
<div class="card-header bg-white"><i class="bi bi-hdd-network me-2"></i>Top hosts</div>
<div class="card-body p-0">
<div class="list-group list-group-flush">
<?php $maxHost = max(array_column($hostStats, 'cnt')); ?>
<?php foreach ($hostStats as $h): ?>
<div class="list-group-item">
<div class="d-flex justify-content-between align-items-center mb-1">
<a href="?page=logs&host=<?= urlencode($h['FromHost']) ?>" class="text-decoration-none"><?= htmlspecialchars($h['FromHost']) ?></a>
<span class="badge bg-primary rounded-pill"><?= number_format($h['cnt'], 0, ',', '.') ?></span>
</div>
<div class="progress" style="height:4px">
<div class="progress-bar" style="width:<?= $maxHost > 0 ? ($h['cnt']/$maxHost*100) : 0 ?>%"></div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card shadow-sm">
<div class="card-header bg-white"><i class="bi bi-tags me-2"></i>Top tags</div>
<div class="card-body p-0">
<div class="list-group list-group-flush">
<?php $maxTag = max(array_column($tagStats, 'cnt')); ?>
<?php foreach ($tagStats as $t): ?>
<div class="list-group-item">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="text-muted small font-monospace"><?= htmlspecialchars($t['SysLogTag'] ?? '—') ?></span>
<span class="badge bg-secondary rounded-pill"><?= number_format($t['cnt'], 0, ',', '.') ?></span>
</div>
<div class="progress" style="height:4px">
<div class="progress-bar bg-info" style="width:<?= $maxTag > 0 ? ($t['cnt']/$maxTag*100) : 0 ?>%"></div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
new Chart(document.getElementById('dailyChart'), {
type: 'bar',
data: {
labels: <?= json_encode(array_map(fn($d) => date('d-m', strtotime($d['date'])), $daily)) ?>,
datasets: [
{ label: 'Berichten', data: <?= json_encode(array_column($daily, 'cnt')) ?>, backgroundColor: '#0d6efd', borderRadius: 2 },
{ label: 'Hosts', data: <?= json_encode(array_column($daily, 'hosts')) ?>, backgroundColor: '#6ea8fe', borderRadius: 2 }
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { position: 'top', labels: { boxWidth: 12 } } },
scales: { y: { beginAtZero: true } }
}
});
new Chart(document.getElementById('sevChart'), {
type: 'doughnut',
data: {
labels: <?= json_encode(array_map(fn($s) => SyslogQuery::severityName((int)$s['Priority']), $sevStats)) ?>,
datasets: [{
data: <?= json_encode(array_column($sevStats, 'cnt')) ?>,
backgroundColor: ['#dc3545','#dc3545','#dc3545','#ffc107','#ffc107','#0dcaf0','#6c757d','#6c757d']
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { position: 'right', labels: { boxWidth: 12, font: { size: 11 } } } }
}
});
});
</script>
<?php $sq = null; // close PDO connection ?>