130 lines
4.9 KiB
PHP
130 lines
4.9 KiB
PHP
<?php
|
|
/**
|
|
* Yumee Panels - Persistent Background Worker (Foreground Service Equivalent)
|
|
*/
|
|
|
|
require_once __DIR__ . '/db/config.php';
|
|
|
|
// Prevent multiple instances
|
|
$lockFile = __DIR__ . '/worker.lock';
|
|
$lock = fopen($lockFile, 'c');
|
|
if (!flock($lock, LOCK_EX | LOCK_NB)) {
|
|
die("Worker is already running.\n");
|
|
}
|
|
|
|
function sendTelegramMessage($text) {
|
|
global $pdo; // Assume db() uses a global or similar, let's fetch from settings
|
|
try {
|
|
$stmt = db()->query("SELECT setting_value FROM settings WHERE setting_key = 'telegram_token'");
|
|
$token = $stmt->fetchColumn();
|
|
$stmt = db()->query("SELECT setting_value FROM settings WHERE setting_key = 'telegram_chat_id'");
|
|
$chatId = $stmt->fetchColumn();
|
|
|
|
if (!$token || !$chatId) return false;
|
|
|
|
$url = "https://api.telegram.org/bot$token/sendMessage";
|
|
$data = [
|
|
'chat_id' => $chatId,
|
|
'text' => "🔔 *Uptime Alert*\n" . $text,
|
|
'parse_mode' => 'Markdown'
|
|
];
|
|
|
|
$options = [
|
|
'http' => [
|
|
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
|
'method' => 'POST',
|
|
'content' => http_build_query($data),
|
|
],
|
|
];
|
|
$context = stream_context_create($options);
|
|
return file_get_contents($url, false, $context);
|
|
} catch (Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
echo "Yumee Panels Background Worker Started (v1.1)...
|
|
";
|
|
|
|
while (true) {
|
|
try {
|
|
$start_time = microtime(true);
|
|
|
|
// Fetch monitors
|
|
$stmt = db()->query("SELECT * FROM monitors");
|
|
$monitors = $stmt->fetchAll();
|
|
|
|
if (!empty($monitors)) {
|
|
$mh = curl_multi_init();
|
|
$handles = [];
|
|
|
|
foreach ($monitors as $m) {
|
|
$ch = curl_init($m['url']);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
|
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
|
curl_setopt($ch, CURLOPT_USERAGENT, 'YumeePinger-Worker/1.1');
|
|
curl_multi_add_handle($mh, $ch);
|
|
$handles[$m['id']] = ['ch' => $ch, 'data' => $m];
|
|
}
|
|
|
|
$running = null;
|
|
do {
|
|
curl_multi_exec($mh, $running);
|
|
usleep(5000);
|
|
} while ($running);
|
|
|
|
foreach ($handles as $id => $h) {
|
|
$ch = $h['ch'];
|
|
$m = $h['data'];
|
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$latency = round(curl_getinfo($ch, CURLINFO_TOTAL_TIME) * 1000);
|
|
curl_multi_remove_handle($mh, $ch);
|
|
curl_close($ch);
|
|
|
|
$is_up = ($http_code >= 200 && $http_code < 400);
|
|
$prev_status = $m['last_status'];
|
|
$prev_notified = $m['last_notified_status'];
|
|
|
|
// Update monitor
|
|
$upd = db()->prepare("UPDATE monitors SET last_status = ?, last_latency = ? WHERE id = ?");
|
|
$upd->execute([$http_code, $latency, $id]);
|
|
|
|
// Log entry
|
|
$log = db()->prepare("INSERT INTO monitor_logs (monitor_id, status_code, latency) VALUES (?, ?, ?)");
|
|
$log->execute([$id, $http_code, $latency]);
|
|
|
|
// Notification logic: only notify on transition
|
|
if ($prev_notified !== null) {
|
|
$prev_was_up = ($prev_notified >= 200 && $prev_notified < 400);
|
|
if ($is_up !== $prev_was_up) {
|
|
$status_str = $is_up ? "✅ UP" : "❌ DOWN";
|
|
$msg = "Monitor *{$m['name']}* is now $status_str\nURL: {$m['url']}\nStatus: $http_code\nLatency: {$latency}ms";
|
|
sendTelegramMessage($msg);
|
|
|
|
// Update last notified status
|
|
$upd_notify = db()->prepare("UPDATE monitors SET last_notified_status = ? WHERE id = ?");
|
|
$upd_notify->execute([$http_code, $id]);
|
|
}
|
|
} else {
|
|
// Initial notification status set
|
|
$upd_notify = db()->prepare("UPDATE monitors SET last_notified_status = ? WHERE id = ?");
|
|
$upd_notify->execute([$http_code, $id]);
|
|
}
|
|
}
|
|
curl_multi_close($mh);
|
|
}
|
|
|
|
// Record heartbeat in settings for UI to check
|
|
db()->prepare("INSERT INTO settings (setting_key, setting_value) VALUES ('worker_heartbeat', UNIX_TIMESTAMP()) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)")->execute();
|
|
|
|
$end_time = microtime(true);
|
|
$execution_time = ($end_time - $start_time);
|
|
$sleep_time = max(0.1, 1 - $execution_time);
|
|
usleep($sleep_time * 1000000);
|
|
|
|
} catch (Exception $e) {
|
|
echo "Error: " . $e->getMessage() . "\n";
|
|
sleep(2);
|
|
}
|
|
} |