UptimeMonitor

This commit is contained in:
Flatlogic Bot 2026-02-25 01:15:30 +00:00
parent 4fdf45d69d
commit a9d9df7775
3 changed files with 188 additions and 15 deletions

View File

@ -28,13 +28,46 @@ function ping($url) {
}
function notifyStatusChange($url, $oldStatus, $newStatus, $error = null) {
$recipient = 'yumeecute@aol.com';
$time = date('Y-m-d H:i:s');
$statusEmoji = ($newStatus === 'error') ? '🚨' : '🟢';
$statusText = strtoupper($newStatus);
// 1. Send Telegram Push to Phone (24/7 real-time forcing)
try {
$stmt = db()->query("SELECT value FROM settings WHERE `key` = 'telegram_token'");
$token = $stmt->fetchColumn();
$stmt2 = db()->query("SELECT value FROM settings WHERE `key` = 'telegram_chat_id'");
$chatId = $stmt2->fetchColumn();
if ($token && $chatId) {
$msg = "$statusEmoji *MONITOR ALERT*
URL: $url
Status: *$statusText*
Time: $time
" . ($error ? "Error: $error" : "");
$tgUrl = "https://api.telegram.org/bot$token/sendMessage";
$data = ['chat_id' => $chatId, 'text' => $msg, 'parse_mode' => 'Markdown'];
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded
",
'method' => 'POST',
'content' => http_build_query($data),
],
];
file_get_contents($tgUrl, false, stream_context_create($options));
}
} catch (Exception $e) {
// Ignore errors if telegram not setup
}
// 2. Original Email logic
$recipient = 'yumeecute@aol.com';
if ($oldStatus === 'ok' && $newStatus === 'error') {
$subject = "🔴 ALERT: Website Down - $url";
$html = "
<div style='font-family: Arial, sans-serif; border: 1px solid #ff4d4d; padding: 20px; border-radius: 8px;'>
$html = <div style='font-family: Arial, sans-serif; border: 1px solid #ff4d4d; padding: 20px; border-radius: 8px;'>
<h2 style='color: #ff4d4d;'>Website Down Alert</h2>
<p>The following website is currently unresponsive:</p>
<p><strong>URL:</strong> <a href='$url'>$url</a></p>
@ -46,8 +79,7 @@ function notifyStatusChange($url, $oldStatus, $newStatus, $error = null) {
";
} elseif ($oldStatus === 'error' && $newStatus === 'ok') {
$subject = "🟢 RESOLVED: Website Up - $url";
$html = "
<div style='font-family: Arial, sans-serif; border: 1px solid #28a745; padding: 20px; border-radius: 8px;'>
$html = <div style='font-family: Arial, sans-serif; border: 1px solid #28a745; padding: 20px; border-radius: 8px;'>
<h2 style='color: #28a745;'>Website Back Online</h2>
<p>The following website is responding normally again:</p>
<p><strong>URL:</strong> <a href='$url'>$url</a></p>
@ -79,6 +111,30 @@ function generateApiKey() {
}
switch ($action) {
case 'save_telegram':
$data = json_decode(file_get_contents('php://input'), true);
$token = $data['telegram_token'] ?? '';
$chatId = $data['telegram_chat_id'] ?? '';
$stmt = db()->prepare("INSERT INTO settings (`key`, value) VALUES ('telegram_token', ?) ON DUPLICATE KEY UPDATE value = VALUES(value)");
$stmt->execute([$token]);
$stmt = db()->prepare("INSERT INTO settings (`key`, value) VALUES ('telegram_chat_id', ?) ON DUPLICATE KEY UPDATE value = VALUES(value)");
$stmt->execute([$chatId]);
echo json_encode(['success' => true]);
break;
case 'get_telegram':
$stmt = db()->query("SELECT `key`, value FROM settings WHERE `key` IN ('telegram_token', 'telegram_chat_id')");
$res = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
echo json_encode([
'telegram_token' => $res['telegram_token'] ?? '',
'telegram_chat_id' => $res['telegram_chat_id'] ?? ''
]);
break;
case 'settings':
echo json_encode(['monitoring_enabled' => isMonitoringEnabled()]);
break;

47
backend_monitor.php Normal file
View File

@ -0,0 +1,47 @@
<?php
require_once __DIR__ . '/api/uptime.php';
// A simple CLI script that runs continuously on the server
// Usage: php backend_monitor.php &
if (php_sapi_name() !== 'cli') {
die("This script must be run from the command line.");
}
echo "Starting 24/7 Flatlogic Backend Monitor...\n";
echo "Monitoring URLs every 2 seconds...\n";
while (true) {
if (isMonitoringEnabled()) {
$stmt = db()->query("SELECT * FROM urls WHERE is_active = 1");
$urls = $stmt->fetchAll();
foreach ($urls as $row) {
$res = ping($row['url']);
// Log latency to ensure history exists
$ins = db()->prepare("INSERT INTO uptime_logs (url_id, status, latency) VALUES (?, ?, ?)");
$ins->execute([$row['id'], $res['status'], $res['latency']]);
// Notify on change
notifyStatusChange($row['url'], $row['last_status'], $res['status'], $res['error']);
// Update URL status
$upd = db()->prepare("UPDATE urls SET last_status = ?, last_latency = ?, last_checked_at = NOW() WHERE id = ?");
$upd->execute([$res['status'], $res['latency'], $row['id']]);
// Keep only last 500 logs per URL to save DB space
$del = db()->prepare(
"DELETE FROM uptime_logs
WHERE url_id = ?
AND id NOT IN (
SELECT id FROM (
SELECT id FROM uptime_logs WHERE url_id = ? ORDER BY id DESC LIMIT 500
) foo
)"
);
$del->execute([$row['id'], $row['id']]);
}
}
sleep(2); // Wait 2 seconds before the next check
}

View File

@ -176,7 +176,8 @@ $v = time(); // Cache busting version
<li class="nav-item active" onclick="showSection('dashboard')"><span>📊</span> Dashboard</li>
<li class="nav-item" onclick="showSection('monitors')"><span>🔍</span> Monitors</li>
<li class="nav-item" onclick="showSection('teams')"><span>👥</span> Team</li>
<li class="nav-item" onclick="showSection('api')"><span>🔑</span> API</li>
<li class="nav-item" onclick="showSection('api')"><span>🔑</span> API</li>
<li class="nav-item" onclick="showSection('telegram')"><span>📱</span> Mobile Push</li>
</ul>
<div style="padding: 1rem; border-top: 1px solid var(--border);">
<button class="btn-glow" style="width:100%; margin-bottom:10px;" onclick="enterMobileMonitor()">📱 FULL VIEW</button>
@ -267,7 +268,29 @@ $v = time(); // Cache busting version
</table>
</div>
</div>
<div id="api" class="section">
<!-- TELEGRAM PUSH SECTION -->
<div id="telegram" class="section">
<div class="card" style="text-align: left; padding: 2rem;">
<h3 style="margin-top:0;">📱 Mobile Push Notifications (24/7)</h3>
<p>Aplikasi ini berjalan <b>online 24/7 di server Flatlogic</b>. Untuk memaksa memunculkan notifikasi (wget monitor) langsung ke handphone Anda walau browser tertutup, hubungkan Telegram Bot Anda.</p>
<div style="margin: 1.5rem 0; display:flex; flex-direction:column; gap:10px;">
<input type="text" id="tg_token" class="input-field" placeholder="Bot Token (e.g. 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)">
<input type="text" id="tg_chat_id" class="input-field" placeholder="Chat ID (e.g. 123456789)">
<button class="btn" onclick="saveTelegram()">Save Telegram Push Settings</button>
</div>
<div style="font-size:0.85rem; opacity:0.8; background:rgba(0,0,0,0.2); padding:1rem; border-radius:8px;">
<b style="color:var(--accent);">Cara Setup:</b><br>
1. Buka Telegram, cari <b>@BotFather</b>, ketik <code>/newbot</code> lalu copy Token-nya.<br>
2. Ketik nama bot Anda di kolom pencarian Telegram dan Start.<br>
3. Buka browser: <code>https://api.telegram.org/bot&lt;TOKEN_ANDA&gt;/getUpdates</code> untuk menemukan <b>"chat":{"id":123456789}</b> Anda.<br>
4. Masukkan Token dan Chat ID di atas lalu Save. <b>Server akan mem-push pesan 🚨 ERROR & 🟢 RUN otomatis ke handphone Anda!</b>
</div>
</div>
</div>
<div id="api" class="section">
<div class="card" style="margin-bottom: 20px;">
<h3>Generate API Key</h3>
<div style="display:flex; gap: 10px;">
@ -308,7 +331,8 @@ $v = time(); // Cache busting version
<script>
let audioAlert = new Audio('https://assets.mixkit.co/active_storage/sfx/2869/2869-preview.mp3');
let audioAlertError = new Audio('https://assets.mixkit.co/active_storage/sfx/995/995-preview.mp3'); // Sirene / Alert
let audioAlertRun = new Audio('https://assets.mixkit.co/active_storage/sfx/1435/1435-preview.mp3'); // Chime / Success
let previousStatuses = {};
if ("Notification" in window && Notification.permission !== "granted" && Notification.permission !== "denied") {
@ -317,20 +341,32 @@ $v = time(); // Cache busting version
async function checkNotifications(assets) {
for (const u of assets) {
if (previousStatuses[u.id] && previousStatuses[u.id] !== u.last_status) {
// First run: just set the status so it doesn't alert immediately
if (!previousStatuses.hasOwnProperty(u.id)) {
previousStatuses[u.id] = u.last_status;
continue;
}
if (previousStatuses[u.id] !== u.last_status) {
if (u.last_status === 'error') {
if ("Notification" in window && Notification.permission === "granted") {
new Notification("🔴 Alert: Monitor Down!", { body: u.url + " is offline!" });
new Notification("🚨 ALARM: MONITOR ERROR!", {
body: `[ DOWN ] ${u.url} is offline/error!`,
icon: 'https://cdn-icons-png.flaticon.com/512/190/190406.png'
});
}
audioAlert.play().catch(e => console.log('Audio play failed', e));
audioAlertError.play().catch(e => console.log('Audio error failed', e));
} else if (u.last_status === 'ok') {
if ("Notification" in window && Notification.permission === "granted") {
new Notification("🟢 Alert: Monitor Up!", { body: u.url + " is back online!" });
new Notification("✅ INFO: MONITOR RUN!", {
body: `[ RUN ] ${u.url} is back online!`,
icon: 'https://cdn-icons-png.flaticon.com/512/190/190411.png'
});
}
audioAlert.play().catch(e => console.log('Audio play failed', e));
audioAlertRun.play().catch(e => console.log('Audio run failed', e));
}
previousStatuses[u.id] = u.last_status;
}
previousStatuses[u.id] = u.last_status;
}
}
@ -529,7 +565,8 @@ $v = time(); // Cache busting version
}
}
function showSection(id) {
function showSection(id) {
document.querySelectorAll('.section').forEach(s => s.classList.remove('active'));
const sec = document.getElementById(id);
if (sec) sec.classList.add('active');
@ -537,10 +574,43 @@ $v = time(); // Cache busting version
if (id === 'teams') fetchTeams();
if (id === 'api') fetchApiKeys();
if (id === 'telegram') fetchTelegram();
refreshData();
}
async function fetchTelegram() {
try {
const res = await fetch('api/uptime.php?action=get_telegram');
const data = await res.json();
document.getElementById('tg_token').value = data.telegram_token || '';
document.getElementById('tg_chat_id').value = data.telegram_chat_id || '';
} catch (e) {
console.error(e);
}
}
async function saveTelegram() {
const token = document.getElementById('tg_token').value;
const chatId = document.getElementById('tg_chat_id').value;
try {
const res = await fetch('api/uptime.php?action=save_telegram', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ telegram_token: token, telegram_chat_id: chatId })
});
const data = await res.json();
if (data.success) {
alert('Telegram Settings Saved! Handphone kamu akan menerima notifikasi 24/7 sekarang.');
} else {
alert('Failed to save.');
}
} catch (e) {
alert('Error saving settings.');
}
}
setInterval(() => {
const time = new Date().toISOString().split('T')[1].split('.')[0];
document.getElementById('clock').innerText = time + ' UTC';