mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 00:35:38 +08:00
Squashed commit of the following:
commit 2a9f2f20e9c6d88c2f96fd40589740e1f236f64a
Author: Tunglies <77394545+Tunglies@users.noreply.github.com>
Date: Mon Oct 13 11:07:31 2025 +0800
fix: improve message handling in CommandEvent logging with CompactString
commit c77fc18accefeaf471594035d61bd13e235c87d6
Author: Tunglies <77394545+Tunglies@users.noreply.github.com>
Date: Mon Oct 13 10:47:16 2025 +0800
fix: optimize shared writer locking in CommandEvent handling
commit d5286ee5f1612f17b7a97eead84d430669816d98
Author: Tunglies <77394545+Tunglies@users.noreply.github.com>
Date: Mon Oct 13 10:30:19 2025 +0800
feat: integrate CompactString for improved logging and dependency management
commit 951fb2b120ce159c00dc57d43c5a519990f34cee
Author: Tunglies <77394545+Tunglies@users.noreply.github.com>
Date: Mon Oct 13 09:39:29 2025 +0800
refactor: remove write_sidecar_log function and streamline logging in CommandEvent handling
commit fd48d66c55a2c62fd32741fd3c65cc06d4cc693f
Author: Tunglies <77394545+Tunglies@users.noreply.github.com>
Date: Mon Oct 13 09:38:05 2025 +0800
Revert "refactor(core): stabilize 'static backing for sidecar logging"
This reverts commit fe7eb59f18.
This commit is contained in:
35
src-tauri/Cargo.lock
generated
35
src-tauri/Cargo.lock
generated
@@ -962,6 +962,15 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6"
|
checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "castaway"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
|
||||||
|
dependencies = [
|
||||||
|
"rustversion",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.40"
|
version = "1.2.40"
|
||||||
@@ -1101,6 +1110,7 @@ dependencies = [
|
|||||||
"chrono",
|
"chrono",
|
||||||
"clash_verge_logger",
|
"clash_verge_logger",
|
||||||
"clash_verge_service_ipc",
|
"clash_verge_service_ipc",
|
||||||
|
"compact_str",
|
||||||
"console-subscriber",
|
"console-subscriber",
|
||||||
"criterion",
|
"criterion",
|
||||||
"dashmap 6.1.0",
|
"dashmap 6.1.0",
|
||||||
@@ -1232,7 +1242,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1245,6 +1255,21 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "compact_str"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a"
|
||||||
|
dependencies = [
|
||||||
|
"castaway 0.2.4",
|
||||||
|
"cfg-if",
|
||||||
|
"itoa",
|
||||||
|
"rustversion",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "concat-idents"
|
name = "concat-idents"
|
||||||
version = "1.1.5"
|
version = "1.1.5"
|
||||||
@@ -3196,7 +3221,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2 0.5.10",
|
"socket2 0.6.0",
|
||||||
"system-configuration",
|
"system-configuration",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
@@ -3648,7 +3673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9"
|
checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel 1.9.0",
|
"async-channel 1.9.0",
|
||||||
"castaway",
|
"castaway 0.1.2",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"curl",
|
"curl",
|
||||||
"curl-sys",
|
"curl-sys",
|
||||||
@@ -5644,7 +5669,7 @@ dependencies = [
|
|||||||
"quinn-udp",
|
"quinn-udp",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"rustls",
|
"rustls",
|
||||||
"socket2 0.5.10",
|
"socket2 0.6.0",
|
||||||
"thiserror 2.0.17",
|
"thiserror 2.0.17",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
@@ -5681,7 +5706,7 @@ dependencies = [
|
|||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2 0.5.10",
|
"socket2 0.6.0",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.60.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ clash_verge_logger = { version = "0.1.0", git = "https://github.com/clash-verge-
|
|||||||
clash_verge_service_ipc = { version = "2.0.15", features = [
|
clash_verge_service_ipc = { version = "2.0.15", 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" }
|
||||||
|
compact_str = { version = "0.9.0", features = ["serde"] }
|
||||||
# clash_verge_service_ipc = { version = "2.0.14", features = [
|
# clash_verge_service_ipc = { version = "2.0.14", features = [
|
||||||
# "client",
|
# "client",
|
||||||
# ], path = "../../clash-verge-service-ipc" }
|
# ], path = "../../clash-verge-service-ipc" }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use crate::{
|
|||||||
core::{CoreManager, handle},
|
core::{CoreManager, handle},
|
||||||
};
|
};
|
||||||
use crate::{config::*, feat, logging, utils::logging::Type, wrap_err};
|
use crate::{config::*, feat, logging, utils::logging::Type, wrap_err};
|
||||||
|
use compact_str::CompactString;
|
||||||
use serde_yaml_ng::Mapping;
|
use serde_yaml_ng::Mapping;
|
||||||
|
|
||||||
/// 复制Clash环境变量
|
/// 复制Clash环境变量
|
||||||
@@ -285,7 +286,7 @@ pub async fn validate_dns_config() -> CmdResult<(bool, String)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_clash_logs() -> CmdResult<VecDeque<String>> {
|
pub async fn get_clash_logs() -> CmdResult<VecDeque<CompactString>> {
|
||||||
let logs = CoreManager::global()
|
let logs = CoreManager::global()
|
||||||
.get_clash_logs()
|
.get_clash_logs()
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use crate::AsyncHandler;
|
|||||||
use crate::core::logger::ClashLogger;
|
use crate::core::logger::ClashLogger;
|
||||||
use crate::process::CommandChildGuard;
|
use crate::process::CommandChildGuard;
|
||||||
use crate::utils::init::sidecar_writer;
|
use crate::utils::init::sidecar_writer;
|
||||||
use crate::utils::logging::SharedWriter;
|
use crate::utils::logging::{SharedWriter, write_sidecar_log};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::*,
|
config::*,
|
||||||
core::{
|
core::{
|
||||||
@@ -17,9 +17,9 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use compact_str::CompactString;
|
||||||
use flexi_logger::DeferredNow;
|
use flexi_logger::DeferredNow;
|
||||||
use flexi_logger::writers::LogWriter;
|
use log::Level;
|
||||||
use log::Record;
|
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::{fmt, path::PathBuf, sync::Arc};
|
use std::{fmt, path::PathBuf, sync::Arc};
|
||||||
@@ -58,29 +58,6 @@ impl fmt::Display for RunningMode {
|
|||||||
|
|
||||||
use crate::config::IVerge;
|
use crate::config::IVerge;
|
||||||
|
|
||||||
fn write_sidecar_log(
|
|
||||||
writer: &dyn LogWriter,
|
|
||||||
now: &mut DeferredNow,
|
|
||||||
level: log::Level,
|
|
||||||
message: String,
|
|
||||||
) -> String {
|
|
||||||
let boxed = message.into_boxed_str();
|
|
||||||
let leaked: &'static mut str = Box::leak(boxed);
|
|
||||||
let leaked_ptr = leaked as *mut str;
|
|
||||||
{
|
|
||||||
let _ = writer.write(
|
|
||||||
now,
|
|
||||||
&Record::builder()
|
|
||||||
.args(format_args!("{}", &*leaked))
|
|
||||||
.level(level)
|
|
||||||
.target("sidecar")
|
|
||||||
.build(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// SAFETY: `leaked` originated from `Box::leak` above; reboxing frees it immediately after use.
|
|
||||||
unsafe { String::from(Box::from_raw(leaked_ptr)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CoreManager {
|
impl CoreManager {
|
||||||
/// 检查文件是否为脚本文件
|
/// 检查文件是否为脚本文件
|
||||||
fn is_script_file(&self, path: &str) -> Result<bool> {
|
fn is_script_file(&self, path: &str) -> Result<bool> {
|
||||||
@@ -767,30 +744,35 @@ impl CoreManager {
|
|||||||
|
|
||||||
AsyncHandler::spawn(|| async move {
|
AsyncHandler::spawn(|| async move {
|
||||||
while let Some(event) = rx.recv().await {
|
while let Some(event) = rx.recv().await {
|
||||||
let w = shared_writer.lock().await;
|
|
||||||
match event {
|
match event {
|
||||||
tauri_plugin_shell::process::CommandEvent::Stdout(line) => {
|
tauri_plugin_shell::process::CommandEvent::Stdout(line) => {
|
||||||
let mut now = DeferredNow::default();
|
let mut now = DeferredNow::default();
|
||||||
let message = String::from_utf8_lossy(&line).into_owned();
|
let message =
|
||||||
let message = write_sidecar_log(&*w, &mut now, log::Level::Error, message);
|
CompactString::from(String::from_utf8_lossy(&line).into_owned());
|
||||||
|
let w = shared_writer.lock().await;
|
||||||
|
write_sidecar_log(w, &mut now, Level::Error, &message);
|
||||||
ClashLogger::global().append_log(message);
|
ClashLogger::global().append_log(message);
|
||||||
}
|
}
|
||||||
tauri_plugin_shell::process::CommandEvent::Stderr(line) => {
|
tauri_plugin_shell::process::CommandEvent::Stderr(line) => {
|
||||||
let mut now = DeferredNow::default();
|
let mut now = DeferredNow::default();
|
||||||
let message = String::from_utf8_lossy(&line).into_owned();
|
let message =
|
||||||
let message = write_sidecar_log(&*w, &mut now, log::Level::Error, message);
|
CompactString::from(String::from_utf8_lossy(&line).into_owned());
|
||||||
|
let w = shared_writer.lock().await;
|
||||||
|
write_sidecar_log(w, &mut now, Level::Error, &message);
|
||||||
ClashLogger::global().append_log(message);
|
ClashLogger::global().append_log(message);
|
||||||
}
|
}
|
||||||
tauri_plugin_shell::process::CommandEvent::Terminated(term) => {
|
tauri_plugin_shell::process::CommandEvent::Terminated(term) => {
|
||||||
let mut now = DeferredNow::default();
|
let mut now = DeferredNow::default();
|
||||||
let message = if let Some(code) = term.code {
|
let message = if let Some(code) = term.code {
|
||||||
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 {
|
||||||
format!("Process terminated by signal: {}", signal)
|
CompactString::from(format!("Process terminated by signal: {}", signal))
|
||||||
} else {
|
} else {
|
||||||
"Process terminated".to_string()
|
CompactString::from("Process terminated")
|
||||||
};
|
};
|
||||||
write_sidecar_log(&*w, &mut now, log::Level::Info, message);
|
let w = shared_writer.lock().await;
|
||||||
|
write_sidecar_log(w, &mut now, Level::Info, &message);
|
||||||
|
ClashLogger::global().clear_logs();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -899,10 +881,15 @@ impl CoreManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_clash_logs(&self) -> Result<VecDeque<String>> {
|
pub async fn get_clash_logs(&self) -> Result<VecDeque<CompactString>> {
|
||||||
logging!(info, Type::Core, "get clash logs");
|
logging!(info, Type::Core, "get clash logs");
|
||||||
let logs = match self.get_running_mode() {
|
let logs = match self.get_running_mode() {
|
||||||
RunningMode::Service => service::get_clash_logs_by_service().await?,
|
// TODO 服务端也完成 CompactString 迁移
|
||||||
|
RunningMode::Service => service::get_clash_logs_by_service()
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.map(CompactString::from)
|
||||||
|
.collect::<VecDeque<CompactString>>(),
|
||||||
RunningMode::Sidecar => ClashLogger::global().get_logs().clone(),
|
RunningMode::Sidecar => ClashLogger::global().get_logs().clone(),
|
||||||
_ => VecDeque::new(),
|
_ => VecDeque::new(),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
use std::{collections::VecDeque, sync::Arc};
|
use std::{collections::VecDeque, sync::Arc};
|
||||||
|
|
||||||
|
use compact_str::CompactString;
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use parking_lot::{RwLock, RwLockReadGuard};
|
use parking_lot::{RwLock, RwLockReadGuard};
|
||||||
|
|
||||||
const LOGS_QUEUE_LEN: usize = 100;
|
const LOGS_QUEUE_LEN: usize = 100;
|
||||||
|
|
||||||
pub struct ClashLogger {
|
pub struct ClashLogger {
|
||||||
logs: Arc<RwLock<VecDeque<String>>>,
|
logs: Arc<RwLock<VecDeque<CompactString>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClashLogger {
|
impl ClashLogger {
|
||||||
@@ -18,11 +19,11 @@ impl ClashLogger {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_logs(&self) -> RwLockReadGuard<'_, VecDeque<String>> {
|
pub fn get_logs(&self) -> RwLockReadGuard<'_, VecDeque<CompactString>> {
|
||||||
self.logs.read()
|
self.logs.read()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_log(&self, text: String) {
|
pub fn append_log(&self, text: CompactString) {
|
||||||
let mut logs = self.logs.write();
|
let mut logs = self.logs.write();
|
||||||
if logs.len() > LOGS_QUEUE_LEN {
|
if logs.len() > LOGS_QUEUE_LEN {
|
||||||
logs.pop_front();
|
logs.pop_front();
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
|
use compact_str::CompactString;
|
||||||
use flexi_logger::writers::FileLogWriter;
|
use flexi_logger::writers::FileLogWriter;
|
||||||
|
use flexi_logger::writers::LogWriter;
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
#[cfg(not(feature = "tauri-dev"))]
|
||||||
use flexi_logger::{DeferredNow, filter::LogLineFilter};
|
use flexi_logger::{DeferredNow, filter::LogLineFilter};
|
||||||
|
use log::Level;
|
||||||
#[cfg(not(feature = "tauri-dev"))]
|
#[cfg(not(feature = "tauri-dev"))]
|
||||||
use log::Record;
|
use log::Record;
|
||||||
use std::{fmt, sync::Arc};
|
use std::{fmt, sync::Arc};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::{Mutex, MutexGuard};
|
||||||
|
|
||||||
pub type SharedWriter = Arc<Mutex<FileLogWriter>>;
|
pub type SharedWriter = Arc<Mutex<FileLogWriter>>;
|
||||||
|
|
||||||
@@ -134,6 +137,23 @@ macro_rules! logging_error {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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"))]
|
#[cfg(not(feature = "tauri-dev"))]
|
||||||
pub struct NoModuleFilter<'a>(pub &'a [&'a str]);
|
pub struct NoModuleFilter<'a>(pub &'a [&'a str]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user