mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-04-13 05:20:28 +08:00
feat: reconfig log dynamically (#5724)
This commit is contained in:
parent
4adf678480
commit
421bbd090e
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -156,7 +156,7 @@ dependencies = [
|
|||||||
"objc2-foundation 0.3.2",
|
"objc2-foundation 0.3.2",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"windows-sys 0.60.2",
|
"windows-sys 0.59.0",
|
||||||
"wl-clipboard-rs",
|
"wl-clipboard-rs",
|
||||||
"x11rb",
|
"x11rb",
|
||||||
]
|
]
|
||||||
@ -1354,8 +1354,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clash_verge_service_ipc"
|
name = "clash_verge_service_ipc"
|
||||||
version = "2.0.27"
|
version = "2.0.28"
|
||||||
source = "git+https://github.com/clash-verge-rev/clash-verge-service-ipc#43274f2db38959090797b35416c404ee482e8744"
|
source = "git+https://github.com/clash-verge-rev/clash-verge-service-ipc#cac4cd880dac2488c95e0b214377fcdde4f147d0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"compact_str",
|
"compact_str",
|
||||||
@ -2151,7 +2151,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users 0.5.2",
|
"redox_users 0.5.2",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2424,7 +2424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3986,7 +3986,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi 0.5.2",
|
"hermit-abi 0.5.2",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4792,7 +4792,7 @@ version = "0.50.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6117,7 +6117,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2 0.5.10",
|
"socket2 0.5.10",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.60.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6732,7 +6732,7 @@ dependencies = [
|
|||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.11.0",
|
"linux-raw-sys 0.11.0",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6790,7 +6790,7 @@ dependencies = [
|
|||||||
"security-framework 3.5.1",
|
"security-framework 3.5.1",
|
||||||
"security-framework-sys",
|
"security-framework-sys",
|
||||||
"webpki-root-certs",
|
"webpki-root-certs",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -8323,7 +8323,7 @@ dependencies = [
|
|||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.1.2",
|
"rustix 1.1.2",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@ -11,4 +11,3 @@ flexi_logger = { workspace = true }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
tauri-dev = []
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
use compact_str::CompactString;
|
use compact_str::CompactString;
|
||||||
use flexi_logger::DeferredNow;
|
use flexi_logger::DeferredNow;
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
|
||||||
use flexi_logger::filter::LogLineFilter;
|
use flexi_logger::filter::LogLineFilter;
|
||||||
use flexi_logger::writers::FileLogWriter;
|
use flexi_logger::writers::FileLogWriter;
|
||||||
use flexi_logger::writers::LogWriter as _;
|
use flexi_logger::writers::LogWriter as _;
|
||||||
@ -98,15 +97,13 @@ pub fn write_sidecar_log(
|
|||||||
let _ = writer.write(now, &record);
|
let _ = writer.write(now, &record);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
pub struct NoModuleFilter<'a>(pub Vec<&'a str>);
|
||||||
pub struct NoModuleFilter<'a>(pub &'a [&'a str]);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
|
||||||
impl<'a> NoModuleFilter<'a> {
|
impl<'a> NoModuleFilter<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn filter(&self, record: &Record) -> bool {
|
pub fn filter(&self, record: &Record) -> bool {
|
||||||
if let Some(module) = record.module_path() {
|
if let Some(module) = record.module_path() {
|
||||||
for blocked in self.0 {
|
for blocked in self.0.iter() {
|
||||||
if module.len() >= blocked.len() && module.as_bytes()[..blocked.len()] == blocked.as_bytes()[..] {
|
if module.len() >= blocked.len() && module.as_bytes()[..blocked.len()] == blocked.as_bytes()[..] {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -116,7 +113,6 @@ impl<'a> NoModuleFilter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
|
||||||
impl<'a> LogLineFilter for NoModuleFilter<'a> {
|
impl<'a> LogLineFilter for NoModuleFilter<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(
|
fn write(
|
||||||
|
|||||||
@ -18,7 +18,7 @@ crate-type = ["staticlib", "cdylib", "rlib"]
|
|||||||
default = ["custom-protocol"]
|
default = ["custom-protocol"]
|
||||||
custom-protocol = ["tauri/custom-protocol"]
|
custom-protocol = ["tauri/custom-protocol"]
|
||||||
verge-dev = ["clash_verge_logger/color"]
|
verge-dev = ["clash_verge_logger/color"]
|
||||||
tauri-dev = ["clash-verge-logging/tauri-dev"]
|
tauri-dev = []
|
||||||
tokio-trace = ["console-subscriber"]
|
tokio-trace = ["console-subscriber"]
|
||||||
clippy = ["tauri/test"]
|
clippy = ["tauri/test"]
|
||||||
tracing = []
|
tracing = []
|
||||||
@ -65,7 +65,12 @@ boa_engine = "0.21.0"
|
|||||||
once_cell = { version = "1.21.3", features = ["parking_lot"] }
|
once_cell = { version = "1.21.3", features = ["parking_lot"] }
|
||||||
delay_timer = "0.11.6"
|
delay_timer = "0.11.6"
|
||||||
percent-encoding = "2.3.2"
|
percent-encoding = "2.3.2"
|
||||||
reqwest = { version = "0.13.1", features = ["json", "cookies", "rustls", "form"] }
|
reqwest = { version = "0.13.1", features = [
|
||||||
|
"json",
|
||||||
|
"cookies",
|
||||||
|
"rustls",
|
||||||
|
"form",
|
||||||
|
] }
|
||||||
regex = "1.12.2"
|
regex = "1.12.2"
|
||||||
sysproxy = { git = "https://github.com/clash-verge-rev/sysproxy-rs", features = [
|
sysproxy = { git = "https://github.com/clash-verge-rev/sysproxy-rs", features = [
|
||||||
"guard",
|
"guard",
|
||||||
@ -94,7 +99,7 @@ tauri-plugin-devtools = { version = "2.0.1" }
|
|||||||
tauri-plugin-mihomo = { git = "https://github.com/clash-verge-rev/tauri-plugin-mihomo" }
|
tauri-plugin-mihomo = { git = "https://github.com/clash-verge-rev/tauri-plugin-mihomo" }
|
||||||
clash_verge_logger = { git = "https://github.com/clash-verge-rev/clash-verge-logger" }
|
clash_verge_logger = { git = "https://github.com/clash-verge-rev/clash-verge-logger" }
|
||||||
async-trait = "0.1.89"
|
async-trait = "0.1.89"
|
||||||
clash_verge_service_ipc = { version = "2.0.27", features = [
|
clash_verge_service_ipc = { version = "2.0.28", features = [
|
||||||
"client",
|
"client",
|
||||||
], git = "https://github.com/clash-verge-rev/clash-verge-service-ipc" }
|
], git = "https://github.com/clash-verge-rev/clash-verge-service-ipc" }
|
||||||
arc-swap = "1.8.0"
|
arc-swap = "1.8.0"
|
||||||
|
|||||||
@ -1 +1,223 @@
|
|||||||
// TODO: global logger to record verge log message
|
use std::{
|
||||||
|
str::FromStr as _,
|
||||||
|
sync::{
|
||||||
|
Arc,
|
||||||
|
atomic::{AtomicU64, AtomicUsize, Ordering},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::{Result, bail};
|
||||||
|
use clash_verge_logging::{Type, logging};
|
||||||
|
use clash_verge_service_ipc::WriterConfig;
|
||||||
|
use compact_str::CompactString;
|
||||||
|
use flexi_logger::{
|
||||||
|
Cleanup, Criterion, DeferredNow, FileSpec, LogSpecBuilder, LogSpecification, LoggerHandle,
|
||||||
|
writers::{FileLogWriter, FileLogWriterBuilder, LogWriter as _},
|
||||||
|
};
|
||||||
|
use log::{Level, LevelFilter, Record};
|
||||||
|
use parking_lot::{Mutex, RwLock};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
core::service,
|
||||||
|
singleton,
|
||||||
|
utils::dirs::{self, service_log_dir, sidecar_log_dir},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Logger {
|
||||||
|
handle: Arc<Mutex<Option<LoggerHandle>>>,
|
||||||
|
sidecar_file_writer: Arc<RwLock<Option<FileLogWriter>>>,
|
||||||
|
log_level: Arc<RwLock<LevelFilter>>,
|
||||||
|
log_max_size: AtomicU64,
|
||||||
|
log_max_count: AtomicUsize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Logger {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
handle: Arc::new(Mutex::new(None)),
|
||||||
|
sidecar_file_writer: Arc::new(RwLock::new(None)),
|
||||||
|
log_level: Arc::new(RwLock::new(LevelFilter::Info)),
|
||||||
|
log_max_size: AtomicU64::new(128),
|
||||||
|
log_max_count: AtomicUsize::new(8),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
singleton!(Logger, LOGGER);
|
||||||
|
|
||||||
|
impl Logger {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn init(&self) -> Result<()> {
|
||||||
|
let (log_level, log_max_size, log_max_count) = {
|
||||||
|
let verge_guard = crate::config::Config::verge().await;
|
||||||
|
let verge = verge_guard.latest_arc();
|
||||||
|
(
|
||||||
|
verge.get_log_level(),
|
||||||
|
verge.app_log_max_size.unwrap_or(128),
|
||||||
|
verge.app_log_max_count.unwrap_or(8),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let log_level = std::env::var("RUST_LOG")
|
||||||
|
.ok()
|
||||||
|
.and_then(|v| log::LevelFilter::from_str(&v).ok())
|
||||||
|
.unwrap_or(log_level);
|
||||||
|
*self.log_level.write() = log_level;
|
||||||
|
self.log_max_size.store(log_max_size, Ordering::SeqCst);
|
||||||
|
self.log_max_count.store(log_max_count, Ordering::SeqCst);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "tauri-dev"))]
|
||||||
|
{
|
||||||
|
let log_spec = Self::generate_log_spec(log_level);
|
||||||
|
let log_dir = dirs::app_logs_dir()?;
|
||||||
|
let logger = flexi_logger::Logger::with(log_spec)
|
||||||
|
.log_to_file(FileSpec::default().directory(log_dir).basename(""))
|
||||||
|
.duplicate_to_stdout(log_level.into())
|
||||||
|
.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 {
|
||||||
|
current_infix: Some("latest"),
|
||||||
|
format: "%Y-%m-%d_%H-%M-%S",
|
||||||
|
},
|
||||||
|
Cleanup::KeepLogFiles(log_max_count),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut filter_modules = vec!["wry", "tokio_tungstenite", "tungstenite"];
|
||||||
|
#[cfg(not(feature = "tracing"))]
|
||||||
|
filter_modules.push("tauri");
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
filter_modules.extend(["tauri_plugin_mihomo", "kode_bridge"]);
|
||||||
|
let logger = logger.filter(Box::new(clash_verge_logging::NoModuleFilter(filter_modules)));
|
||||||
|
|
||||||
|
let handle = logger.start()?;
|
||||||
|
*self.handle.lock() = Some(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
let sidecar_file_writer = self.generate_sidecar_writer()?;
|
||||||
|
*self.sidecar_file_writer.write() = Some(sidecar_file_writer);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_log_spec(log_level: LevelFilter) -> LogSpecification {
|
||||||
|
let mut spec = LogSpecBuilder::new();
|
||||||
|
let log_level = std::env::var("RUST_LOG")
|
||||||
|
.ok()
|
||||||
|
.and_then(|v| log::LevelFilter::from_str(&v).ok())
|
||||||
|
.unwrap_or(log_level);
|
||||||
|
spec.default(log_level);
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
spec.module("tauri", log::LevelFilter::Debug)
|
||||||
|
.module("wry", log::LevelFilter::Off)
|
||||||
|
.module("tauri_plugin_mihomo", log::LevelFilter::Off);
|
||||||
|
spec.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_file_log_writer(&self) -> Result<FileLogWriterBuilder> {
|
||||||
|
let log_dir = dirs::app_logs_dir()?;
|
||||||
|
let log_max_size = self.log_max_size.load(Ordering::SeqCst);
|
||||||
|
let log_max_count = self.log_max_count.load(Ordering::SeqCst);
|
||||||
|
let flwb = FileLogWriter::builder(FileSpec::default().directory(log_dir).basename("")).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),
|
||||||
|
);
|
||||||
|
Ok(flwb)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// only update app log level
|
||||||
|
pub fn update_log_level(&self, level: LevelFilter) -> Result<()> {
|
||||||
|
println!("refresh log level");
|
||||||
|
*self.log_level.write() = level;
|
||||||
|
let log_level = self.log_level.read().to_owned();
|
||||||
|
if let Some(handle) = self.handle.lock().as_mut() {
|
||||||
|
let log_spec = Self::generate_log_spec(log_level);
|
||||||
|
handle.set_new_spec(log_spec);
|
||||||
|
handle.adapt_duplication_to_stdout(log_level.into())?;
|
||||||
|
} else {
|
||||||
|
bail!("failed to get logger handle, make sure it init");
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// update app and mihomo core log config
|
||||||
|
pub async fn update_log_config(&self, log_max_size: u64, log_max_count: usize) -> Result<()> {
|
||||||
|
println!("refresh log file");
|
||||||
|
self.log_max_size.store(log_max_size, Ordering::SeqCst);
|
||||||
|
self.log_max_count.store(log_max_count, Ordering::SeqCst);
|
||||||
|
if let Some(handle) = self.handle.lock().as_ref() {
|
||||||
|
let log_file_writer = self.generate_file_log_writer()?;
|
||||||
|
handle.reset_flw(&log_file_writer)?;
|
||||||
|
} else {
|
||||||
|
bail!("failed to get logger handle, make sure it init");
|
||||||
|
};
|
||||||
|
let sidecar_writer = self.generate_sidecar_writer()?;
|
||||||
|
*self.sidecar_file_writer.write() = Some(sidecar_writer);
|
||||||
|
|
||||||
|
// update service writer config
|
||||||
|
if service::is_service_ipc_path_exists() && service::is_service_available().await.is_ok() {
|
||||||
|
let service_log_dir = dirs::path_to_str(&service_log_dir()?)?.into();
|
||||||
|
clash_verge_service_ipc::update_writer(&WriterConfig {
|
||||||
|
directory: service_log_dir,
|
||||||
|
max_log_size: log_max_size * 1024,
|
||||||
|
max_log_files: log_max_count,
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_sidecar_writer(&self) -> Result<FileLogWriter> {
|
||||||
|
let sidecar_log_dir = sidecar_log_dir()?;
|
||||||
|
let log_max_size = self.log_max_size.load(Ordering::SeqCst);
|
||||||
|
let log_max_count = self.log_max_count.load(Ordering::SeqCst);
|
||||||
|
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()?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn writer_sidecar_log(&self, level: Level, message: &CompactString) {
|
||||||
|
if let Some(writer) = self.sidecar_file_writer.read().as_ref() {
|
||||||
|
let mut now = DeferredNow::default();
|
||||||
|
let args = format_args!("{}", message);
|
||||||
|
let record = Record::builder().args(args).level(level).target("sidecar").build();
|
||||||
|
let _ = writer.write(&mut now, &record);
|
||||||
|
} else {
|
||||||
|
logging!(error, Type::System, "failed to get sidecar file log writer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn service_writer_config(&self) -> Result<WriterConfig> {
|
||||||
|
let service_log_dir = dirs::path_to_str(&service_log_dir()?)?.into();
|
||||||
|
let log_max_size = self.log_max_size.load(Ordering::SeqCst);
|
||||||
|
let log_max_count = self.log_max_count.load(Ordering::SeqCst);
|
||||||
|
let writer_config = WriterConfig {
|
||||||
|
directory: service_log_dir,
|
||||||
|
max_log_size: log_max_size * 1024,
|
||||||
|
max_log_files: log_max_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(writer_config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,14 +2,13 @@ use super::{CoreManager, RunningMode};
|
|||||||
use crate::{
|
use crate::{
|
||||||
AsyncHandler,
|
AsyncHandler,
|
||||||
config::{Config, IClashTemp},
|
config::{Config, IClashTemp},
|
||||||
core::{handle, manager::CLASH_LOGGER, service},
|
core::{handle, logger::Logger, manager::CLASH_LOGGER, service},
|
||||||
logging,
|
logging,
|
||||||
utils::{dirs, init::sidecar_writer},
|
utils::dirs,
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clash_verge_logging::{SharedWriter, Type, write_sidecar_log};
|
use clash_verge_logging::Type;
|
||||||
use compact_str::CompactString;
|
use compact_str::CompactString;
|
||||||
use flexi_logger::DeferredNow;
|
|
||||||
use log::Level;
|
use log::Level;
|
||||||
use scopeguard::defer;
|
use scopeguard::defer;
|
||||||
use tauri_plugin_shell::ShellExt as _;
|
use tauri_plugin_shell::ShellExt as _;
|
||||||
@ -60,20 +59,16 @@ impl CoreManager {
|
|||||||
self.set_running_child_sidecar(child);
|
self.set_running_child_sidecar(child);
|
||||||
self.set_running_mode(RunningMode::Sidecar);
|
self.set_running_mode(RunningMode::Sidecar);
|
||||||
|
|
||||||
let shared_writer: SharedWriter = std::sync::Arc::new(tokio::sync::Mutex::new(sidecar_writer().await?));
|
|
||||||
|
|
||||||
AsyncHandler::spawn(|| async move {
|
AsyncHandler::spawn(|| async move {
|
||||||
while let Some(event) = rx.recv().await {
|
while let Some(event) = rx.recv().await {
|
||||||
match event {
|
match event {
|
||||||
tauri_plugin_shell::process::CommandEvent::Stdout(line)
|
tauri_plugin_shell::process::CommandEvent::Stdout(line)
|
||||||
| tauri_plugin_shell::process::CommandEvent::Stderr(line) => {
|
| tauri_plugin_shell::process::CommandEvent::Stderr(line) => {
|
||||||
let mut now = DeferredNow::default();
|
|
||||||
let message = CompactString::from(String::from_utf8_lossy(&line).as_ref());
|
let message = CompactString::from(String::from_utf8_lossy(&line).as_ref());
|
||||||
write_sidecar_log(shared_writer.lock().await, &mut now, Level::Error, &message);
|
Logger::global().writer_sidecar_log(Level::Error, &message);
|
||||||
CLASH_LOGGER.append_log(message).await;
|
CLASH_LOGGER.append_log(message).await;
|
||||||
}
|
}
|
||||||
tauri_plugin_shell::process::CommandEvent::Terminated(term) => {
|
tauri_plugin_shell::process::CommandEvent::Terminated(term) => {
|
||||||
let mut now = DeferredNow::default();
|
|
||||||
let message = if let Some(code) = term.code {
|
let message = if let Some(code) = term.code {
|
||||||
CompactString::from(format!("Process terminated with code: {}", code))
|
CompactString::from(format!("Process terminated with code: {}", code))
|
||||||
} else if let Some(signal) = term.signal {
|
} else if let Some(signal) = term.signal {
|
||||||
@ -81,7 +76,7 @@ impl CoreManager {
|
|||||||
} else {
|
} else {
|
||||||
CompactString::from("Process terminated")
|
CompactString::from("Process terminated")
|
||||||
};
|
};
|
||||||
write_sidecar_log(shared_writer.lock().await, &mut now, Level::Info, &message);
|
Logger::global().writer_sidecar_log(Level::Info, &message);
|
||||||
CLASH_LOGGER.clear_logs().await;
|
CLASH_LOGGER.clear_logs().await;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, IClashTemp},
|
config::{Config, IClashTemp},
|
||||||
core::tray::Tray,
|
core::{logger::Logger, tray::Tray},
|
||||||
utils::{dirs, init::service_writer_config},
|
utils::dirs,
|
||||||
};
|
};
|
||||||
use anyhow::{Context as _, Result, bail};
|
use anyhow::{Context as _, Result, bail};
|
||||||
use clash_verge_logging::{Type, logging, logging_error};
|
use clash_verge_logging::{Type, logging, logging_error};
|
||||||
@ -313,7 +313,7 @@ pub(super) async fn start_with_existing_service(config_file: &PathBuf) -> Result
|
|||||||
core_ipc_path: IClashTemp::guard_external_controller_ipc(),
|
core_ipc_path: IClashTemp::guard_external_controller_ipc(),
|
||||||
config_dir: dirs::path_to_str(&dirs::app_home_dir()?)?.into(),
|
config_dir: dirs::path_to_str(&dirs::app_home_dir()?)?.into(),
|
||||||
},
|
},
|
||||||
log_config: service_writer_config().await?,
|
log_config: Logger::global().service_writer_config()?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = clash_verge_service_ipc::start_clash(&payload)
|
let response = clash_verge_service_ipc::start_clash(&payload)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, IVerge},
|
config::{Config, IVerge},
|
||||||
core::{CoreManager, handle, hotkey, sysopt, tray},
|
core::{CoreManager, handle, hotkey, logger::Logger, sysopt, tray},
|
||||||
module::{auto_backup::AutoBackupManager, lightweight},
|
module::{auto_backup::AutoBackupManager, lightweight},
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
@ -65,6 +65,8 @@ bitflags! {
|
|||||||
const SYSTRAY_CLICK_BEHAVIOR = 1 << 9;
|
const SYSTRAY_CLICK_BEHAVIOR = 1 << 9;
|
||||||
const LIGHT_WEIGHT = 1 << 10;
|
const LIGHT_WEIGHT = 1 << 10;
|
||||||
const LANGUAGE = 1 << 11;
|
const LANGUAGE = 1 << 11;
|
||||||
|
const LOG_LEVEL = 1 << 12;
|
||||||
|
const LOG_FILE = 1 << 13;
|
||||||
|
|
||||||
const GROUP_SYS_TRAY = Self::SYSTRAY_MENU.bits()
|
const GROUP_SYS_TRAY = Self::SYSTRAY_MENU.bits()
|
||||||
| Self::SYSTRAY_TOOLTIP.bits()
|
| Self::SYSTRAY_TOOLTIP.bits()
|
||||||
@ -111,6 +113,9 @@ fn determine_update_flags(patch: &IVerge) -> UpdateFlags {
|
|||||||
let tray_inline_outbound_modes = patch.tray_inline_outbound_modes;
|
let tray_inline_outbound_modes = patch.tray_inline_outbound_modes;
|
||||||
let enable_proxy_guard = patch.enable_proxy_guard;
|
let enable_proxy_guard = patch.enable_proxy_guard;
|
||||||
let proxy_guard_duration = patch.proxy_guard_duration;
|
let proxy_guard_duration = patch.proxy_guard_duration;
|
||||||
|
let log_level = &patch.app_log_level;
|
||||||
|
let log_max_size = patch.app_log_max_size;
|
||||||
|
let log_max_count = patch.app_log_max_count;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let restart_core_needed = socks_enabled.is_some()
|
let restart_core_needed = socks_enabled.is_some()
|
||||||
@ -182,6 +187,12 @@ fn determine_update_flags(patch: &IVerge) -> UpdateFlags {
|
|||||||
if tray_proxy_groups_display_mode.is_some() {
|
if tray_proxy_groups_display_mode.is_some() {
|
||||||
update_flags.insert(UpdateFlags::SYSTRAY_MENU);
|
update_flags.insert(UpdateFlags::SYSTRAY_MENU);
|
||||||
}
|
}
|
||||||
|
if log_level.is_some() {
|
||||||
|
update_flags.insert(UpdateFlags::LOG_LEVEL);
|
||||||
|
}
|
||||||
|
if log_max_size.is_some() || log_max_count.is_some() {
|
||||||
|
update_flags.insert(UpdateFlags::LOG_FILE);
|
||||||
|
}
|
||||||
if tray_inline_outbound_modes.is_some() {
|
if tray_inline_outbound_modes.is_some() {
|
||||||
update_flags.insert(UpdateFlags::SYSTRAY_MENU);
|
update_flags.insert(UpdateFlags::SYSTRAY_MENU);
|
||||||
}
|
}
|
||||||
@ -244,6 +255,14 @@ async fn process_terminated_flags(update_flags: UpdateFlags, patch: &IVerge) ->
|
|||||||
lightweight::disable_auto_light_weight_mode();
|
lightweight::disable_auto_light_weight_mode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if update_flags.contains(UpdateFlags::LOG_LEVEL) {
|
||||||
|
Logger::global().update_log_level(patch.get_log_level())?;
|
||||||
|
}
|
||||||
|
if update_flags.contains(UpdateFlags::LOG_FILE) {
|
||||||
|
let log_max_size = patch.app_log_max_size.unwrap_or(128);
|
||||||
|
let log_max_count = patch.app_log_max_count.unwrap_or(8);
|
||||||
|
Logger::global().update_log_config(log_max_size, log_max_count).await?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -238,7 +238,7 @@ pub fn run() {
|
|||||||
.set(app.app_handle().clone())
|
.set(app.app_handle().clone())
|
||||||
.expect("failed to set global app handle");
|
.expect("failed to set global app handle");
|
||||||
|
|
||||||
let _handle = resolve::init_work_dir_and_logger();
|
resolve::init_work_dir_and_logger()?;
|
||||||
|
|
||||||
logging!(info, Type::Setup, "开始应用初始化...");
|
logging!(info, Type::Setup, "开始应用初始化...");
|
||||||
if let Err(e) = app_init::setup_autostart(app) {
|
if let Err(e) = app_init::setup_autostart(app) {
|
||||||
|
|||||||
@ -6,137 +6,18 @@ use crate::{
|
|||||||
logging,
|
logging,
|
||||||
process::AsyncHandler,
|
process::AsyncHandler,
|
||||||
utils::{
|
utils::{
|
||||||
dirs::{self, PathBufExec as _, service_log_dir, sidecar_log_dir},
|
dirs::{self, PathBufExec as _},
|
||||||
help,
|
help,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use chrono::{Local, TimeZone as _};
|
use chrono::{Local, TimeZone as _};
|
||||||
#[cfg(all(not(feature = "tauri-dev"), not(feature = "tracing-full")))]
|
|
||||||
use clash_verge_logging::NoModuleFilter;
|
|
||||||
use clash_verge_logging::Type;
|
use clash_verge_logging::Type;
|
||||||
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, LoggerHandle};
|
|
||||||
use std::{path::PathBuf, str::FromStr as _};
|
use std::{path::PathBuf, str::FromStr as _};
|
||||||
use tauri_plugin_shell::ShellExt as _;
|
use tauri_plugin_shell::ShellExt as _;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use tokio::fs::DirEntry;
|
use tokio::fs::DirEntry;
|
||||||
|
|
||||||
/// initialize this instance's log file
|
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
|
||||||
pub async fn init_logger() -> Result<LoggerHandle> {
|
|
||||||
// TODO 提供 runtime 级别实时修改
|
|
||||||
let (log_level, log_max_size, log_max_count) = {
|
|
||||||
let verge_guard = Config::verge().await;
|
|
||||||
let verge = verge_guard.data_arc();
|
|
||||||
(
|
|
||||||
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 mut spec = LogSpecBuilder::new();
|
|
||||||
let level = std::env::var("RUST_LOG")
|
|
||||||
.ok()
|
|
||||||
.and_then(|v| log::LevelFilter::from_str(&v).ok())
|
|
||||||
.unwrap_or(log_level);
|
|
||||||
spec.default(level);
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
spec.module("tauri", log::LevelFilter::Debug)
|
|
||||||
.module("wry", log::LevelFilter::Off)
|
|
||||||
.module("tauri_plugin_mihomo", log::LevelFilter::Off);
|
|
||||||
let spec = spec.build();
|
|
||||||
|
|
||||||
let logger = Logger::with(spec)
|
|
||||||
.log_to_file(FileSpec::default().directory(log_dir).basename(""))
|
|
||||||
.duplicate_to_stdout(Duplicate::Debug)
|
|
||||||
.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 {
|
|
||||||
current_infix: Some("latest"),
|
|
||||||
format: "%Y-%m-%d_%H-%M-%S",
|
|
||||||
},
|
|
||||||
Cleanup::KeepLogFiles(log_max_count),
|
|
||||||
);
|
|
||||||
#[cfg(all(not(feature = "tracing"), not(feature = "tracing-full")))]
|
|
||||||
let logger = logger.filter(Box::new(NoModuleFilter(&[
|
|
||||||
"wry",
|
|
||||||
"tauri",
|
|
||||||
"tokio_tungstenite",
|
|
||||||
"tungstenite",
|
|
||||||
])));
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
let logger = logger.filter(Box::new(NoModuleFilter(&[
|
|
||||||
"wry",
|
|
||||||
"tauri_plugin_mihomo",
|
|
||||||
"tokio_tungstenite",
|
|
||||||
"tungstenite",
|
|
||||||
"kode_bridge",
|
|
||||||
])));
|
|
||||||
|
|
||||||
let handle = logger.start()?;
|
|
||||||
|
|
||||||
// TODO 全局 logger handle 控制
|
|
||||||
// GlobalLoggerProxy::global().set_inner(handle);
|
|
||||||
// TODO 提供前端设置等级,热更新等级
|
|
||||||
// logger.parse_new_spec(spec)
|
|
||||||
|
|
||||||
Ok(handle)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn sidecar_writer() -> Result<FileLogWriter> {
|
|
||||||
let (log_max_size, log_max_count) = {
|
|
||||||
let verge_guard = Config::verge().await;
|
|
||||||
let verge = verge_guard.data_arc();
|
|
||||||
(
|
|
||||||
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()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
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.data_arc();
|
|
||||||
(
|
|
||||||
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()?)?.into();
|
|
||||||
|
|
||||||
Ok(WriterConfig {
|
|
||||||
directory: service_log_dir,
|
|
||||||
max_log_size: log_max_size * 1024,
|
|
||||||
max_log_files: log_max_count,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO flexi_logger 提供了最大保留天数,或许我们应该用内置删除log文件
|
// TODO flexi_logger 提供了最大保留天数,或许我们应该用内置删除log文件
|
||||||
/// 删除log文件
|
/// 删除log文件
|
||||||
pub async fn delete_log() -> Result<()> {
|
pub async fn delete_log() -> Result<()> {
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use flexi_logger::LoggerHandle;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
core::{
|
core::{
|
||||||
CoreManager, Timer, handle,
|
CoreManager, Timer, handle,
|
||||||
hotkey::Hotkey,
|
hotkey::Hotkey,
|
||||||
|
logger::Logger,
|
||||||
service::{SERVICE_MANAGER, ServiceManager, is_service_ipc_path_exists},
|
service::{SERVICE_MANAGER, ServiceManager, is_service_ipc_path_exists},
|
||||||
sysopt,
|
sysopt,
|
||||||
tray::Tray,
|
tray::Tray,
|
||||||
@ -28,20 +28,13 @@ pub mod window_script;
|
|||||||
|
|
||||||
static RESOLVE_DONE: AtomicBool = AtomicBool::new(false);
|
static RESOLVE_DONE: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
pub fn init_work_dir_and_logger() -> Option<LoggerHandle> {
|
pub fn init_work_dir_and_logger() -> anyhow::Result<()> {
|
||||||
AsyncHandler::block_on(async {
|
AsyncHandler::block_on(async {
|
||||||
init_work_config().await;
|
init_work_config().await;
|
||||||
init_resources().await;
|
init_resources().await;
|
||||||
|
logging!(info, Type::Setup, "Initializing logger");
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
Logger::global().init().await?;
|
||||||
{
|
Ok(())
|
||||||
logging!(info, Type::Setup, "Initializing logger");
|
|
||||||
init::init_logger().await.ok()
|
|
||||||
}
|
|
||||||
#[cfg(feature = "tauri-dev")]
|
|
||||||
{
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user