Consolidate HTTP checking and improve display formatting
- Change site latency timeout from 5s to 2s for faster error detection - Replace curl with reqwest for external connectivity checks (consistent timeouts) - Remove unused gitea-specific monitoring functionality - Update dashboard: show 'unreachable' for latency > 2000ms, add arrows (→) between site and latency - Add percentage signs to CPU metrics display - All HTTP requests now use reqwest with 2-second timeouts
This commit is contained in:
parent
819ca4ad73
commit
0cb69ea8fa
@ -651,7 +651,6 @@ impl ServiceCollector {
|
|||||||
"postgresql" | "postgres" => self.get_postgres_connections().await.map(|s| vec![s]),
|
"postgresql" | "postgres" => self.get_postgres_connections().await.map(|s| vec![s]),
|
||||||
"mysql" | "mariadb" => self.get_mysql_connections().await.map(|s| vec![s]),
|
"mysql" | "mariadb" => self.get_mysql_connections().await.map(|s| vec![s]),
|
||||||
"redis" | "redis-immich" => self.get_redis_info().await.map(|s| vec![s]),
|
"redis" | "redis-immich" => self.get_redis_info().await.map(|s| vec![s]),
|
||||||
"gitea" => self.get_gitea_info().await.map(|s| vec![s]),
|
|
||||||
"immich-server" => self.get_immich_info().await.map(|s| vec![s]),
|
"immich-server" => self.get_immich_info().await.map(|s| vec![s]),
|
||||||
"vaultwarden" => self.get_vaultwarden_info().await.map(|s| vec![s]),
|
"vaultwarden" => self.get_vaultwarden_info().await.map(|s| vec![s]),
|
||||||
"unifi" => self.get_unifi_info().await.map(|s| vec![s]),
|
"unifi" => self.get_unifi_info().await.map(|s| vec![s]),
|
||||||
@ -843,7 +842,7 @@ impl ServiceCollector {
|
|||||||
|
|
||||||
// Create HTTP client with short timeout
|
// Create HTTP client with short timeout
|
||||||
let client = match reqwest::Client::builder()
|
let client = match reqwest::Client::builder()
|
||||||
.timeout(Duration::from_secs(5))
|
.timeout(Duration::from_secs(2))
|
||||||
.build()
|
.build()
|
||||||
{
|
{
|
||||||
Ok(client) => client,
|
Ok(client) => client,
|
||||||
@ -1050,31 +1049,28 @@ impl ServiceCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn check_site_accessibility(&self, hostname: &str) -> bool {
|
async fn check_site_accessibility(&self, hostname: &str) -> bool {
|
||||||
|
// Create HTTP client with same timeout as site latency checks
|
||||||
|
let client = match reqwest::Client::builder()
|
||||||
|
.timeout(Duration::from_secs(2))
|
||||||
|
.build()
|
||||||
|
{
|
||||||
|
Ok(client) => client,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
|
|
||||||
// Try HTTPS first, then HTTP
|
// Try HTTPS first, then HTTP
|
||||||
for scheme in ["https", "http"] {
|
for scheme in ["https", "http"] {
|
||||||
let url = format!("{}://{}", scheme, hostname);
|
let url = format!("{}://{}", scheme, hostname);
|
||||||
|
|
||||||
match tokio::time::timeout(
|
match client.get(&url).send().await {
|
||||||
Duration::from_secs(5),
|
Ok(response) => {
|
||||||
Command::new("/run/current-system/sw/bin/curl")
|
let status = response.status().as_u16();
|
||||||
.args(["-s", "-I", "--max-time", "3", &url])
|
// Check for successful HTTP status codes (same logic as before)
|
||||||
.stdout(Stdio::piped())
|
if status == 200 || status == 301 || status == 302 || status == 403 {
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.output()
|
|
||||||
).await {
|
|
||||||
Ok(Ok(output)) if output.status.success() => {
|
|
||||||
let response = String::from_utf8_lossy(&output.stdout);
|
|
||||||
// Check for successful HTTP status codes
|
|
||||||
if response.contains("HTTP/") && (
|
|
||||||
response.contains(" 200 ") ||
|
|
||||||
response.contains(" 301 ") ||
|
|
||||||
response.contains(" 302 ") ||
|
|
||||||
response.contains(" 403 ") // Some sites return 403 but are still "accessible"
|
|
||||||
) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => continue,
|
Err(_) => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1139,44 +1135,6 @@ impl ServiceCollector {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_gitea_info(&self) -> Option<String> {
|
|
||||||
// Try to get gitea stats from API (if accessible)
|
|
||||||
let output = Command::new("/run/current-system/sw/bin/curl")
|
|
||||||
.args(["-s", "-f", "-m", "2", "http://localhost:3000/api/v1/repos/search?limit=1"])
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.output()
|
|
||||||
.await
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
if output.status.success() {
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
if let Ok(json) = serde_json::from_str::<serde_json::Value>(&stdout) {
|
|
||||||
if let Some(total_count) = json["total_count"].as_u64() {
|
|
||||||
return Some(format!("{} repositories", total_count));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback: check HTTP connections on port 3000
|
|
||||||
let output = Command::new("/run/current-system/sw/bin/ss")
|
|
||||||
.args(["-tn", "state", "established", "dport", "= :3000"])
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.output()
|
|
||||||
.await
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
if output.status.success() {
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let connection_count = stdout.lines().count().saturating_sub(1);
|
|
||||||
if connection_count > 0 {
|
|
||||||
return Some(format!("{} connections", connection_count));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_immich_info(&self) -> Option<String> {
|
async fn get_immich_info(&self) -> Option<String> {
|
||||||
// Check HTTP connections - Immich runs on port 8084 (from nginx proxy config)
|
// Check HTTP connections - Immich runs on port 8084 (from nginx proxy config)
|
||||||
|
|||||||
@ -110,9 +110,9 @@ fn render_metrics(
|
|||||||
let service_name_with_latency = if let Some(parent) = &svc.sub_service {
|
let service_name_with_latency = if let Some(parent) = &svc.sub_service {
|
||||||
if parent == "nginx" {
|
if parent == "nginx" {
|
||||||
match &svc.latency_ms {
|
match &svc.latency_ms {
|
||||||
Some(latency) if *latency >= 5000.0 => format!("{} unreachable", svc.name), // Timeout (5s+)
|
Some(latency) if *latency >= 2000.0 => format!("{} → unreachable", svc.name), // Timeout (2s+)
|
||||||
Some(latency) => format!("{} {:.0}ms", svc.name, latency),
|
Some(latency) => format!("{} → {:.0}ms", svc.name, latency),
|
||||||
None => format!("{} unreachable", svc.name), // Connection failed
|
None => format!("{} → unreachable", svc.name), // Connection failed
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
svc.name.clone()
|
svc.name.clone()
|
||||||
@ -178,9 +178,9 @@ fn format_memory_value(used: f32, quota: f32) -> String {
|
|||||||
|
|
||||||
fn format_cpu_value(cpu_percent: f32) -> String {
|
fn format_cpu_value(cpu_percent: f32) -> String {
|
||||||
if cpu_percent >= 0.1 {
|
if cpu_percent >= 0.1 {
|
||||||
format!("{:.1}", cpu_percent)
|
format!("{:.1}%", cpu_percent)
|
||||||
} else {
|
} else {
|
||||||
"0.0".to_string()
|
"0.0%".to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user