feat: refine request log

This commit is contained in:
2025-12-06 21:49:51 +08:00
parent 1941e6bcaf
commit 8be7af6815
7 changed files with 248 additions and 87 deletions

View File

@@ -1,15 +1,17 @@
use std::sync::Arc;
use axum::{
Json,
extract::{Path, State},
extract::{Path, Query, State},
http::StatusCode,
Json,
};
use serde::Deserialize;
use tracing::error;
use crate::{
AppContext, auth,
auth,
db::{self, models::RequestLog},
AppContext,
};
use super::models::*;
@@ -237,7 +239,10 @@ pub async fn update_rule(
{
Ok(_) => match db::repositories::rules::find_by_id(&state.db, id).await {
Ok(Some(rule)) => Ok(Json(rule.into())),
_ => Err((StatusCode::NOT_FOUND, Json(ApiError::new("Rule not found")))),
_ => Err((
StatusCode::NOT_FOUND,
Json(ApiError::new("Rule not found")),
)),
},
Err(e) => {
error!("Failed to update rule: {}", e);
@@ -310,11 +315,25 @@ pub async fn verify_command(
}
}
}
// Log handlers
#[derive(Deserialize)]
pub struct ListLogsParams {
pub method: Option<String>,
pub search: Option<String>,
}
pub async fn list_logs(
State(state): State<Arc<AppContext>>,
Query(params): Query<ListLogsParams>,
) -> Result<Json<Vec<RequestLog>>, (StatusCode, Json<ApiError>)> {
match db::repositories::logs::list_all(&state.db).await {
match db::repositories::logs::list(
&state.db,
params.method.as_deref(),
params.search.as_deref(),
)
.await
{
Ok(logs) => Ok(Json(logs)),
Err(e) => {
error!("Failed to list logs: {}", e);

View File

@@ -1,13 +1,37 @@
use crate::db::models::RequestLog;
use serde_json::Value;
use sqlx::SqlitePool;
use sqlx::{QueryBuilder, SqlitePool};
pub async fn list_all(pool: &SqlitePool) -> anyhow::Result<Vec<RequestLog>> {
Ok(
sqlx::query_as::<_, RequestLog>("SELECT * FROM request_logs ORDER BY created_at")
.fetch_all(pool)
.await?,
)
pub async fn list(
pool: &SqlitePool,
method: Option<&str>,
search: Option<&str>,
) -> anyhow::Result<Vec<RequestLog>> {
let mut builder: QueryBuilder<sqlx::Sqlite> =
QueryBuilder::new("SELECT * FROM request_logs");
if let Some(method_val) = method {
builder.push(" WHERE method = ");
builder.push_bind(method_val);
}
if let Some(search_val) = search {
let pattern = format!("%{}%", search_val);
if method.is_some() {
builder.push(" AND (request_body LIKE ");
} else {
builder.push(" WHERE (request_body LIKE ");
}
builder.push_bind(pattern.clone());
builder.push(" OR response_body LIKE ");
builder.push_bind(pattern);
builder.push(")");
}
builder.push(" ORDER BY created_at DESC");
let query = builder.build_query_as();
Ok(query.fetch_all(pool).await?)
}
pub async fn create(