From f425fbaf9db8bff6766f56bac448443b49709a14 Mon Sep 17 00:00:00 2001 From: GyDi Date: Fri, 18 Nov 2022 22:08:06 +0800 Subject: [PATCH] feat: adjust clash log --- src-tauri/src/core/clash_api.rs | 57 +++++++++++++++++++++++++++++++ src-tauri/src/core/core.rs | 38 +++++++++++++++------ src-tauri/src/core/tray.rs | 1 + src-tauri/src/core/win_service.rs | 5 +-- 4 files changed, 88 insertions(+), 13 deletions(-) diff --git a/src-tauri/src/core/clash_api.rs b/src-tauri/src/core/clash_api.rs index cb00db8..2261d1d 100644 --- a/src-tauri/src/core/clash_api.rs +++ b/src-tauri/src/core/clash_api.rs @@ -62,3 +62,60 @@ fn clash_client_info() -> Result<(String, HeaderMap)> { Ok((server, headers)) } + +/// 缩短clash的日志 +pub fn parse_log(log: String) -> String { + if log.starts_with("time=") { + return (&log[33..]).to_owned(); + } + (&log[9..]).to_owned() +} + +/// 缩短clash -t的错误输出 +/// 仅适配 clash p核 8-26、clash meta 1.13.1 +pub fn parse_check_output(log: String) -> String { + let t = log.find("time="); + let m = log.find("msg="); + let mr = log.rfind('"'); + + if let (Some(_), Some(m), Some(mr)) = (t, m, mr) { + let e = match log.find("level=error msg=") { + Some(e) => e + 17, + None => m + 5, + }; + + if mr > m { + return (&log[e..mr]).to_owned(); + } + } + + let l = log.find("error="); + let r = log.find("path=").or(Some(log.len())); + + if let (Some(l), Some(r)) = (l, r) { + return (&log[(l + 6)..(r - 1)]).to_owned(); + } + + log +} + +#[test] +fn test_parse_check_output() { + let str1 = r#"xxxx\n time="2022-11-18T20:42:58+08:00" level=error msg="proxy 0: 'alpn' expected type 'string', got unconvertible type '[]interface {}'""#; + let str2 = r#"20:43:49 ERR [Config] configuration file test failed error=proxy 0: unsupport proxy type: hysteria path=xxx"#; + let str3 = r#" + "time="2022-11-18T21:38:01+08:00" level=info msg="Start initial configuration in progress" + time="2022-11-18T21:38:01+08:00" level=error msg="proxy 0: 'alpn' expected type 'string', got unconvertible type '[]interface {}'" + configuration file xxx\n + "#; + + let res1 = parse_check_output(str1.into()); + let res2 = parse_check_output(str2.into()); + let res3 = parse_check_output(str3.into()); + + println!("res1: {res1}"); + println!("res2: {res2}"); + println!("res3: {res3}"); + + assert_eq!(res1, res3); +} diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 342c202..df0e8d0 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -37,6 +37,7 @@ impl CoreManager { system.refresh_all(); system.process(Pid::from_u32(pid)).map(|proc| { if proc.name().contains("clash") { + log::debug!(target: "app", "kill old clash process"); proc.kill(); } }); @@ -63,8 +64,9 @@ impl CoreManager { .output()?; if !output.status.success() { - Logger::global().set_log(output.stdout.clone()); - bail!("{}", output.stdout); // 过滤掉终端颜色值 + let error = clash_api::parse_check_output(output.stdout.clone()); + Logger::global().set_log(output.stdout); + bail!("{error}"); } Ok(()) @@ -74,8 +76,18 @@ impl CoreManager { pub async fn run_core(&self) -> Result<()> { let config_path = Config::generate_file(ConfigType::Run)?; - if let Some(child) = self.sidecar.lock().take() { - let _ = child.kill(); + let should_kill = match self.sidecar.lock().take() { + Some(child) => { + log::debug!(target: "app", "stop the core sidecar"); + let _ = child.kill(); + true + } + None => false, + }; + + // 这里得等一会儿 + if should_kill { + sleep(Duration::from_millis(500)).await; } #[cfg(target_os = "windows")] @@ -93,6 +105,7 @@ impl CoreManager { if enable { // 服务模式启动失败就直接运行sidecar match { + log::debug!(target: "app", "try to run core in service mode"); win_service::check_service().await?; win_service::run_core_by_service(&config_path).await } { @@ -142,21 +155,21 @@ impl CoreManager { while let Some(event) = rx.recv().await { match event { CommandEvent::Stdout(line) => { - let can_short = line.starts_with("time=") && line.len() > 33; - let stdout = if can_short { &line[33..] } else { &line }; - log::info!(target: "app" ,"[clash]: {}", stdout); + let stdout = clash_api::parse_log(line.clone()); + log::info!(target: "app", "[clash]: {stdout}"); Logger::global().set_log(line); } CommandEvent::Stderr(err) => { - log::error!(target: "app" ,"[clash]: {err}"); + let stdout = clash_api::parse_log(err.clone()); + log::error!(target: "app", "[clash]: {stdout}"); Logger::global().set_log(err); } CommandEvent::Error(err) => { - log::error!(target: "app" ,"[clash]: {err}"); + log::error!(target: "app", "[clash]: {err}"); Logger::global().set_log(err); } CommandEvent::Terminated(_) => { - log::info!(target: "app" ,"clash core terminated"); + log::info!(target: "app", "clash core terminated"); break; } _ => {} @@ -171,6 +184,7 @@ impl CoreManager { pub fn stop_core(&self) -> Result<()> { #[cfg(target_os = "windows")] if *self.use_service_mode.lock() { + log::debug!(target: "app", "stop core by service"); tauri::async_runtime::block_on(async move { log_err!(super::win_service::stop_core_by_service().await); }); @@ -217,6 +231,8 @@ impl CoreManager { /// 更新proxies那些 /// 如果涉及端口和外部控制则需要重启 pub async fn update_config(&self) -> Result<()> { + log::debug!(target: "app", "try to update clash config"); + // 更新配置 Config::generate()?; @@ -233,7 +249,7 @@ impl CoreManager { Ok(_) => break, Err(err) => { if i < 4 { - log::error!(target: "app", "{err}"); + log::info!(target: "app", "{err}"); } else { bail!(err); } diff --git a/src-tauri/src/core/tray.rs b/src-tauri/src/core/tray.rs index 8ec8d09..6d6cfdb 100644 --- a/src-tauri/src/core/tray.rs +++ b/src-tauri/src/core/tray.rs @@ -116,6 +116,7 @@ impl Tray { resolve::resolve_reset(); api::process::kill_children(); app_handle.exit(0); + std::process::exit(0); } _ => {} }, diff --git a/src-tauri/src/core/win_service.rs b/src-tauri/src/core/win_service.rs index f3f8850..16cf70c 100644 --- a/src-tauri/src/core/win_service.rs +++ b/src-tauri/src/core/win_service.rs @@ -98,10 +98,11 @@ pub async fn check_service() -> Result { .build()? .get(url) .send() - .await? + .await + .context("failed to connect to the Clash Verge Service")? .json::() .await - .context("failed to connect to the Clash Verge Service")?; + .context("failed to parse the Clash Verge Service response")?; Ok(response) }