Uptime
This commit is contained in:
parent
6fabe9540d
commit
dc9d779de8
BIN
monitor.log
BIN
monitor.log
Binary file not shown.
185
monitor.php
185
monitor.php
@ -5,102 +5,125 @@ require_once __DIR__ . '/db/config.php';
|
|||||||
$lockFile = __DIR__ . '/monitor.lock';
|
$lockFile = __DIR__ . '/monitor.lock';
|
||||||
$fp = fopen($lockFile, 'c');
|
$fp = fopen($lockFile, 'c');
|
||||||
if (!flock($fp, LOCK_EX | LOCK_NB)) {
|
if (!flock($fp, LOCK_EX | LOCK_NB)) {
|
||||||
die("Another instance is already running.\n");
|
// Silently exit if already running (good for cron)
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "Monitoring started with Multi-Threading...\n";
|
echo "Monitoring started with Multi-Threading...\n";
|
||||||
|
|
||||||
function sendTelegramNotification($message) {
|
function sendTelegramNotification($message) {
|
||||||
$db = db();
|
try {
|
||||||
$stmt = $db->query("SELECT name, value FROM settings WHERE name IN ('telegram_bot_token', 'telegram_chat_id')");
|
$db = db();
|
||||||
$settings = [];
|
$stmt = $db->query("SELECT name, value FROM settings WHERE name IN ('telegram_bot_token', 'telegram_chat_id')");
|
||||||
while ($row = $stmt->fetch()) {
|
$settings = [];
|
||||||
$settings[$row['name']] = $row['value'];
|
while ($row = $stmt->fetch()) {
|
||||||
|
$settings[$row['name']] = $row['value'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($settings['telegram_bot_token']) || empty($settings['telegram_chat_id'])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = "https://api.telegram.org/bot" . $settings['telegram_bot_token'] . "/sendMessage";
|
||||||
|
$data = [
|
||||||
|
'chat_id' => $settings['telegram_chat_id'],
|
||||||
|
'text' => $message,
|
||||||
|
'parse_mode' => 'HTML'
|
||||||
|
];
|
||||||
|
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||||
|
curl_exec($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Suppress errors to not break the monitor loop
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($settings['telegram_bot_token']) || empty($settings['telegram_chat_id'])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$url = "https://api.telegram.org/bot" . $settings['telegram_bot_token'] . "/sendMessage";
|
|
||||||
$data = [
|
|
||||||
'chat_id' => $settings['telegram_chat_id'],
|
|
||||||
'text' => $message,
|
|
||||||
'parse_mode' => 'HTML'
|
|
||||||
];
|
|
||||||
|
|
||||||
$ch = curl_init($url);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
|
||||||
curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loop indefinitely
|
||||||
while (true) {
|
while (true) {
|
||||||
$startLoop = microtime(true);
|
try {
|
||||||
|
$db = db();
|
||||||
$db = db();
|
$urls = $db->query("SELECT * FROM urls WHERE is_active = 1")->fetchAll();
|
||||||
$urls = $db->query("SELECT * FROM urls WHERE is_active = 1")->fetchAll();
|
|
||||||
|
|
||||||
if (count($urls) > 0) {
|
if (count($urls) > 0) {
|
||||||
$mh = curl_multi_init();
|
$mh = curl_multi_init();
|
||||||
$ch_list = [];
|
$curl_arr = [];
|
||||||
|
$url_info = [];
|
||||||
|
|
||||||
foreach ($urls as $urlData) {
|
// Add handles
|
||||||
$ch = curl_init($urlData['url']);
|
foreach ($urls as $urlData) {
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
$ch = curl_init($urlData['url']);
|
||||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
curl_setopt($ch, CURLOPT_HEADER, false); // We don't need body, just headers
|
||||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
curl_setopt($ch, CURLOPT_NOBODY, true); // HEAD request is faster
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||||
curl_multi_add_handle($mh, $ch);
|
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 10s timeout
|
||||||
$ch_list[(int)$ch] = [
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
'id' => $urlData['id'],
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
'url' => $urlData['url'],
|
|
||||||
'old_status' => $urlData['status'],
|
curl_multi_add_handle($mh, $ch);
|
||||||
'start_time' => microtime(true)
|
$curl_arr[] = $ch;
|
||||||
];
|
// Store info mapped by intval of handle
|
||||||
}
|
$url_info[(int)$ch] = $urlData;
|
||||||
|
|
||||||
$active = null;
|
|
||||||
do {
|
|
||||||
$mrc = curl_multi_exec($mh, $active);
|
|
||||||
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
|
|
||||||
|
|
||||||
while ($active && $mrc == CURLM_OK) {
|
|
||||||
if (curl_multi_select($mh) != -1) {
|
|
||||||
do {
|
|
||||||
$mrc = curl_multi_exec($mh, $active);
|
|
||||||
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($ch_list as $ch_id => $data) {
|
// Execute handles
|
||||||
$ch = null;
|
$active = null;
|
||||||
// Find the handle
|
do {
|
||||||
foreach ($ch_list as $handle_id => $info) {
|
$mrc = curl_multi_exec($mh, $active);
|
||||||
if ($handle_id == $ch_id) {
|
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
|
||||||
// This is tricky in PHP to get handle by int.
|
|
||||||
// Actually we can just keep the handles in an array.
|
while ($active && $mrc == CURLM_OK) {
|
||||||
|
if (curl_multi_select($mh) != -1) {
|
||||||
|
do {
|
||||||
|
$mrc = curl_multi_exec($mh, $active);
|
||||||
|
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read results
|
||||||
|
foreach ($curl_arr as $ch) {
|
||||||
|
$ch_id = (int)$ch;
|
||||||
|
$urlData = $url_info[$ch_id];
|
||||||
|
|
||||||
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$total_time = curl_getinfo($ch, CURLINFO_TOTAL_TIME);
|
||||||
|
$total_time_ms = round($total_time * 1000);
|
||||||
|
|
||||||
|
// Determine new status: UP if 200-399
|
||||||
|
$new_status = ($http_code >= 200 && $http_code < 400) ? 'UP' : 'DOWN';
|
||||||
|
$old_status = $urlData['status'];
|
||||||
|
|
||||||
|
// Update database
|
||||||
|
$stmt = $db->prepare("UPDATE urls SET status = ?, last_checked = NOW() WHERE id = ?");
|
||||||
|
$stmt->execute([$new_status, $urlData['id']]);
|
||||||
|
|
||||||
|
$stmt = $db->prepare("INSERT INTO logs (url_id, status, response_time, checked_at) VALUES (?, ?, ?, NOW())");
|
||||||
|
$stmt->execute([$urlData['id'], $new_status, $total_time_ms]);
|
||||||
|
|
||||||
|
// Check for status change and notify
|
||||||
|
if ($old_status && $old_status !== $new_status) {
|
||||||
|
$icon = $new_status === 'UP' ? '✅' : '🚨';
|
||||||
|
$msg = "{$icon} <b>Monitor Alert</b>\n\n";
|
||||||
|
$msg .= "<b>URL:</b> {$urlData['url']}\n";
|
||||||
|
$msg .= "<b>Status:</b> {$new_status} (HTTP {$http_code})\n";
|
||||||
|
$msg .= "<b>Response:</b> {$total_time_ms}ms";
|
||||||
|
sendTelegramNotification($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_multi_remove_handle($mh, $ch);
|
||||||
|
curl_close($ch);
|
||||||
|
}
|
||||||
|
curl_multi_close($mh);
|
||||||
}
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
// Re-doing the loop for better handle management
|
echo "Error: " . $e->getMessage() . "\n";
|
||||||
foreach ($ch_list as $ch_int => $info) {
|
|
||||||
// Wait, I need the actual handle.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SIMPLIFIED Sequential for stability if multi is complex in 1s loop
|
// Wait 30 seconds before next check
|
||||||
// Let's stick to sequential but optimized for now, or fix multi properly.
|
sleep(30);
|
||||||
// Actually, curl_multi is better. Let's do it right.
|
}
|
||||||
|
|
||||||
// (Self-correction: curl_multi is better but I need to store the handles properly)
|
|
||||||
|
|
||||||
$endLoop = microtime(true);
|
|
||||||
// ... sleep ...
|
|
||||||
usleep(1000000); // Temporary simplified sleep
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user