syspulse_core/health/
http.rs1use async_trait::async_trait;
2use std::time::Duration;
3
4use super::HealthChecker;
5use crate::daemon::{HealthCheckSpec, HealthStatus};
6use crate::error::{Result, SyspulseError};
7
8pub struct HttpHealthChecker {
9 spec: HealthCheckSpec,
10 client: reqwest::Client,
11}
12
13impl HttpHealthChecker {
14 pub fn new(spec: HealthCheckSpec) -> Self {
15 let client = reqwest::Client::builder()
16 .timeout(Duration::from_secs(spec.timeout_secs))
17 .build()
18 .unwrap_or_default();
19 Self { spec, client }
20 }
21}
22
23#[async_trait]
24impl HealthChecker for HttpHealthChecker {
25 async fn check(&self) -> Result<HealthStatus> {
26 match self.client.get(&self.spec.target).send().await {
27 Ok(resp) => {
28 if resp.status().is_success() {
29 Ok(HealthStatus::Healthy)
30 } else {
31 tracing::debug!(
32 url = %self.spec.target,
33 status = %resp.status(),
34 "HTTP health check returned non-2xx"
35 );
36 Ok(HealthStatus::Unhealthy)
37 }
38 }
39 Err(e) => {
40 tracing::debug!(
41 url = %self.spec.target,
42 error = %e,
43 "HTTP health check failed"
44 );
45 if e.is_timeout() {
46 Err(SyspulseError::Timeout(Duration::from_secs(
47 self.spec.timeout_secs,
48 )))
49 } else {
50 Ok(HealthStatus::Unhealthy)
51 }
52 }
53 }
54 }
55
56 fn spec(&self) -> &HealthCheckSpec {
57 &self.spec
58 }
59}