63 lines
2.2 KiB
Rust
63 lines
2.2 KiB
Rust
use actix_web::{web, get, HttpResponse, Responder};
|
|
use sqlx::postgres::PgPool;
|
|
use serde::Serialize;
|
|
|
|
#[derive(Serialize)]
|
|
pub struct HealthResponse {
|
|
pub status: String,
|
|
pub database: String,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub error: Option<String>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub hint: Option<String>,
|
|
}
|
|
|
|
#[get("/health")]
|
|
pub async fn health_check(pool: web::Data<PgPool>) -> impl Responder {
|
|
match sqlx::query("SELECT 1").fetch_one(pool.get_ref()).await {
|
|
Ok(_) => {
|
|
HttpResponse::Ok().json(HealthResponse {
|
|
status: "ok".to_string(),
|
|
database: "connected".to_string(),
|
|
error: None,
|
|
hint: None,
|
|
})
|
|
}
|
|
Err(e) => {
|
|
let err_str = e.to_string();
|
|
let (error_msg, hint_msg) = if err_str.contains("connection refused") {
|
|
(
|
|
"无法连接到数据库".to_string(),
|
|
"请检查数据库服务是否运行".to_string(),
|
|
)
|
|
} else if err_str.contains("Connection timed out") {
|
|
(
|
|
"数据库连接超时".to_string(),
|
|
"请检查网络连接".to_string(),
|
|
)
|
|
} else if err_str.contains("does not exist") {
|
|
("数据库不存在".to_string(), "请检查数据库配置".to_string())
|
|
} else if err_str.contains("28P01") {
|
|
(
|
|
"数据库认证失败".to_string(),
|
|
"用户名或密码错误".to_string(),
|
|
)
|
|
} else {
|
|
(
|
|
"数据库连接失败".to_string(),
|
|
"请查看服务器日志获取详细信息".to_string(),
|
|
)
|
|
};
|
|
|
|
tracing::error!("健康检查失败: {:?}", e);
|
|
|
|
HttpResponse::ServiceUnavailable().json(HealthResponse {
|
|
status: "error".to_string(),
|
|
database: "disconnected".to_string(),
|
|
error: Some(error_msg),
|
|
hint: Some(hint_msg),
|
|
})
|
|
}
|
|
}
|
|
}
|