mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 08:45:41 +08:00
feat: add clash_verge_logger and clash_verge_service_ipc dependencies; refactor logging and process management
This commit is contained in:
@@ -144,6 +144,7 @@ pub fn service_path() -> Result<PathBuf> {
|
||||
Ok(res_dir.join("clash-verge-service.exe"))
|
||||
}
|
||||
|
||||
// TODO 迁移 Service日志后删除
|
||||
pub fn service_log_file() -> Result<PathBuf> {
|
||||
use chrono::Local;
|
||||
|
||||
@@ -158,6 +159,20 @@ pub fn service_log_file() -> Result<PathBuf> {
|
||||
Ok(log_file)
|
||||
}
|
||||
|
||||
pub fn sidecar_log_dir() -> Result<PathBuf> {
|
||||
let log_dir = app_logs_dir()?.join("sidecar");
|
||||
let _ = std::fs::create_dir_all(&log_dir);
|
||||
|
||||
Ok(log_dir)
|
||||
}
|
||||
|
||||
pub fn service_log_dir() -> Result<PathBuf> {
|
||||
let log_dir = app_logs_dir()?.join("service");
|
||||
let _ = std::fs::create_dir_all(&log_dir);
|
||||
|
||||
Ok(log_dir)
|
||||
}
|
||||
|
||||
pub fn path_to_str(path: &PathBuf) -> Result<&str> {
|
||||
let path_str = path
|
||||
.as_os_str()
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(feature = "tauri-dev"))] {
|
||||
use crate::utils::logging::{console_colored_format, file_format, NoExternModule};
|
||||
use flexi_logger::{Cleanup, Criterion, Duplicate, FileSpec, LogSpecification, Logger};
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
use crate::utils::logging::NoModuleFilter;
|
||||
use crate::{
|
||||
config::*,
|
||||
core::handle,
|
||||
logging,
|
||||
process::AsyncHandler,
|
||||
utils::{dirs, help, logging::Type},
|
||||
utils::{
|
||||
dirs::{self, service_log_dir, sidecar_log_dir},
|
||||
help,
|
||||
logging::Type,
|
||||
},
|
||||
};
|
||||
use anyhow::Result;
|
||||
use chrono::{Local, TimeZone};
|
||||
use clash_verge_service_ipc::WriterConfig;
|
||||
use flexi_logger::writers::FileLogWriter;
|
||||
use flexi_logger::{Cleanup, Criterion, FileSpec};
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
use flexi_logger::{Duplicate, LogSpecBuilder, Logger};
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
use tokio::fs;
|
||||
@@ -34,11 +38,13 @@ pub async fn init_logger() -> Result<()> {
|
||||
};
|
||||
|
||||
let log_dir = dirs::app_logs_dir()?;
|
||||
let logger = Logger::with(LogSpecification::from(log_level))
|
||||
let spec = LogSpecBuilder::new().default(log_level).build();
|
||||
|
||||
let logger = Logger::with(spec)
|
||||
.log_to_file(FileSpec::default().directory(log_dir).basename(""))
|
||||
.duplicate_to_stdout(Duplicate::Debug)
|
||||
.format(console_colored_format)
|
||||
.format_for_files(file_format)
|
||||
.format(clash_verge_logger::console_format)
|
||||
.format_for_files(clash_verge_logger::file_format_with_level)
|
||||
.rotate(
|
||||
Criterion::Size(log_max_size * 1024),
|
||||
flexi_logger::Naming::TimestampsCustomFormat {
|
||||
@@ -47,7 +53,7 @@ pub async fn init_logger() -> Result<()> {
|
||||
},
|
||||
Cleanup::KeepLogFiles(log_max_count),
|
||||
)
|
||||
.filter(Box::new(NoExternModule));
|
||||
.filter(Box::new(NoModuleFilter(&["wry", "tauri"])));
|
||||
|
||||
let _handle = logger.start()?;
|
||||
|
||||
@@ -59,6 +65,54 @@ pub async fn init_logger() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn sidecar_writer() -> Result<FileLogWriter> {
|
||||
let (log_max_size, log_max_count) = {
|
||||
let verge_guard = Config::verge().await;
|
||||
let verge = verge_guard.latest_ref();
|
||||
(
|
||||
verge.app_log_max_size.unwrap_or(128),
|
||||
verge.app_log_max_count.unwrap_or(8),
|
||||
)
|
||||
};
|
||||
let sidecar_log_dir = sidecar_log_dir()?;
|
||||
Ok(FileLogWriter::builder(
|
||||
FileSpec::default()
|
||||
.directory(sidecar_log_dir)
|
||||
.basename("sidecar")
|
||||
.suppress_timestamp(),
|
||||
)
|
||||
.format(clash_verge_logger::file_format_without_level)
|
||||
.rotate(
|
||||
Criterion::Size(log_max_size * 1024),
|
||||
flexi_logger::Naming::TimestampsCustomFormat {
|
||||
current_infix: Some("latest"),
|
||||
format: "%Y-%m-%d_%H-%M-%S",
|
||||
},
|
||||
Cleanup::KeepLogFiles(log_max_count),
|
||||
)
|
||||
.try_build()?)
|
||||
}
|
||||
|
||||
// TODO 后续迁移新 service 时使用
|
||||
#[allow(dead_code)]
|
||||
pub async fn service_writer_config() -> Result<WriterConfig> {
|
||||
let (log_max_size, log_max_count) = {
|
||||
let verge_guard = Config::verge().await;
|
||||
let verge = verge_guard.latest_ref();
|
||||
(
|
||||
verge.app_log_max_size.unwrap_or(128),
|
||||
verge.app_log_max_count.unwrap_or(8),
|
||||
)
|
||||
};
|
||||
let service_log_dir = dirs::path_to_str(&service_log_dir()?)?.to_string();
|
||||
|
||||
Ok(WriterConfig {
|
||||
directory: service_log_dir,
|
||||
max_log_size: log_max_size * 1024,
|
||||
max_log_files: log_max_count,
|
||||
})
|
||||
}
|
||||
|
||||
// TODO flexi_logger 提供了最大保留天数,或许我们应该用内置删除log文件
|
||||
/// 删除log文件
|
||||
pub async fn delete_log() -> Result<()> {
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "tauri-dev")] {
|
||||
use std::fmt;
|
||||
} else {
|
||||
#[cfg(feature = "verge-dev")]
|
||||
use nu_ansi_term::Color;
|
||||
use std::{fmt, io::Write, thread};
|
||||
use flexi_logger::DeferredNow;
|
||||
use log::{LevelFilter, Record};
|
||||
use flexi_logger::filter::LogLineFilter;
|
||||
}
|
||||
}
|
||||
use flexi_logger::writers::FileLogWriter;
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
use flexi_logger::{DeferredNow, filter::LogLineFilter};
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
use log::Record;
|
||||
use std::{fmt, sync::Arc};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
pub type SharedWriter = Arc<Mutex<FileLogWriter>>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Type {
|
||||
@@ -28,7 +25,6 @@ pub enum Type {
|
||||
Lightweight,
|
||||
Network,
|
||||
ProxyMode,
|
||||
// Ipc,
|
||||
// Cache,
|
||||
ClashVergeRev,
|
||||
}
|
||||
@@ -51,7 +47,6 @@ impl fmt::Display for Type {
|
||||
Type::Lightweight => write!(f, "[Lightweight]"),
|
||||
Type::Network => write!(f, "[Network]"),
|
||||
Type::ProxyMode => write!(f, "[ProxMode]"),
|
||||
// Type::Ipc => write!(f, "[IPC]"),
|
||||
// Type::Cache => write!(f, "[Cache]"),
|
||||
Type::ClashVergeRev => write!(f, "[ClashVergeRev]"),
|
||||
}
|
||||
@@ -173,75 +168,36 @@ macro_rules! logging_error {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
static IGNORE_MODULES: &[&str] = &["tauri", "wry"];
|
||||
pub struct NoModuleFilter<'a>(pub &'a [&'a str]);
|
||||
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
pub struct NoExternModule;
|
||||
impl<'a> NoModuleFilter<'a> {
|
||||
#[inline]
|
||||
pub fn filter(&self, record: &Record) -> bool {
|
||||
if let Some(module) = record.module_path() {
|
||||
for blocked in self.0 {
|
||||
if module.len() >= blocked.len()
|
||||
&& module.as_bytes()[..blocked.len()] == blocked.as_bytes()[..]
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
impl LogLineFilter for NoExternModule {
|
||||
impl<'a> LogLineFilter for NoModuleFilter<'a> {
|
||||
fn write(
|
||||
&self,
|
||||
now: &mut DeferredNow,
|
||||
record: &Record,
|
||||
log_line_writer: &dyn flexi_logger::filter::LogLineWriter,
|
||||
writer: &dyn flexi_logger::filter::LogLineWriter,
|
||||
) -> std::io::Result<()> {
|
||||
let module_path = record.module_path().unwrap_or_default();
|
||||
if IGNORE_MODULES.iter().any(|m| module_path.starts_with(m)) {
|
||||
Ok(())
|
||||
} else {
|
||||
log_line_writer.write(now, record)
|
||||
if !self.filter(record) {
|
||||
return Ok(());
|
||||
}
|
||||
writer.write(now, record)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
pub fn get_log_level(log_level: &LevelFilter) -> String {
|
||||
#[cfg(feature = "verge-dev")]
|
||||
match log_level {
|
||||
LevelFilter::Off => Color::Fixed(8).paint("OFF").to_string(),
|
||||
LevelFilter::Error => Color::Red.paint("ERROR").to_string(),
|
||||
LevelFilter::Warn => Color::Yellow.paint("WARN ").to_string(),
|
||||
LevelFilter::Info => Color::Green.paint("INFO ").to_string(),
|
||||
LevelFilter::Debug => Color::Blue.paint("DEBUG").to_string(),
|
||||
LevelFilter::Trace => Color::Purple.paint("TRACE").to_string(),
|
||||
}
|
||||
#[cfg(not(feature = "verge-dev"))]
|
||||
log_level.to_string()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
pub fn console_colored_format(
|
||||
w: &mut dyn Write,
|
||||
now: &mut DeferredNow,
|
||||
record: &log::Record,
|
||||
) -> std::io::Result<()> {
|
||||
let current_thread = thread::current();
|
||||
let thread_name = current_thread.name().unwrap_or("unnamed");
|
||||
|
||||
let level = get_log_level(&record.level().to_level_filter());
|
||||
let line = record.line().unwrap_or(0);
|
||||
write!(
|
||||
w,
|
||||
"[{}] {} [{}:{}] T[{}] {}",
|
||||
now.format("%H:%M:%S%.3f"),
|
||||
level,
|
||||
record.module_path().unwrap_or("<unnamed>"),
|
||||
line,
|
||||
thread_name,
|
||||
record.args(),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "tauri-dev"))]
|
||||
pub fn file_format(
|
||||
w: &mut dyn Write,
|
||||
now: &mut DeferredNow,
|
||||
record: &Record,
|
||||
) -> std::io::Result<()> {
|
||||
write!(
|
||||
w,
|
||||
"[{}] {} {}",
|
||||
now.format("%Y-%m-%d %H:%M:%S%.3f"),
|
||||
record.level(),
|
||||
record.args(),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user