diff --git a/UPDATELOG.md b/UPDATELOG.md index d8ee0782..61256bc7 100644 --- a/UPDATELOG.md +++ b/UPDATELOG.md @@ -1,5 +1,9 @@ ## v2.4.3 +### ✨ 新增功能 + +- 支持前端修改日志(最大文件大小、最大保留数量) + ### 🚀 优化改进 - 重构并简化服务模式启动检测流程,消除重复检测 diff --git a/src-tauri/src/config/verge.rs b/src-tauri/src/config/verge.rs index cda71e72..4a02bc97 100644 --- a/src-tauri/src/config/verge.rs +++ b/src-tauri/src/config/verge.rs @@ -14,6 +14,12 @@ pub struct IVerge { /// silent | error | warn | info | debug | trace pub app_log_level: Option, + /// app log max size in KB + pub app_log_max_size: Option, + + /// app log max count + pub app_log_max_count: Option, + // i18n pub language: Option, @@ -350,6 +356,8 @@ impl IVerge { pub fn template() -> Self { Self { + app_log_max_size: Some(128), + app_log_max_count: Some(8), clash_core: Some("verge-mihomo".into()), language: Some(Self::get_system_language()), theme_mode: Some("system".into()), @@ -426,6 +434,9 @@ impl IVerge { } patch!(app_log_level); + patch!(app_log_max_size); + patch!(app_log_max_count); + patch!(language); patch!(theme_mode); patch!(tray_event); @@ -524,6 +535,8 @@ impl IVerge { #[derive(Debug, Clone, Serialize)] pub struct IVergeResponse { pub app_log_level: Option, + pub app_log_max_size: Option, + pub app_log_max_count: Option, pub language: Option, pub theme_mode: Option, pub tray_event: Option, @@ -595,6 +608,8 @@ impl From for IVergeResponse { let valid_clash_core = verge.get_valid_clash_core(); Self { app_log_level: verge.app_log_level, + app_log_max_size: verge.app_log_max_size, + app_log_max_count: verge.app_log_max_count, language: verge.language, theme_mode: verge.theme_mode, tray_event: verge.tray_event, diff --git a/src-tauri/src/utils/init.rs b/src-tauri/src/utils/init.rs index d3c7b7e4..325fbbb7 100644 --- a/src-tauri/src/utils/init.rs +++ b/src-tauri/src/utils/init.rs @@ -22,7 +22,16 @@ use tokio::fs::DirEntry; /// initialize this instance's log file #[cfg(not(feature = "tauri-dev"))] pub async fn init_logger() -> Result<()> { - let log_level = Config::verge().await.latest_ref().get_log_level(); + // TODO 提供 runtime 级别实时修改 + let (log_level, log_max_size, log_max_count) = { + let verge_guard = Config::verge().await; + let verge = verge_guard.latest_ref(); + ( + verge.get_log_level(), + verge.app_log_max_size.unwrap_or(128), + verge.app_log_max_count.unwrap_or(8), + ) + }; let log_dir = dirs::app_logs_dir()?; let logger = Logger::with(LogSpecification::from(log_level)) @@ -31,14 +40,12 @@ pub async fn init_logger() -> Result<()> { .format(console_colored_format) .format_for_files(file_format) .rotate( - // ? 总是保持单个日志最大 10 MB - Criterion::Size(10 * 1024 * 1024), + Criterion::Size(log_max_size * 1024), flexi_logger::Naming::TimestampsCustomFormat { current_infix: Some("latest"), format: "%Y-%m-%d_%H-%M-%S", }, - // TODO 提供前端设置最大保留文件数量 - Cleanup::Never, + Cleanup::KeepLogFiles(log_max_count), ) .filter(Box::new(NoExternModule)); diff --git a/src/components/setting/mods/misc-viewer.tsx b/src/components/setting/mods/misc-viewer.tsx index 02ca5369..b0048fd8 100644 --- a/src/components/setting/mods/misc-viewer.tsx +++ b/src/components/setting/mods/misc-viewer.tsx @@ -23,6 +23,8 @@ export const MiscViewer = forwardRef((props, ref) => { const [open, setOpen] = useState(false); const [values, setValues] = useState({ appLogLevel: "warn", + appLogMaxSize: 8, + appLogMaxCount: 12, autoCloseConnection: true, autoCheckUpdate: true, enableBuiltinEnhanced: true, @@ -37,6 +39,8 @@ export const MiscViewer = forwardRef((props, ref) => { setOpen(true); setValues({ appLogLevel: verge?.app_log_level ?? "warn", + appLogMaxSize: verge?.app_log_max_size ?? 128, + appLogMaxCount: verge?.app_log_max_count ?? 8, autoCloseConnection: verge?.auto_close_connection ?? true, autoCheckUpdate: verge?.auto_check_update ?? true, enableBuiltinEnhanced: verge?.enable_builtin_enhanced ?? true, @@ -100,6 +104,66 @@ export const MiscViewer = forwardRef((props, ref) => { + + + + setValues((v) => ({ + ...v, + appLogMaxSize: Math.max(1, parseInt(e.target.value) || 128), + })) + } + slotProps={{ + input: { + endAdornment: ( + {t("KB")} + ), + }, + }} + /> + + + + + + setValues((v) => ({ + ...v, + appLogMaxCount: Math.max(1, parseInt(e.target.value) || 1), + })) + } + slotProps={{ + input: { + endAdornment: ( + {t("Files")} + ), + }, + }} + /> + + ((props, ref) => { div": { py: "7.5px" } }} + sx={{ width: 160, "> div": { py: "7.5px" } }} value={values.autoLogClean} onChange={(e) => setValues((v) => ({ diff --git a/src/services/types.d.ts b/src/services/types.d.ts index 752c581d..254f7590 100644 --- a/src/services/types.d.ts +++ b/src/services/types.d.ts @@ -778,6 +778,8 @@ interface IProxyConfig interface IVergeConfig { app_log_level?: "trace" | "debug" | "info" | "warn" | "error" | string; + app_log_max_size?: number; // KB + app_log_max_count?: number; language?: string; tray_event?: | "main_window"