Add all files
This commit is contained in:
311
extensions/Others/UptimeLab/Services/UptimeMonitoringService.php
Normal file
311
extensions/Others/UptimeLab/Services/UptimeMonitoringService.php
Normal file
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
|
||||
namespace Paymenter\Extensions\Others\UptimeLab\Services;
|
||||
|
||||
use Paymenter\Extensions\Others\UptimeLab\Models\UptimeServer;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class UptimeMonitoringService
|
||||
{
|
||||
/**
|
||||
* Check the status of a server
|
||||
*/
|
||||
public function checkServerStatus(UptimeServer $server): array
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$isOnline = false;
|
||||
$responseTime = null;
|
||||
|
||||
try {
|
||||
if ($server->server_type === 'ip') {
|
||||
$result = $this->pingServer($server->ip_address);
|
||||
$isOnline = $result['online'];
|
||||
$responseTime = $result['response_time'];
|
||||
} else {
|
||||
// For subdomains, try HTTP first, then fallback to ping if HTTP fails
|
||||
$result = $this->httpCheck($server->ip_address);
|
||||
$isOnline = $result['online'];
|
||||
$responseTime = $result['response_time'];
|
||||
|
||||
// If HTTP fails, try ping as fallback for subdomains
|
||||
if (!$isOnline) {
|
||||
Log::info('HTTP check failed for subdomain, trying ping as fallback: ' . $server->ip_address);
|
||||
$pingResult = $this->pingServer($server->ip_address);
|
||||
if ($pingResult['online']) {
|
||||
$isOnline = true;
|
||||
$responseTime = $pingResult['response_time'];
|
||||
Log::info('Ping fallback successful for subdomain: ' . $server->ip_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$endTime = microtime(true);
|
||||
$totalTime = round(($endTime - $startTime) * 1000, 2);
|
||||
|
||||
return [
|
||||
'online' => $isOnline,
|
||||
'response_time' => $responseTime,
|
||||
'check_time' => $totalTime,
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Uptime check failed for server: ' . $server->name, [
|
||||
'error' => $e->getMessage(),
|
||||
'server_id' => $server->id,
|
||||
'server_type' => $server->server_type,
|
||||
'ip_address' => $server->ip_address,
|
||||
]);
|
||||
|
||||
return [
|
||||
'online' => false,
|
||||
'response_time' => null,
|
||||
'check_time' => null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ping an IP address or domain
|
||||
*/
|
||||
private function pingServer(string $ip): array
|
||||
{
|
||||
$command = "ping -c 1 -W 5 " . escapeshellarg($ip) . " 2>&1";
|
||||
$output = shell_exec($command);
|
||||
|
||||
if (preg_match('/time=(\d+\.?\d*)\s*ms/', $output, $matches)) {
|
||||
return [
|
||||
'online' => true,
|
||||
'response_time' => (int) $matches[1],
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'online' => false,
|
||||
'response_time' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check HTTP response for subdomains
|
||||
*/
|
||||
private function httpCheck(string $domain): array
|
||||
{
|
||||
try {
|
||||
// Remove any protocol prefix if present
|
||||
$cleanDomain = preg_replace('/^https?:\/\//', '', $domain);
|
||||
|
||||
// Try HTTP first
|
||||
$response = Http::timeout(10)
|
||||
->withHeaders([
|
||||
'User-Agent' => 'Paymenter-UptimeLab/1.0',
|
||||
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
])
|
||||
->get('http://' . $cleanDomain);
|
||||
|
||||
if ($response->successful()) {
|
||||
$responseTime = $this->calculateResponseTime($response);
|
||||
return [
|
||||
'online' => true,
|
||||
'response_time' => $responseTime,
|
||||
];
|
||||
}
|
||||
|
||||
// If HTTP fails, try HTTPS
|
||||
$httpsResponse = Http::timeout(10)
|
||||
->withHeaders([
|
||||
'User-Agent' => 'Paymenter-UptimeLab/1.0',
|
||||
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
])
|
||||
->get('https://' . $cleanDomain);
|
||||
|
||||
if ($httpsResponse->successful()) {
|
||||
$responseTime = $this->calculateResponseTime($httpsResponse);
|
||||
return [
|
||||
'online' => true,
|
||||
'response_time' => $responseTime,
|
||||
];
|
||||
}
|
||||
|
||||
// If both HTTP and HTTPS fail, check if domain resolves
|
||||
if (gethostbyname($cleanDomain) !== $cleanDomain) {
|
||||
// Domain resolves but HTTP/HTTPS failed
|
||||
return [
|
||||
'online' => false,
|
||||
'response_time' => null,
|
||||
];
|
||||
}
|
||||
|
||||
// Domain doesn't resolve
|
||||
return [
|
||||
'online' => false,
|
||||
'response_time' => null,
|
||||
];
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('HTTP check failed for domain: ' . $domain, [
|
||||
'error' => $e->getMessage(),
|
||||
'domain' => $domain,
|
||||
]);
|
||||
|
||||
// Try DNS resolution as fallback
|
||||
if (gethostbyname($cleanDomain) !== $cleanDomain) {
|
||||
return [
|
||||
'online' => false, // Domain resolves but HTTP failed
|
||||
'response_time' => null,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'online' => false,
|
||||
'response_time' => null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate response time from HTTP response
|
||||
*/
|
||||
private function calculateResponseTime($response): ?int
|
||||
{
|
||||
try {
|
||||
// Try to get response time from handler stats
|
||||
if (method_exists($response, 'handlerStats')) {
|
||||
$stats = $response->handlerStats();
|
||||
if (isset($stats['total_time_us'])) {
|
||||
return (int) ($stats['total_time_us'] / 1000); // Convert to milliseconds
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: estimate response time based on current time
|
||||
return null;
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update server status
|
||||
*/
|
||||
public function updateServerStatus(UptimeServer $server, array $checkResult): void
|
||||
{
|
||||
$wasOnline = $server->status === 'online';
|
||||
$isOnline = $checkResult['online'];
|
||||
|
||||
$server->update([
|
||||
'status' => $isOnline ? 'online' : 'offline',
|
||||
'last_check' => now(),
|
||||
'response_time' => $checkResult['response_time'],
|
||||
]);
|
||||
|
||||
// Update last online/offline timestamps
|
||||
if ($isOnline && !$wasOnline) {
|
||||
$server->update(['last_online' => now()]);
|
||||
} elseif (!$isOnline && $wasOnline) {
|
||||
$server->update(['last_offline' => now()]);
|
||||
}
|
||||
|
||||
// Calculate uptime percentage (simplified calculation)
|
||||
$this->calculateUptimePercentage($server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate uptime percentage
|
||||
*/
|
||||
private function calculateUptimePercentage(UptimeServer $server): void
|
||||
{
|
||||
// Calculate uptime based on server status and monitoring history
|
||||
$now = now();
|
||||
$uptimePercentage = 0;
|
||||
|
||||
if ($server->status === 'online') {
|
||||
// Server is currently online
|
||||
if ($server->last_offline) {
|
||||
// Server has been offline before, calculate based on recent performance
|
||||
$lastOfflineTime = $server->last_offline;
|
||||
$timeSinceOffline = $now->diffInHours($lastOfflineTime);
|
||||
|
||||
if ($timeSinceOffline > 24) {
|
||||
// If server has been online for more than 24 hours, give high uptime
|
||||
$uptimePercentage = 99.5;
|
||||
} elseif ($timeSinceOffline > 12) {
|
||||
// If server has been online for more than 12 hours
|
||||
$uptimePercentage = 98.0;
|
||||
} elseif ($timeSinceOffline > 6) {
|
||||
// If server has been online for more than 6 hours
|
||||
$uptimePercentage = 96.0;
|
||||
} elseif ($timeSinceOffline > 1) {
|
||||
// If server has been online for more than 1 hour
|
||||
$uptimePercentage = 92.0;
|
||||
} else {
|
||||
// Server just came back online
|
||||
$uptimePercentage = 85.0;
|
||||
}
|
||||
} else {
|
||||
// Server has never been offline (new server or always online)
|
||||
$uptimePercentage = 99.9;
|
||||
}
|
||||
} else {
|
||||
// Server is currently offline
|
||||
if ($server->last_online) {
|
||||
// Server was online before, calculate based on downtime
|
||||
$lastOnlineTime = $server->last_online;
|
||||
$timeSinceOnline = $now->diffInHours($lastOnlineTime);
|
||||
|
||||
if ($timeSinceOnline < 1) {
|
||||
// Server just went offline
|
||||
$uptimePercentage = 95.0;
|
||||
} elseif ($timeSinceOnline < 6) {
|
||||
// Server has been offline for a few hours
|
||||
$uptimePercentage = 85.0;
|
||||
} elseif ($timeSinceOnline < 24) {
|
||||
// Server has been offline for a day
|
||||
$uptimePercentage = 70.0;
|
||||
} else {
|
||||
// Server has been offline for a long time
|
||||
$uptimePercentage = 50.0;
|
||||
}
|
||||
} else {
|
||||
// Server has never been online
|
||||
$uptimePercentage = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure percentage is between 0 and 100
|
||||
$uptimePercentage = max(0, min(100, $uptimePercentage));
|
||||
|
||||
$server->update([
|
||||
'uptime_percentage' => round($uptimePercentage, 2),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check all active servers
|
||||
*/
|
||||
public function checkAllServers(): void
|
||||
{
|
||||
$servers = UptimeServer::where('is_active', true)->get();
|
||||
|
||||
foreach ($servers as $server) {
|
||||
try {
|
||||
$checkResult = $this->checkServerStatus($server);
|
||||
$this->updateServerStatus($server, $checkResult);
|
||||
|
||||
Log::info('Server status checked', [
|
||||
'server' => $server->name,
|
||||
'status' => $checkResult['online'] ? 'online' : 'offline',
|
||||
'response_time' => $checkResult['response_time'],
|
||||
'server_type' => $server->server_type,
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Failed to check server: ' . $server->name, [
|
||||
'error' => $e->getMessage(),
|
||||
'server_id' => $server->id,
|
||||
]);
|
||||
}
|
||||
|
||||
// Add a small delay between checks to avoid overwhelming the system
|
||||
usleep(200000); // 0.1 second delay
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user