Standalone app for Q5 deployment
هذا الالتزام موجود في:
102
dashboard.html
Normal file
102
dashboard.html
Normal file
@@ -0,0 +1,102 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ar" dir="rtl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>مراقبة mithal.space</title>
|
||||
<style>
|
||||
body { font-family: Arial; background: #0f172a; color: #e2e8f0; padding: 30px; }
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 15px; margin-bottom: 20px; }
|
||||
.card { background: #1e293b; padding: 20px; border-radius: 10px; }
|
||||
.big { font-size: 28px; font-weight: bold; }
|
||||
.status-up { color: #22c55e; }
|
||||
.status-down { color: #ef4444; }
|
||||
canvas { background: #1e293b; border-radius: 10px; padding: 10px; }
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
|
||||
td, th { padding: 8px; border-bottom: 1px solid #334155; text-align: right; font-size: 13px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>لوحة مراقبة mithal.space</h1>
|
||||
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<div>نسبة التشغيل (24 ساعة)</div>
|
||||
<div class="big" id="uptime-pct">-</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div>حالة SSL</div>
|
||||
<div class="big" id="ssl-status">-</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div>آخر زمن استجابة</div>
|
||||
<div class="big" id="latest-latency">-</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div>زمن الاستجابة — آخر ساعة</div>
|
||||
<canvas id="latencyChart" height="80"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="card" style="margin-top:15px;">
|
||||
<h3>آخر 10 فحوصات</h3>
|
||||
<table id="log-table">
|
||||
<thead><tr><th>الوقت</th><th>الحالة</th><th>الاستجابة</th><th>SSL</th><th>DNS</th></tr></thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.0/chart.umd.min.js"></script>
|
||||
<script>
|
||||
let chart;
|
||||
|
||||
async function loadData() {
|
||||
const res = await fetch('mithal_monitor_log.json');
|
||||
const text = await res.text();
|
||||
const lines = text.trim().split('\n').filter(Boolean).map(JSON.parse);
|
||||
|
||||
const last = lines[lines.length - 1];
|
||||
const upCount = lines.filter(l => l.uptime.up).length;
|
||||
const uptimePct = ((upCount / lines.length) * 100).toFixed(1);
|
||||
|
||||
document.getElementById('uptime-pct').innerHTML =
|
||||
`<span class="${uptimePct > 95 ? 'status-up' : 'status-down'}">${uptimePct}%</span>`;
|
||||
document.getElementById('ssl-status').innerHTML = last.ssl.valid
|
||||
? `<span class="status-up">صالحة (${last.ssl.days_until_expiry} يوم)</span>`
|
||||
: `<span class="status-down">غير صالحة</span>`;
|
||||
document.getElementById('latest-latency').innerText = last.uptime.latency_ms + ' ms';
|
||||
|
||||
const recent = lines.slice(-60);
|
||||
const labels = recent.map(l => new Date(l.timestamp).toLocaleTimeString('ar-EG'));
|
||||
const data = recent.map(l => l.uptime.latency_ms);
|
||||
|
||||
if (chart) {
|
||||
chart.data.labels = labels;
|
||||
chart.data.datasets[0].data = data;
|
||||
chart.update();
|
||||
} else {
|
||||
chart = new Chart(document.getElementById('latencyChart'), {
|
||||
type: 'line',
|
||||
data: { labels, datasets: [{ label: 'ms', data, borderColor: '#38bdf8', tension: 0.3 }] },
|
||||
options: { plugins: { legend: { display: false } }, scales: { y: { beginAtZero: true } } }
|
||||
});
|
||||
}
|
||||
|
||||
const tbody = document.querySelector('#log-table tbody');
|
||||
tbody.innerHTML = '';
|
||||
lines.slice(-10).reverse().forEach(l => {
|
||||
tbody.innerHTML += `<tr>
|
||||
<td>${new Date(l.timestamp).toLocaleTimeString('ar-EG')}</td>
|
||||
<td>${l.uptime.up ? '✅' : '❌'}</td>
|
||||
<td>${l.uptime.latency_ms} ms</td>
|
||||
<td>${l.ssl.valid ? '✅' : '❌'}</td>
|
||||
<td>${l.dns.dns_time_ms} ms</td>
|
||||
</tr>`;
|
||||
});
|
||||
}
|
||||
|
||||
loadData();
|
||||
setInterval(loadData, 60000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
المرجع في مشكلة جديدة
حظر مستخدم