CluPilotCloud/app/Services/Monitoring/HttpMonitoringClient.php

72 lines
2.6 KiB
PHP

<?php
namespace App\Services\Monitoring;
use Illuminate\Support\Facades\Http;
/**
* Registers uptime targets with the configured monitoring service. If none is
* configured, returns a deterministic id (no-op) so provisioning still records a
* stable breadcrumb. Not unit-tested (live I/O).
*/
class HttpMonitoringClient implements MonitoringClient
{
public function registerTarget(string $name, string $url): string
{
$endpoint = (string) config('services.monitoring.url');
if (blank($endpoint)) {
return 'mon-'.substr(sha1($url), 0, 12);
}
$base = rtrim($endpoint, '/');
$token = (string) config('services.monitoring.token');
// Idempotent: reuse an existing monitor for this URL rather than creating
// a duplicate when a crash retries after a prior successful POST.
$existing = collect(Http::withToken($token)->get($base.'/monitors')->throw()->json('monitors', []))
->first(fn ($monitor) => ($monitor['url'] ?? null) === $url);
if ($existing !== null) {
return (string) $existing['id'];
}
return (string) Http::withToken($token)
->post($base.'/monitors', ['friendly_name' => $name, 'url' => $url, 'type' => 'https'])
->throw()->json('monitor.id');
}
public function isHealthy(string $externalId): bool
{
// Unknown counts as healthy HERE, and only here: this is the
// provisioning acceptance check, which must not fail a delivery because
// monitoring is not set up.
return $this->health($externalId) ?? true;
}
public function health(string $externalId): ?bool
{
$endpoint = (string) config('services.monitoring.url');
if (blank($endpoint)) {
return null; // nothing is watching, which is not the same as healthy
}
try {
$monitor = Http::withToken((string) config('services.monitoring.token'))
->get(rtrim($endpoint, '/').'/monitors/'.$externalId)->throw()->json('monitor', []);
} catch (\Throwable) {
return null; // the monitor is unreachable, which says nothing about the instance
}
return ($monitor['status'] ?? '') === 'up';
}
public function deregisterTarget(string $externalId): void
{
$endpoint = (string) config('services.monitoring.url');
if (filled($endpoint)) {
Http::withToken((string) config('services.monitoring.token'))
->delete(rtrim($endpoint, '/').'/monitors/'.$externalId)->throw();
}
}
}