feat(logging): introduce clash-verge-logging crate for management (#5486)

* feat(logging): introduce clash-verge-logging crate for management

- Added a new crate `clash-verge-logging` with dependencies on `log`, `tokio`, `compact_str`, and `flexi_logger`.
- Implemented logging types and macros for structured logging across the application.
- Replaced existing logging imports with the new `clash_verge_logging` crate in various modules.
- Updated logging functionality to support different logging types and error handling.
- Refactored code to improve logging consistency and maintainability.

* fix(logging): update import paths for clash_verge_logging in linux.rs and dns.rs

* fix(logging): update import statement for clash_verge_logging in windows.rs
This commit is contained in:
Tunglies
2025-11-17 10:42:57 +08:00
committed by GitHub
parent 635f63e9e5
commit 0866b93175
61 changed files with 145 additions and 169 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
#[cfg(target_os = "windows")]
use crate::{logging, utils::logging::Type};
#[cfg(target_os = "windows")]
use anyhow::{Result, anyhow};
#[cfg(target_os = "windows")]
use clash_verge_logging::{Type, logging};
#[cfg(target_os = "windows")]
use std::{os::windows::process::CommandExt as _, path::Path, path::PathBuf};
+2 -5
View File
@@ -1,10 +1,7 @@
use crate::{
core::{CoreManager, handle, manager::RunningMode},
logging,
utils::logging::Type,
};
use crate::core::{CoreManager, handle, manager::RunningMode};
use anyhow::Result;
use async_trait::async_trait;
use clash_verge_logging::{Type, logging};
use once_cell::sync::OnceCell;
#[cfg(unix)]
use std::iter;
+2 -1
View File
@@ -1,5 +1,6 @@
use crate::{config::with_encryption, enhance::seq::SeqMap, logging, utils::logging::Type};
use crate::{config::with_encryption, enhance::seq::SeqMap};
use anyhow::{Context as _, Result, anyhow, bail};
use clash_verge_logging::{Type, logging};
use nanoid::nanoid;
use serde::{Serialize, de::DeserializeOwned};
use serde_yaml_ng::Mapping;
+3 -3
View File
@@ -1,6 +1,4 @@
// #[cfg(not(feature = "tracing"))]
#[cfg(not(feature = "tauri-dev"))]
use crate::utils::logging::NoModuleFilter;
use crate::{
config::{Config, IClashTemp, IProfiles, IVerge},
constants,
@@ -10,11 +8,13 @@ use crate::{
utils::{
dirs::{self, PathBufExec as _, service_log_dir, sidecar_log_dir},
help,
logging::Type,
},
};
use anyhow::Result;
use chrono::{Local, TimeZone as _};
#[cfg(not(feature = "tauri-dev"))]
use clash_verge_logging::NoModuleFilter;
use clash_verge_logging::Type;
use clash_verge_service_ipc::WriterConfig;
use flexi_logger::writers::FileLogWriter;
use flexi_logger::{Cleanup, Criterion, FileSpec};
+1 -2
View File
@@ -1,6 +1,5 @@
use crate::logging;
use crate::utils::logging::Type;
use anyhow::Result;
use clash_verge_logging::{Type, logging};
use std::collections::{HashMap, HashSet};
use std::env;
use std::fs;
-157
View File
@@ -1,157 +0,0 @@
use compact_str::CompactString;
use flexi_logger::DeferredNow;
#[cfg(not(feature = "tauri-dev"))]
use flexi_logger::filter::LogLineFilter;
use flexi_logger::writers::FileLogWriter;
use flexi_logger::writers::LogWriter as _;
use log::Level;
use log::Record;
use std::{fmt, sync::Arc};
use tokio::sync::{Mutex, MutexGuard};
pub type SharedWriter = Arc<Mutex<FileLogWriter>>;
#[derive(Debug, PartialEq, Eq)]
pub enum Type {
Cmd,
Core,
Config,
Setup,
System,
Service,
Hotkey,
Window,
Tray,
Timer,
Frontend,
Backup,
File,
Lightweight,
Network,
ProxyMode,
Validate,
ClashVergeRev,
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Cmd => write!(f, "[Cmd]"),
Self::Core => write!(f, "[Core]"),
Self::Config => write!(f, "[Config]"),
Self::Setup => write!(f, "[Setup]"),
Self::System => write!(f, "[System]"),
Self::Service => write!(f, "[Service]"),
Self::Hotkey => write!(f, "[Hotkey]"),
Self::Window => write!(f, "[Window]"),
Self::Tray => write!(f, "[Tray]"),
Self::Timer => write!(f, "[Timer]"),
Self::Frontend => write!(f, "[Frontend]"),
Self::Backup => write!(f, "[Backup]"),
Self::File => write!(f, "[File]"),
Self::Lightweight => write!(f, "[Lightweight]"),
Self::Network => write!(f, "[Network]"),
Self::ProxyMode => write!(f, "[ProxMode]"),
Self::Validate => write!(f, "[Validate]"),
Self::ClashVergeRev => write!(f, "[ClashVergeRev]"),
}
}
}
#[macro_export]
macro_rules! error {
($result: expr) => {
log::error!(target: "app", "{}", $result);
};
}
/// wrap the anyhow error
/// transform the error to String
#[macro_export]
macro_rules! wrap_err {
// Case 1: Future<Result<T, E>>
($stat:expr, async) => {{
match $stat.await {
Ok(a) => Ok::<_, ::anyhow::Error>(a),
Err(err) => {
log::error!(target: "app", "{}", err);
Err(::anyhow::Error::msg(err.to_string()))
}
}
}};
}
#[macro_export]
macro_rules! logging {
// 不带 print 参数的版本(默认不打印)
($level:ident, $type:expr, $($arg:tt)*) => {
log::$level!(target: "app", "{} {}", $type, format_args!($($arg)*))
};
}
#[macro_export]
macro_rules! logging_error {
// Handle Result<T, E>
($type:expr, $expr:expr) => {
if let Err(err) = $expr {
log::error!(target: "app", "[{}] {}", $type, err);
}
};
// Handle formatted message: always print to stdout and log as error
($type:expr, $fmt:literal $(, $arg:expr)*) => {
log::error!(target: "app", "[{}] {}", $type, format_args!($fmt $(, $arg)*));
};
}
pub fn write_sidecar_log(
writer: MutexGuard<'_, FileLogWriter>,
now: &mut DeferredNow,
level: Level,
message: &CompactString,
) {
let args = format_args!("{}", message);
let record = Record::builder()
.args(args)
.level(level)
.target("sidecar")
.build();
let _ = writer.write(now, &record);
}
#[cfg(not(feature = "tauri-dev"))]
pub struct NoModuleFilter<'a>(pub &'a [&'a str]);
#[cfg(not(feature = "tauri-dev"))]
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<'a> LogLineFilter for NoModuleFilter<'a> {
fn write(
&self,
now: &mut DeferredNow,
record: &Record,
writer: &dyn flexi_logger::filter::LogLineWriter,
) -> std::io::Result<()> {
if !self.filter(record) {
return Ok(());
}
writer.write(now, record)
}
}
-1
View File
@@ -6,7 +6,6 @@ pub mod i18n;
pub mod init;
#[cfg(target_os = "linux")]
pub mod linux;
pub mod logging;
pub mod network;
pub mod notification;
pub mod resolve;
+3 -4
View File
@@ -1,8 +1,7 @@
#[cfg(target_os = "macos")]
use crate::{logging, utils::logging::Type};
use clash_verge_logging::{Type, logging};
pub async fn set_public_dns(dns_server: String) {
use crate::utils::logging::Type;
use crate::{core::handle, logging, utils::dirs};
use crate::{core::handle, utils::dirs};
use tauri_plugin_shell::ShellExt as _;
let app_handle = handle::Handle::app_handle();
+2 -2
View File
@@ -9,11 +9,11 @@ use crate::{
sysopt,
tray::Tray,
},
logging, logging_error,
module::{auto_backup::AutoBackupManager, lightweight::auto_lightweight_boot, signal},
process::AsyncHandler,
utils::{init, logging::Type, server, window_manager::WindowManager},
utils::{init, server, window_manager::WindowManager},
};
use clash_verge_logging::{Type, logging, logging_error};
pub mod dns;
pub mod scheme;
+1 -2
View File
@@ -8,9 +8,8 @@ use tauri::Url;
use crate::{
config::{Config, PrfItem, profiles},
core::handle,
logging,
utils::logging::Type,
};
use clash_verge_logging::{Type, logging};
pub(super) async fn resolve_scheme(param: &str) -> Result<()> {
logging!(info, Type::Config, "received deep link: {param}");
+1 -1
View File
@@ -6,7 +6,7 @@ use std::sync::{
};
use tokio::sync::Notify;
use crate::{logging, utils::logging::Type};
use clash_verge_logging::{Type, logging};
// 获取 UI 是否准备就绪的全局状态
static UI_READY: AtomicBool = AtomicBool::new(false);
+2 -5
View File
@@ -3,12 +3,9 @@ use tauri::WebviewWindow;
use crate::{
config::Config,
core::handle,
logging_error,
utils::{
logging::Type,
resolve::window_script::{INITIAL_LOADING_OVERLAY, WINDOW_INITIAL_SCRIPT},
},
utils::resolve::window_script::{INITIAL_LOADING_OVERLAY, WINDOW_INITIAL_SCRIPT},
};
use clash_verge_logging::{Type, logging_error};
// 定义默认窗口尺寸常量
const DEFAULT_WIDTH: f64 = 940.0;
+2 -2
View File
@@ -1,12 +1,12 @@
use super::resolve;
use crate::{
config::{Config, DEFAULT_PAC, IVerge},
logging, logging_error,
module::lightweight,
process::AsyncHandler,
utils::{logging::Type, window_manager::WindowManager},
utils::window_manager::WindowManager,
};
use anyhow::{Result, bail};
use clash_verge_logging::{Type, logging, logging_error};
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use port_scanner::local_port_available;
+2 -2
View File
@@ -47,9 +47,9 @@ macro_rules! singleton_with_logging {
pub fn global() -> &'static $struct_name {
$instance_name.get_or_init(|| {
let instance = Self::new();
$crate::logging!(
clash_verge_logging::logging!(
info,
$crate::utils::logging::Type::Setup,
clash_verge_logging::Type::Setup,
concat!($struct_name_str, " initialized")
);
instance
+2 -5
View File
@@ -1,8 +1,5 @@
use crate::{
core::handle,
logging,
utils::{logging::Type, resolve::window::build_new_window},
};
use crate::{core::handle, utils::resolve::window::build_new_window};
use clash_verge_logging::{Type, logging};
use std::future::Future;
use std::pin::Pin;
use tauri::{Manager as _, WebviewWindow, Wry};