feat: support auto clean log files
This commit is contained in:
parent
7e3a85e9da
commit
e0d26203dd
@ -83,6 +83,10 @@ pub struct IVerge {
|
||||
/// proxy 页面布局 列数
|
||||
pub proxy_layout_column: Option<i32>,
|
||||
|
||||
/// 日志清理
|
||||
/// 0: 不清理; 1: 7天; 2: 30天; 3: 90天
|
||||
pub auto_log_clean: Option<i32>,
|
||||
|
||||
/// window size and position
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub window_size_position: Option<Vec<f64>>,
|
||||
@ -137,6 +141,7 @@ impl IVerge {
|
||||
auto_close_connection: Some(true),
|
||||
enable_builtin_enhanced: Some(true),
|
||||
enable_clash_fields: Some(true),
|
||||
auto_log_clean: Some(3),
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
@ -183,7 +188,7 @@ impl IVerge {
|
||||
patch!(enable_builtin_enhanced);
|
||||
patch!(proxy_layout_column);
|
||||
patch!(enable_clash_fields);
|
||||
|
||||
patch!(auto_log_clean);
|
||||
patch!(window_size_position);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
use crate::config::*;
|
||||
use crate::utils::{dirs, help};
|
||||
use anyhow::Result;
|
||||
use chrono::Local;
|
||||
use chrono::{DateTime, Local};
|
||||
use log::LevelFilter;
|
||||
use log4rs::append::console::ConsoleAppender;
|
||||
use log4rs::append::file::FileAppender;
|
||||
use log4rs::config::{Appender, Logger, Root};
|
||||
use log4rs::encode::pattern::PatternEncoder;
|
||||
use std::fs;
|
||||
use std::fs::{self, DirEntry};
|
||||
use std::str::FromStr;
|
||||
use tauri::PackageInfo;
|
||||
|
||||
/// initialize this instance's log file
|
||||
@ -69,6 +70,72 @@ fn init_log() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 删除log文件
|
||||
pub fn delete_log() -> Result<()> {
|
||||
let log_dir = dirs::app_logs_dir()?;
|
||||
if !log_dir.exists() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let auto_log_clean = {
|
||||
let verge = Config::verge();
|
||||
let verge = verge.data();
|
||||
verge.auto_log_clean.clone().unwrap_or(0)
|
||||
};
|
||||
|
||||
let day = match auto_log_clean {
|
||||
1 => 7,
|
||||
2 => 30,
|
||||
3 => 90,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
log::debug!(target: "app", "try to delete log files, day: {day}");
|
||||
|
||||
// %Y-%m-%d to NaiveDateTime
|
||||
let parse_time_str = |s: &str| {
|
||||
let sa: Vec<&str> = s.split('-').collect();
|
||||
if sa.len() != 4 {
|
||||
return Err(anyhow::anyhow!("invalid time str"));
|
||||
}
|
||||
|
||||
let year = i32::from_str(sa[0])?;
|
||||
let month = u32::from_str(sa[1])?;
|
||||
let day = u32::from_str(sa[2])?;
|
||||
let time = chrono::NaiveDate::from_ymd_opt(year, month, day)
|
||||
.ok_or(anyhow::anyhow!("invalid time str"))?
|
||||
.and_hms_opt(0, 0, 0)
|
||||
.ok_or(anyhow::anyhow!("invalid time str"))?;
|
||||
Ok(time)
|
||||
};
|
||||
|
||||
let process_file = |file: DirEntry| -> Result<()> {
|
||||
let file_name = file.file_name();
|
||||
let file_name = file_name.to_str().unwrap_or_default();
|
||||
|
||||
if file_name.ends_with(".log") {
|
||||
let now = Local::now();
|
||||
let created_time = parse_time_str(&file_name[0..file_name.len() - 4])?;
|
||||
let file_time = DateTime::<Local>::from_local(created_time, now.offset().clone());
|
||||
|
||||
let duration = now.signed_duration_since(file_time);
|
||||
if duration.num_days() > day {
|
||||
let file_path = file.path();
|
||||
let _ = fs::remove_file(file_path);
|
||||
log::info!(target: "app", "delete log file: {file_name}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
for file in fs::read_dir(&log_dir)? {
|
||||
if let Ok(file) = file {
|
||||
let _ = process_file(file);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initialize all the config files
|
||||
/// before tauri setup
|
||||
pub fn init_config() -> Result<()> {
|
||||
@ -78,6 +145,7 @@ pub fn init_config() -> Result<()> {
|
||||
}
|
||||
|
||||
let _ = init_log();
|
||||
let _ = delete_log();
|
||||
|
||||
crate::log_err!(dirs::app_home_dir().map(|app_dir| {
|
||||
if !app_dir.exists() {
|
||||
|
@ -25,6 +25,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
enableBuiltinEnhanced: true,
|
||||
proxyLayoutColumn: 6,
|
||||
defaultLatencyTest: "",
|
||||
autoLogClean: 0,
|
||||
});
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
@ -37,6 +38,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
enableBuiltinEnhanced: verge?.enable_builtin_enhanced ?? true,
|
||||
proxyLayoutColumn: verge?.proxy_layout_column || 6,
|
||||
defaultLatencyTest: verge?.default_latency_test || "",
|
||||
autoLogClean: verge?.auto_log_clean || 0,
|
||||
});
|
||||
},
|
||||
close: () => setOpen(false),
|
||||
@ -51,6 +53,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
enable_builtin_enhanced: values.enableBuiltinEnhanced,
|
||||
proxy_layout_column: values.proxyLayoutColumn,
|
||||
default_latency_test: values.defaultLatencyTest,
|
||||
auto_log_clean: values.autoLogClean as any,
|
||||
});
|
||||
setOpen(false);
|
||||
} catch (err: any) {
|
||||
@ -128,7 +131,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<ListItemText primary={t("Proxy Layout Column")} />
|
||||
<Select
|
||||
size="small"
|
||||
sx={{ width: 100, "> div": { py: "7.5px" } }}
|
||||
sx={{ width: 135, "> div": { py: "7.5px" } }}
|
||||
value={values.proxyLayoutColumn}
|
||||
onChange={(e) => {
|
||||
setValues((v) => ({
|
||||
@ -148,6 +151,32 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
</Select>
|
||||
</ListItem>
|
||||
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Auto Log Clean")} />
|
||||
<Select
|
||||
size="small"
|
||||
sx={{ width: 135, "> div": { py: "7.5px" } }}
|
||||
value={values.autoLogClean}
|
||||
onChange={(e) => {
|
||||
setValues((v) => ({
|
||||
...v,
|
||||
autoLogClean: e.target.value as number,
|
||||
}));
|
||||
}}
|
||||
>
|
||||
{[
|
||||
{ key: "Never Clean", value: 0 },
|
||||
{ key: "Retain 7 Days", value: 1 },
|
||||
{ key: "Retain 30 Days", value: 2 },
|
||||
{ key: "Retain 90 Days", value: 3 },
|
||||
].map((i) => (
|
||||
<MenuItem key={i.value} value={i.value}>
|
||||
{t(i.key)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</ListItem>
|
||||
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Default Latency Test")} />
|
||||
<TextField
|
||||
|
@ -125,5 +125,11 @@
|
||||
"Enable Clash Fields Filter": "Enable Clash Fields Filter",
|
||||
"Enable Builtin Enhanced": "Enable Builtin Enhanced",
|
||||
"Proxy Layout Column": "Proxy Layout Column",
|
||||
"Default Latency Test": "Default Latency Test"
|
||||
"Default Latency Test": "Default Latency Test",
|
||||
|
||||
"Auto Log Clean": "Auto Log Clean",
|
||||
"Never Clean": "Never Clean",
|
||||
"Retain 7 Days": "Retain 7 Days",
|
||||
"Retain 30 Days": "Retain 30 Days",
|
||||
"Retain 90 Days": "Retain 90 Days"
|
||||
}
|
||||
|
@ -125,5 +125,11 @@
|
||||
"Enable Clash Fields Filter": "开启Clash字段过滤",
|
||||
"Enable Builtin Enhanced": "开启内建增强功能",
|
||||
"Proxy Layout Column": "代理页布局列数",
|
||||
"Default Latency Test": "默认测试链接"
|
||||
"Default Latency Test": "默认测试链接",
|
||||
|
||||
"Auto Log Clean": "自动清理日志",
|
||||
"Never Clean": "不清理",
|
||||
"Retain 7 Days": "保留7天",
|
||||
"Retain 30 Days": "保留30天",
|
||||
"Retain 90 Days": "保留90天"
|
||||
}
|
||||
|
1
src/services/types.d.ts
vendored
1
src/services/types.d.ts
vendored
@ -186,6 +186,7 @@ interface IVergeConfig {
|
||||
default_latency_test?: string;
|
||||
enable_clash_fields?: boolean;
|
||||
enable_builtin_enhanced?: boolean;
|
||||
auto_log_clean?: 0 | 1 | 2 | 3;
|
||||
proxy_layout_column?: number;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user