This commit is contained in:
Hugh Kaznowski
2026-09-05 12:23:46 +01:00
parent 818f8d09ea
commit 68548911bc
34 changed files with 3262 additions and 4 deletions
+66
View File
@@ -0,0 +1,66 @@
use crate::engine::{EngineHandle, EngineMessage, EngineQuery, EngineResponse};
use crate::dto::{LogsParams, TimelineParams};
use axum::extract::{Query, State};
use axum::http::StatusCode;
use axum::response::{IntoResponse, Json};
use axum::routing::get;
use axum::Router;
use tokio::sync::oneshot;
use tower_http::services::{ServeDir, ServeFile};
#[derive(Clone)]
struct ApiState {
engine: EngineHandle,
}
pub fn router(engine: EngineHandle, static_dir: &str) -> Router {
let state = ApiState { engine };
let index_html = format!("{static_dir}/index.html");
let static_service = ServeDir::new(static_dir).fallback(ServeFile::new(index_html));
Router::new()
.route("/api/logs", get(get_logs))
.route("/api/timeline", get(get_timeline))
.route("/api/stats", get(get_stats))
.with_state(state)
.fallback_service(static_service)
}
async fn ask(engine: &EngineHandle, query: EngineQuery) -> Result<EngineResponse, StatusCode> {
let (respond_to, response) = oneshot::channel();
engine
.send(EngineMessage::Query { query, respond_to })
.await
.map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?;
response.await.map_err(|_| StatusCode::SERVICE_UNAVAILABLE)
}
async fn get_logs(
State(state): State<ApiState>,
Query(params): Query<LogsParams>,
) -> impl IntoResponse {
match ask(&state.engine, EngineQuery::Logs(params)).await {
Ok(EngineResponse::Logs(entries)) => Json(entries).into_response(),
Ok(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
Err(status) => status.into_response(),
}
}
async fn get_timeline(
State(state): State<ApiState>,
Query(params): Query<TimelineParams>,
) -> impl IntoResponse {
match ask(&state.engine, EngineQuery::Timeline(params)).await {
Ok(EngineResponse::Timeline(buckets)) => Json(buckets).into_response(),
Ok(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
Err(status) => status.into_response(),
}
}
async fn get_stats(State(state): State<ApiState>) -> impl IntoResponse {
match ask(&state.engine, EngineQuery::Stats).await {
Ok(EngineResponse::Stats(stats)) => Json(stats).into_response(),
Ok(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
Err(status) => status.into_response(),
}
}