Files
ismysiteup.online/app/Jobs/CheckUptime.php
T
2026-03-28 22:07:06 +02:00

102 lines
3.1 KiB
PHP

<?php
namespace App\Jobs;
use App\Models\Site;
use App\Models\UptimeCheck;
use App\Notifications\UptimeAlert;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Bus\Batchable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
class CheckUptime implements ShouldQueue
{
use Queueable, Batchable;
/**
* Create a new job instance.
*/
public function __construct(
public Site $site
) {
}
/**
* Execute the job.
*/
public function handle(): void
{
$client = new Client([
'timeout' => 5,
'connect_timeout' => 5,
'allow_redirects' => [
'max' => 5,
'track_redirects' => true,
],
'http_errors' => false, // Don't throw exceptions on 4xx/5xx responses
]);
$statusCode = null;
$responseTime = null;
$startTime = microtime(true);
try {
// Send HEAD request for faster checks
$response = $client->head($this->site->url);
$endTime = microtime(true);
$responseTime = (int) round(($endTime - $startTime) * 1000); // Convert to milliseconds
$statusCode = $response->getStatusCode();
} catch (ConnectException $e) {
// Connection timeout or DNS failure
Log::info("Connection failed for site {$this->site->id}: {$e->getMessage()}");
$statusCode = null;
$responseTime = null;
} catch (RequestException $e) {
// HTTP error occurred
$endTime = microtime(true);
$responseTime = (int) round(($endTime - $startTime) * 1000);
$statusCode = $e->getResponse() ? $e->getResponse()->getStatusCode() : null;
Log::info("Request failed for site {$this->site->id}: HTTP {$statusCode}");
} catch (\Exception $e) {
// Any other exception
Log::error("Unexpected error checking site {$this->site->id}: {$e->getMessage()}");
$statusCode = null;
$responseTime = null;
}
// Store the uptime check result
UptimeCheck::create([
'site_id' => $this->site->id,
'check_type' => 'http',
'status_code' => $statusCode,
'response_time_ms' => $responseTime,
'is_online' => $statusCode !== null && $statusCode < 400,
'checked_at' => now(),
]);
// Send notification if site is down (status >= 400 or unreachable)
if ($statusCode === null || $statusCode >= 400) {
$this->site->user->notify(new UptimeAlert(
$this->site,
$statusCode,
$responseTime
));
Log::warning("Downtime alert sent for site {$this->site->id}: HTTP {$statusCode}");
}
Log::info("Uptime check completed for site {$this->site->id} ({$this->site->url}): HTTP {$statusCode}, {$responseTime}ms");
}
}