Team Ai
Apppublic

devin15/cursor2api-rust

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
logs.rs110 linesDownload Raw Back to route
1use crate::{2    app::{3        constant::{4            AUTHORIZATION_BEARER_PREFIX, CONTENT_TYPE_TEXT_HTML_WITH_UTF8,5            CONTENT_TYPE_TEXT_PLAIN_WITH_UTF8, ROUTE_LOGS_PATH,6        },7        lazy::AUTH_TOKEN,8        model::{AppConfig, AppState, PageContent, RequestLog},9    },10    common::{models::ApiStatus, utils::extract_token},11};12use axum::{13    body::Body,14    extract::State,15    http::{16        header::{AUTHORIZATION, CONTENT_TYPE},17        HeaderMap, StatusCode,18    },19    response::{IntoResponse, Response},20    Json,21};22use chrono::Local;23use std::sync::Arc;24use tokio::sync::Mutex;25 26// 日志处理27pub async fn handle_logs() -> impl IntoResponse {28    match AppConfig::get_page_content(ROUTE_LOGS_PATH).unwrap_or_default() {29        PageContent::Default => Response::builder()30            .header(CONTENT_TYPE, CONTENT_TYPE_TEXT_HTML_WITH_UTF8)31            .body(Body::from(32                include_str!("../../../static/logs.min.html").to_string(),33            ))34            .unwrap(),35        PageContent::Text(content) => Response::builder()36            .header(CONTENT_TYPE, CONTENT_TYPE_TEXT_PLAIN_WITH_UTF8)37            .body(Body::from(content.clone()))38            .unwrap(),39        PageContent::Html(content) => Response::builder()40            .header(CONTENT_TYPE, CONTENT_TYPE_TEXT_HTML_WITH_UTF8)41            .body(Body::from(content.clone()))42            .unwrap(),43    }44}45 46pub async fn handle_logs_post(47    State(state): State<Arc<Mutex<AppState>>>,48    headers: HeaderMap,49) -> Result<Json<LogsResponse>, StatusCode> {50    let auth_token = AUTH_TOKEN.as_str();51 52    // 获取认证头53    let auth_header = headers54        .get(AUTHORIZATION)55        .and_then(|h| h.to_str().ok())56        .and_then(|h| h.strip_prefix(AUTHORIZATION_BEARER_PREFIX))57        .ok_or(StatusCode::UNAUTHORIZED)?;58 59    let state = state.lock().await;60 61    // 如果是管理员token,返回所有日志62    if auth_header == auth_token {63        return Ok(Json(LogsResponse {64            status: ApiStatus::Success,65            total: state.total_requests,66            active: Some(state.active_requests),67            error: Some(state.error_requests),68            logs: state.request_logs.clone(),69            timestamp: Local::now().to_string(),70        }));71    }72 73    // 解析 token74    let token_part = extract_token(auth_header).ok_or(StatusCode::UNAUTHORIZED)?;75 76    // 否则筛选出token匹配的日志77    let filtered_logs: Vec<RequestLog> = state78        .request_logs79        .iter()80        .filter(|log| log.token_info.token == token_part)81        .cloned()82        .collect();83 84    // 如果没有匹配的日志,返回未授权错误85    if filtered_logs.is_empty() {86        return Err(StatusCode::UNAUTHORIZED);87    }88 89    Ok(Json(LogsResponse {90        status: ApiStatus::Success,91        total: filtered_logs.len() as u64,92        active: None,93        error: None,94        logs: filtered_logs,95        timestamp: Local::now().to_string(),96    }))97}98 99#[derive(serde::Serialize)]100pub struct LogsResponse {101    pub status: ApiStatus,102    pub total: u64,103    #[serde(skip_serializing_if = "Option::is_none")]104    pub active: Option<u64>,105    #[serde(skip_serializing_if = "Option::is_none")]106    pub error: Option<u64>,107    pub logs: Vec<RequestLog>,108    pub timestamp: String,109}110