Skip to content

Commit be9c75b

Browse files
committed
Add a /health HTTP endpoint
1 parent c76c137 commit be9c75b

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

src/metrics.rs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,22 @@ use crate::varz::*;
1818

1919
const METRICS_CONNECTION_TIMEOUT_SECS: u64 = 10;
2020
const METRICS_MAX_CONCURRENT_CONNECTIONS: u32 = 2;
21+
const HEALTH_PATH: &str = "/health";
2122

2223
type BoxBody = http_body_util::Full<hyper::body::Bytes>;
2324

2425
async fn handle_client_connection(
2526
req: Request<hyper::body::Incoming>,
26-
_varz: Varz,
27+
varz: Varz,
2728
path: Arc<String>,
2829
) -> Result<Response<BoxBody>, Error> {
29-
if req.uri().path() != path.as_str() {
30+
let request_path = req.uri().path();
31+
32+
if request_path == HEALTH_PATH {
33+
return handle_health_request(&varz);
34+
}
35+
36+
if request_path != path.as_str() {
3037
return Ok(Response::builder().status(StatusCode::NOT_FOUND).body(
3138
http_body_util::Full::new(hyper::body::Bytes::from("404 Not Found")),
3239
)?);
@@ -41,6 +48,38 @@ async fn handle_client_connection(
4148
.body(http_body_util::Full::new(hyper::body::Bytes::from(buffer)))?)
4249
}
4350

51+
fn handle_health_request(varz: &Varz) -> Result<Response<BoxBody>, Error> {
52+
let uptime_secs = varz.start_instant.0.elapsed().as_secs();
53+
54+
let upstream_sent = varz.upstream_sent.get() as u64;
55+
let upstream_received = varz.upstream_received.get() as u64;
56+
let upstream_errors = varz.upstream_errors.get() as u64;
57+
58+
let upstream_status = if upstream_sent == 0 {
59+
"unknown"
60+
} else if upstream_errors > upstream_received {
61+
"degraded"
62+
} else {
63+
"healthy"
64+
};
65+
66+
let status = if upstream_status == "degraded" {
67+
"degraded"
68+
} else {
69+
"healthy"
70+
};
71+
72+
let body = format!(
73+
r#"{{"status":"{}","uptime_secs":{},"upstream":{{"status":"{}","sent":{},"received":{},"errors":{}}}}}"#,
74+
status, uptime_secs, upstream_status, upstream_sent, upstream_received, upstream_errors
75+
);
76+
77+
Ok(Response::builder()
78+
.status(StatusCode::OK)
79+
.header(CONTENT_TYPE, "application/json")
80+
.body(http_body_util::Full::new(hyper::body::Bytes::from(body)))?)
81+
}
82+
4483
pub async fn prometheus_service(
4584
varz: Varz,
4685
metrics_config: MetricsConfig,

0 commit comments

Comments
 (0)