-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathlogs.rs
More file actions
139 lines (118 loc) · 4.12 KB
/
Copy pathlogs.rs
File metadata and controls
139 lines (118 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Tauri commands for server log management
use crate::state::AppState;
use mcpmux_core::{AppSettingsService, LogLevel, ServerLog};
use serde::Serialize;
use tauri::State;
use tracing::{info, warn};
/// Helper to get the default space ID
async fn get_default_space_id(state: &AppState) -> Result<String, String> {
let space = state
.space_service
.get_active()
.await
.map_err(|e: anyhow::Error| e.to_string())?
.ok_or("No active space found")?;
Ok(space.id.to_string())
}
/// Server log entry for frontend
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ServerLogEntry {
pub timestamp: String,
pub level: String,
pub source: String,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<serde_json::Value>,
}
impl From<ServerLog> for ServerLogEntry {
fn from(log: ServerLog) -> Self {
Self {
timestamp: log.timestamp.to_rfc3339(),
level: log.level.as_str().to_string(),
source: log.source.as_str().to_string(),
message: log.message,
metadata: log.metadata,
}
}
}
/// Get recent logs for a server
#[tauri::command]
pub async fn get_server_logs(
server_id: String,
limit: Option<usize>,
level_filter: Option<String>,
state: State<'_, AppState>,
) -> Result<Vec<ServerLogEntry>, String> {
info!(
"[Logs] Getting logs for server {} (limit: {:?}, filter: {:?})",
server_id, limit, level_filter
);
let space_id = get_default_space_id(&state).await?;
// Parse level filter
let level = level_filter.and_then(|s| LogLevel::parse(&s));
// Get logs
let logs = state
.server_log_manager
.read_logs(&space_id, &server_id, limit.unwrap_or(100), level)
.await
.map_err(|e| {
warn!("[Logs] Failed to read logs for {}: {}", server_id, e);
format!("Failed to read logs: {}", e)
})?;
Ok(logs.into_iter().map(ServerLogEntry::from).collect())
}
/// Clear logs for a server
#[tauri::command]
pub async fn clear_server_logs(
server_id: String,
state: State<'_, AppState>,
) -> Result<(), String> {
info!("[Logs] Clearing logs for server {}", server_id);
let space_id = get_default_space_id(&state).await?;
state
.server_log_manager
.clear_logs(&space_id, &server_id)
.await
.map_err(|e| {
warn!("[Logs] Failed to clear logs for {}: {}", server_id, e);
format!("Failed to clear logs: {}", e)
})?;
info!("[Logs] Cleared logs for server {}", server_id);
Ok(())
}
/// Get log file path for a server (for external viewers)
#[tauri::command]
pub async fn get_server_log_file(
server_id: String,
state: State<'_, AppState>,
) -> Result<String, String> {
let space_id = get_default_space_id(&state).await?;
let path = state.server_log_manager.get_log_file(&space_id, &server_id);
Ok(path.to_string_lossy().to_string())
}
/// Get log retention period in days (0 = keep forever)
#[tauri::command]
pub async fn get_log_retention_days(state: State<'_, AppState>) -> Result<u32, String> {
let settings = AppSettingsService::new(state.settings_repository.clone());
Ok(settings.get_log_retention_days().await)
}
/// Set log retention period in days (0 = keep forever)
#[tauri::command]
pub async fn set_log_retention_days(days: u32, state: State<'_, AppState>) -> Result<(), String> {
info!("[Logs] Setting log retention to {} days", days);
let settings = AppSettingsService::new(state.settings_repository.clone());
settings
.set_log_retention_days(days)
.await
.map_err(|e| format!("Failed to save log retention setting: {}", e))?;
// Run cleanup immediately with the new setting if retention is enabled
if days > 0 {
match state.server_log_manager.cleanup_logs_older_than(days).await {
Ok(n) if n > 0 => info!("[Logs] Cleaned up {} old log file(s)", n),
Ok(_) => {}
Err(e) => warn!("[Logs] Cleanup after setting change failed: {}", e),
}
}
Ok(())
}