From 0d847cba4d46a8523e4c7397bca53a15b52ba755 Mon Sep 17 00:00:00 2001 From: AkiChase <1003019131@qq.com> Date: Tue, 25 Mar 2025 15:24:37 +0800 Subject: [PATCH] feat: unified Logging for frontend and backend --- package.json | 1 + pnpm-lock.yaml | 10 + src-tauri/Cargo.lock | 290 +++++++++++++++++++++++++ src-tauri/Cargo.toml | 3 + src-tauri/capabilities/default.json | 3 +- src-tauri/src/adb.rs | 10 +- src-tauri/src/client.rs | 12 +- src-tauri/src/command.rs | 8 +- src-tauri/src/main.rs | 14 ++ src-tauri/src/socket.rs | 45 ++-- src/components/Device.vue | 9 +- src/components/keyboard/KeyCommon.vue | 4 +- src/components/keyboard/KeySetting.vue | 10 +- src/components/setting/Data.vue | 52 +++-- src/i18n/en-US.json | 3 +- src/i18n/zh-CN.json | 3 +- src/main.ts | 3 + src/store/localStore.ts | 4 +- src/tools/hooks.ts | 4 +- src/tools/hotkey.ts | 17 +- src/tools/websocket.ts | 8 +- 21 files changed, 436 insertions(+), 77 deletions(-) diff --git a/package.json b/package.json index 125027b..2d0d7eb 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@tauri-apps/cli": "^2.3.1", "@tauri-apps/plugin-clipboard-manager": "~2.2.1", "@tauri-apps/plugin-http": "~2", + "@tauri-apps/plugin-log": "~2", "@tauri-apps/plugin-os": "~2", "@tauri-apps/plugin-process": "~2", "@tauri-apps/plugin-shell": "~2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e0921e..762ffb1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: '@tauri-apps/plugin-http': specifier: ~2 version: 2.3.0 + '@tauri-apps/plugin-log': + specifier: ~2 + version: 2.3.1 '@tauri-apps/plugin-os': specifier: ~2 version: 2.2.0 @@ -702,6 +705,9 @@ packages: '@tauri-apps/plugin-http@2.3.0': resolution: {integrity: sha512-pigTvz+zzAqbIhCzRiR1GE98Jw7A03j2V+Eiexr9thBI8VfMiwFQMcbgON51xlwnVaI72LdbYKNajU84im8tlg==} + '@tauri-apps/plugin-log@2.3.1': + resolution: {integrity: sha512-nnKGHENWt7teqvUlIKxd6bp2wCUrrLvCvajN6CWbyrHBNKPi/pyKELzD511siEMDEdndbiZ/GEhiK0xBtZopRg==} + '@tauri-apps/plugin-os@2.2.0': resolution: {integrity: sha512-HszbCdbisMlu5QhCNAN8YIWyz2v33abAWha6+uvV2CKX8P5VSct/y+kEe22JeyqrxCnWlQ3DRx7s49Byg7/0EA==} @@ -1969,6 +1975,10 @@ snapshots: dependencies: '@tauri-apps/api': 2.1.1 + '@tauri-apps/plugin-log@2.3.1': + dependencies: + '@tauri-apps/api': 2.1.1 + '@tauri-apps/plugin-os@2.2.0': dependencies: '@tauri-apps/api': 2.1.1 diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 5481379..1442c49 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -17,6 +17,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -47,6 +58,23 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +[[package]] +name = "android_log-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" + +[[package]] +name = "android_logger" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f39be698127218cca460cb624878c9aa4e2b47dba3b277963d2bf00bad263b" +dependencies = [ + "android_log-sys", + "env_filter", + "log", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -80,6 +108,12 @@ dependencies = [ "x11rb", ] +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "atk" version = "0.18.2" @@ -157,6 +191,18 @@ dependencies = [ "serde", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -184,6 +230,29 @@ dependencies = [ "objc2 0.6.0", ] +[[package]] +name = "borsh" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b74d67a0fc0af8e9823b79fd1c43a0900e5a8f0e0f4cc9210796bf3a820126" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d37ed1b2c9b78421218a0b4f6d8349132d6ec2cfeba1cfb0118b0a8e268df9e" +dependencies = [ + "once_cell", + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.99", +] + [[package]] name = "brotli" version = "7.0.0" @@ -211,6 +280,39 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +[[package]] +name = "byte-unit" +version = "5.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174" +dependencies = [ + "rust_decimal", + "serde", + "utf8-width", +] + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bytemuck" version = "1.22.0" @@ -361,8 +463,10 @@ checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", "serde", + "wasm-bindgen", "windows-link", ] @@ -783,6 +887,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -824,6 +938,15 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fern" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4316185f709b23713e41e3195f90edef7fb00c3ed4adc79769cf09cc762a3b29" +dependencies = [ + "log", +] + [[package]] name = "field-offset" version = "0.3.6" @@ -886,6 +1009,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futf" version = "0.1.5" @@ -1320,6 +1449,9 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] [[package]] name = "hashbrown" @@ -1911,6 +2043,9 @@ name = "log" version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +dependencies = [ + "value-bag", +] [[package]] name = "mac" @@ -2079,6 +2214,15 @@ dependencies = [ "syn 2.0.99", ] +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + [[package]] name = "objc-sys" version = "0.3.5" @@ -2717,6 +2861,26 @@ version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "publicsuffix" version = "2.3.0" @@ -2797,6 +2961,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.7.3" @@ -2933,6 +3103,15 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.12.12" @@ -2997,6 +3176,51 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rkyv" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa7de2ba56ac291bd90c6b9bece784a52ae1411f9506544b3eae36dd2356d50" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -3133,13 +3357,16 @@ name = "scrcpy-mask" version = "0.6.0" dependencies = [ "anyhow", + "chrono", "lazy_static", + "log", "serde", "serde_json", "tauri", "tauri-build", "tauri-plugin-clipboard-manager", "tauri-plugin-http", + "tauri-plugin-log", "tauri-plugin-os", "tauri-plugin-process", "tauri-plugin-shell", @@ -3147,6 +3374,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "selectors" version = "0.22.0" @@ -3357,6 +3590,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "0.3.11" @@ -3631,6 +3870,12 @@ dependencies = [ "syn 2.0.99", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "target-lexicon" version = "0.12.16" @@ -3827,6 +4072,28 @@ dependencies = [ "urlpattern", ] +[[package]] +name = "tauri-plugin-log" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2341d5b9bc5318c8e34f35a569140c78337241aa9c14091550b424c49f0314e0" +dependencies = [ + "android_logger", + "byte-unit", + "fern", + "log", + "objc2 0.6.0", + "objc2-foundation 0.3.0", + "serde", + "serde_json", + "serde_repr", + "swift-rs", + "tauri", + "tauri-plugin", + "thiserror 2.0.12", + "time", +] + [[package]] name = "tauri-plugin-os" version = "2.2.0" @@ -4061,7 +4328,9 @@ checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" dependencies = [ "deranged", "itoa 1.0.15", + "libc", "num-conv", + "num_threads", "powerfmt", "serde", "time-core", @@ -4408,6 +4677,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -4424,6 +4699,12 @@ dependencies = [ "serde", ] +[[package]] +name = "value-bag" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" + [[package]] name = "version-compare" version = "0.2.0" @@ -5197,6 +5478,15 @@ dependencies = [ "x11-dl", ] +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x11" version = "2.21.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 707eb5e..bd7faee 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -16,6 +16,8 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" anyhow = "1" lazy_static = "1" +log = "0.4" +chrono = "0.4" tokio = { version = "1", features = ["rt-multi-thread", "net", "macros", "io-util", "time", "sync"] } tauri-plugin-store = "2" tauri-plugin-process = "2" @@ -23,3 +25,4 @@ tauri-plugin-shell = "2" tauri-plugin-http = "2" tauri-plugin-clipboard-manager = "2" tauri-plugin-os = "2" +tauri-plugin-log = "2" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index db16f5f..4e06a37 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -49,6 +49,7 @@ "clipboard-manager:default", "clipboard-manager:allow-read-text", "clipboard-manager:allow-write-text", - "os:default" + "os:default", + "log:default" ] } \ No newline at end of file diff --git a/src-tauri/src/adb.rs b/src-tauri/src/adb.rs index 5f68cd7..aad319b 100644 --- a/src-tauri/src/adb.rs +++ b/src-tauri/src/adb.rs @@ -24,7 +24,15 @@ impl Device { .args(&["-s", id, "push", src, des]) .output() .with_context(|| format!("Failed to execute 'adb push {} {}'", src, des))?; - Ok(String::from_utf8(res.stdout).unwrap()) + + let output = [ + String::from_utf8(res.stdout)?, + String::from_utf8(res.stderr)?, + ] + .join("\n") + .trim() + .to_string(); + Ok(output) } /// execute "adb reverse" to reverse the device port to local port diff --git a/src-tauri/src/client.rs b/src-tauri/src/client.rs index 7f1fa12..f2bae42 100644 --- a/src-tauri/src/client.rs +++ b/src-tauri/src/client.rs @@ -54,7 +54,7 @@ impl ScrcpyClient { "/data/local/tmp/scrcpy-server.jar", )?; - println!("{}\nSuccessfully push server files", info); + log::info!("Successfully push server files: {}", info); Ok(()) } @@ -65,7 +65,7 @@ impl ScrcpyClient { &format!("tcp:{}", port), &format!("localabstract:scrcpy_{}", scid), )?; - println!("Successfully forward port"); + log::info!("Successfully forward port"); Ok(()) } @@ -76,7 +76,7 @@ impl ScrcpyClient { &format!("localabstract:scrcpy_{}", scid), &format!("tcp:{}", port), )?; - println!("Successfully reverse port"); + log::info!("Successfully reverse port"); Ok(()) } @@ -97,7 +97,7 @@ impl ScrcpyClient { ], )?; - println!("Starting scrcpy server..."); + log::info!("Starting scrcpy server..."); let out = child.stdout.take().unwrap(); let mut out = std::io::BufReader::new(out); let mut s = String::new(); @@ -107,13 +107,13 @@ impl ScrcpyClient { if let core::result::Result::Ok(Some(_)) = child.try_wait() { break; } - print!("{}", s); + log::info!("{}", s.trim()); // clear string to store new line only s.clear(); } *share::CLIENT_INFO.lock().unwrap() = None; - println!("Scrcpy server closed"); + log::info!("Scrcpy server closed"); Ok(()) } } diff --git a/src-tauri/src/command.rs b/src-tauri/src/command.rs index f27f33f..675435a 100644 --- a/src-tauri/src/command.rs +++ b/src-tauri/src/command.rs @@ -84,12 +84,12 @@ pub fn start_scrcpy_server( let share_app = app.clone(); let (device_reply_sender, mut device_reply_receiver) = tokio::sync::mpsc::channel::(16); - println!("device reply channel created"); + log::info!("Device reply channel created"); tokio::spawn(async move { while let Some(reply) = device_reply_receiver.recv().await { share_app.emit("device-reply", reply).unwrap(); } - println!("device reply channel closed"); + log::info!("Device reply channel closed"); }); // create channel to transmit front msg to TcpStream handler @@ -97,10 +97,10 @@ pub fn start_scrcpy_server( let share_app = app.clone(); let listen_handler = share_app.listen("front-command", move |event| { let sender = front_msg_sender.clone(); - // println!("收到front-command: {}", event.payload()); + // log::debug!("Received front-command: {}", event.payload()); tokio::spawn(async move { if let Err(_) = sender.send(event.payload().into()).await { - println!("front-command forwarding failure, please restart the program !"); + log::error!("Forwarding front command failed, please restart the program!"); }; }); }); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 32d417f..2b7cba4 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -3,10 +3,24 @@ use scrcpy_mask::{command, resource::ResHelper}; use tauri::Manager; +use tauri_plugin_log::{Target, TargetKind}; #[tokio::main] async fn main() { tauri::Builder::default() + .plugin( + tauri_plugin_log::Builder::new() + .clear_targets() + .targets([ + Target::new(TargetKind::Webview) + .filter(|metadata| metadata.target().starts_with("scrcpy_mask")), + Target::new(TargetKind::LogDir { + file_name: Some(chrono::Local::now().format("%Y-%m-%d_%H-%M-%S").to_string()), + }) + .filter(|metadata| metadata.target().starts_with("scrcpy_mask")), + ]) + .build(), + ) .plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_http::init()) diff --git a/src-tauri/src/socket.rs b/src-tauri/src/socket.rs index 79ca43a..7232e20 100644 --- a/src-tauri/src/socket.rs +++ b/src-tauri/src/socket.rs @@ -28,7 +28,7 @@ pub async fn connect_socket( .await .context("Socket connect failed")?; - println!("connect to scrcpy-server:{:?}", client.local_addr()); + log::info!("Connected to scrcpy server: {}", client.local_addr().unwrap()); let (read_half, write_half) = client.into_split(); @@ -44,7 +44,7 @@ pub async fn connect_socket( anyhow::Ok(()) } -// 从客户端读取 +// read from scrcpy server async fn read_socket( mut reader: OwnedReadHalf, device_reply_sender: tokio::sync::mpsc::Sender, @@ -52,7 +52,7 @@ async fn read_socket( // read dummy byte let mut buf: [u8; 1] = [0; 1]; if let Err(_e) = reader.read_exact(&mut buf).await { - eprintln!("failed to read dummy byte"); + log::error!("Failed to read dummy byte"); return; } @@ -60,11 +60,11 @@ async fn read_socket( let mut buf: [u8; 64] = [0; 64]; match reader.read(&mut buf).await { Err(_e) => { - eprintln!("failed to read metadata"); + log::error!("Failed to read metadata"); return; } Ok(0) => { - eprintln!("failed to read metadata"); + log::error!("Failed to read metadata"); return; } Ok(n) => { @@ -93,11 +93,11 @@ async fn read_socket( loop { match reader.read_u8().await { Err(e) => { - eprintln!( - "Failed to read from scrcpy server, maybe it was closed. Error:{}", + log::error!( + "Failed to read from scrcpy server, maybe it was closed: {}", e ); - println!("Drop TcpStream reader"); + log::info!("Drop TcpStream reader"); drop(reader); return; } @@ -105,14 +105,14 @@ async fn read_socket( let message_type = match DeviceMsgType::from_u8(message_type) { Some(t) => t, None => { - println!("Ignore unkonw message type: {}", message_type); + log::warn!("Ignore unkonw message type: {}", message_type); continue; } }; if let Err(e) = handle_device_message(message_type, &mut reader, &device_reply_sender).await { - eprintln!("Failed to handle device message: {}", e); + log::warn!("Failed to handle device message: {}", e); } } } @@ -125,7 +125,7 @@ async fn handle_device_message( device_reply_sender: &tokio::sync::mpsc::Sender, ) -> anyhow::Result<()> { match message_type { - // 设备剪切板变动 + // Clipboard changed DeviceMsgType::DeviceMsgTypeClipboard => { let text_length = reader.read_u32().await?; let mut buf: Vec = vec![0; text_length as usize]; @@ -138,7 +138,7 @@ async fn handle_device_message( .to_string(); device_reply_sender.send(msg).await?; } - // 设备剪切板设置成功的回复 + // Clipboard set ACK DeviceMsgType::DeviceMsgTypeAckClipboard => { let sequence = reader.read_u64().await?; let msg = json!({ @@ -148,14 +148,14 @@ async fn handle_device_message( .to_string(); device_reply_sender.send(msg).await?; } - // 虚拟设备输出,仅读取但不做进一步处理 + // Virtual device output(read only but not further processing) DeviceMsgType::DeviceMsgTypeUhidOutput => { let _id = reader.read_u16().await?; let size = reader.read_u16().await?; let mut buf: Vec = vec![0; size as usize]; reader.read_exact(&mut buf).await?; } - // 设备旋转 + // Device rotation DeviceMsgType::DeviceMsgTypeRotation => { let rotation = reader.read_u16().await?; let width = reader.read_i32().await?; @@ -179,7 +179,7 @@ async fn handle_device_message( anyhow::Ok(()) } -// 接收前端发送的消息,执行相关操作 +// Receive messages sent by the front-end and perform related operations async fn recv_front_msg( mut write_half: OwnedWriteHalf, mut front_msg_receiver: tokio::sync::mpsc::Receiver, @@ -189,12 +189,12 @@ async fn recv_front_msg( while let Some(msg) = front_msg_receiver.recv().await { match serde_json::from_str::(&msg) { Err(_e) => { - println!("无法解析的Json数据: {}", msg); + log::warn!("Failed to parse front msg as json: {}", msg); } Ok(payload) => { if let Some(front_msg_type) = payload["msgType"].as_i64() { - // 发送原始控制信息 if front_msg_type >= 0 && front_msg_type <= 14 { + // Processing Control commands let ctrl_msg_type = ControlMsgType::from_i64(front_msg_type).unwrap(); control_msg::send_ctrl_msg( ctrl_msg_type, @@ -204,15 +204,15 @@ async fn recv_front_msg( .await; continue; } else { - // 处理Scrcpy Mask命令 + // Processing Scrcpy Mask commands if let Some(cmd_type) = ScrcpyMaskCmdType::from_i64(front_msg_type) { if let ScrcpyMaskCmdType::Shutdown = cmd_type { *share::CLIENT_INFO.lock().unwrap() = None; drop(write_half); - println!("Drop TcpStream writer"); + log::info!("Drop TcpStream writer"); app.unlisten(listen_handler); - println!("front msg channel closed"); + log::info!("Front msg channel closed"); return; } @@ -225,14 +225,13 @@ async fn recv_front_msg( } } } else { - eprintln!("fc-command invalid!"); - eprintln!("{:?}", payload); + log::warn!("Invalid font command!: {:?}", payload); } } }; } - println!("font msg channel closed"); + log::info!("Font msg channel closed"); } #[derive(Debug)] diff --git a/src/components/Device.vue b/src/components/Device.vue index ac67fec..8719b99 100644 --- a/src/components/Device.vue +++ b/src/components/Device.vue @@ -52,6 +52,7 @@ import ButtonWithTip from "./common/ButtonWithTip.vue"; import { NonReactiveStore } from "../store/noneReactiveStore"; import { useRoute } from "vue-router"; import { useHorRotation } from "../tools/hooks"; +import { error, warn } from "@tauri-apps/plugin-log"; const { t } = useI18n(); const dialog = useDialog(); @@ -124,11 +125,12 @@ onMounted(async () => { } break; default: - console.warn("Unknown reply", payload); + warn("Unknown device reply: " + event.payload); break; } } catch (e) { - console.error(e); + error(("Failed to handle device reply: " + event.payload) as string); + console.error(event.payload, e); } }); }); @@ -367,6 +369,7 @@ async function refreshDevices() { devices.value = await adbDevices(); } catch (e) { message.error(t("pages.Device.adbDeviceError")); + error("Failed to get devices, " + e); console.error(e); } store.hideLoading(); @@ -382,6 +385,7 @@ async function restartAdb() { await adbRestartServer(); } catch (e) { message.error(t("pages.Device.adbRestartError")); + error("Failed to restart adb server, " + e); console.error(e); } store.hideLoading(); @@ -399,6 +403,7 @@ async function connectDevice() { await refreshDevices(); } catch (e) { message.error("t('pages.Device.adbConnectError')"); + error("Failed to connect device wirelessly, " + e); console.error(e); } } diff --git a/src/components/keyboard/KeyCommon.vue b/src/components/keyboard/KeyCommon.vue index e2d062a..00e41f3 100644 --- a/src/components/keyboard/KeyCommon.vue +++ b/src/components/keyboard/KeyCommon.vue @@ -22,6 +22,7 @@ import { import { useKeyboardStore } from "../../store/keyboard"; import { useI18n } from "vue-i18n"; import { configKeyCommon } from "./config"; +import { error } from "@tauri-apps/plugin-log"; const props = defineProps<{ index: number; @@ -148,8 +149,9 @@ function saveMacro() { keyboardStore.edited = true; message.success(t("pages.KeyBoard.KeyCommon.macroParseSuccess")); } catch (e) { - console.error(e); message.error(t("pages.KeyBoard.KeyCommon.macroParseFailed")); + error("Failed to save macro, " + e); + console.error(e); } } diff --git a/src/components/keyboard/KeySetting.vue b/src/components/keyboard/KeySetting.vue index bdc7a68..190bc3a 100644 --- a/src/components/keyboard/KeySetting.vue +++ b/src/components/keyboard/KeySetting.vue @@ -21,6 +21,7 @@ import { useI18n } from "vue-i18n"; import { writeText } from "@tauri-apps/plugin-clipboard-manager"; import { LocalStore } from "../../store/localStore"; import { NonReactiveStore } from "../../store/noneReactiveStore"; +import { error } from "@tauri-apps/plugin-log"; const { t } = useI18n(); const store = useGlobalStore(); @@ -150,8 +151,9 @@ function importKeyMappingConfig() { try { keyMappingConfig = JSON.parse(importModalInputValue.value); } catch (e) { - console.error(e); message.error(t("pages.KeyBoard.KeySetting.importFailed")); + error("Failed to import key mapping config, " + e); + console.error(e); return; } store.keyMappingConfigList.push(keyMappingConfig); @@ -172,8 +174,9 @@ async function importDefaultKeyMappingConfig() { count++; } } catch (e) { - console.error(e); message.error(t("pages.KeyBoard.KeySetting.importDefaultFailed")); + error("Failed to import default key mapping config, " + e); + console.error(e); return; } @@ -266,8 +269,9 @@ function exportKeyMappingConfig() { message.success(t("pages.KeyBoard.KeySetting.exportSuccess")); }) .catch((e) => { - console.error(e); message.error(t("pages.KeyBoard.KeySetting.exportFailed")); + error("Failed to export key mapping config, " + e); + console.error(e); }); } diff --git a/src/components/setting/Data.vue b/src/components/setting/Data.vue index e3475aa..3dc318d 100644 --- a/src/components/setting/Data.vue +++ b/src/components/setting/Data.vue @@ -77,6 +77,14 @@ function delLocalStore(key?: string) { diff --git a/src/i18n/en-US.json b/src/i18n/en-US.json index 6b2ad98..e895078 100644 --- a/src/i18n/en-US.json +++ b/src/i18n/en-US.json @@ -136,7 +136,8 @@ "localStore": "Local data", "delCurData": "Delete current data", "btnRefresh": "Refresh", - "btnDelAll": "Clear local data" + "btnDelAll": "Clear local data", + "logs": "Log dir" }, "About": { "introduction": "A Scrcpy client in Rust & Tarui aimed at providing mouse and key mapping to control Android device.", diff --git a/src/i18n/zh-CN.json b/src/i18n/zh-CN.json index 730dd60..afa2924 100644 --- a/src/i18n/zh-CN.json +++ b/src/i18n/zh-CN.json @@ -136,7 +136,8 @@ "localStore": "本地数据", "delCurData": "删除当前数据", "btnDelAll": "清空本地数据", - "btnRefresh": "刷新" + "btnRefresh": "刷新", + "logs": "日志目录" }, "About": { "about": "关于", diff --git a/src/main.ts b/src/main.ts index 4f0bc3e..510d02b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,6 +4,9 @@ import "./css/global.scss"; import App from "./App.vue"; import router from "./router"; import i18n from "./i18n"; +import { attachConsole } from "@tauri-apps/plugin-log"; + +attachConsole() const pinia = createPinia(); diff --git a/src/store/localStore.ts b/src/store/localStore.ts index e483706..cc2ec17 100644 --- a/src/store/localStore.ts +++ b/src/store/localStore.ts @@ -12,16 +12,18 @@ import { LogicalSize, primaryMonitor, } from "@tauri-apps/api/window"; -import { appDataDir, join } from "@tauri-apps/api/path"; +import { appDataDir, appLogDir, join } from "@tauri-apps/api/path"; export class LocalStore { public static store: Store; public static vueStore: ReturnType; public static path: string; public static dir: string; + public static logDir: string; static async init() { this.dir = await appDataDir(); + this.logDir = await appLogDir(); this.path = await join(this.dir, "store.bin"); this.store = await load("store.bin", { autoSave: true }); this.vueStore = useGlobalStore(); diff --git a/src/tools/hooks.ts b/src/tools/hooks.ts index 8bac216..0d366ed 100644 --- a/src/tools/hooks.ts +++ b/src/tools/hooks.ts @@ -10,6 +10,7 @@ import { useGlobalStore } from "../store/global"; import { h } from "vue"; import { marked } from "marked"; import { open } from "@tauri-apps/plugin-shell"; +import { error } from "@tauri-apps/plugin-log"; const render = new marked.Renderer(); marked.setOptions({ @@ -59,8 +60,9 @@ export function useCheckUpdate() { }); } } catch (e) { - console.error(e); message.error(t("pages.Mask.checkUpdate.failed")); + error("Failed to check for update, " + e); + console.error(e); } }; } diff --git a/src/tools/hotkey.ts b/src/tools/hotkey.ts index 33a4e9f..00b88b5 100644 --- a/src/tools/hotkey.ts +++ b/src/tools/hotkey.ts @@ -38,6 +38,7 @@ import { } from "../frontcommand/controlMsg"; import { NonReactiveStore } from "../store/noneReactiveStore"; import { asType } from "./tools"; +import { error } from "@tauri-apps/plugin-log"; function clientxToPosx(clientx: number) { return clientx < 70 @@ -1289,7 +1290,7 @@ async function execMacro( if (macro === null) return; for (const cmd of macro) { if (!cmd.hasOwnProperty("type") || !cmd.hasOwnProperty("args")) { - console.error("Invalid command: ", cmd); + error("Invalid command: " + cmd); return; } try { @@ -1313,7 +1314,7 @@ async function execMacro( touchAction = TouchAction.Move; break; default: - console.error("Invalid touch action: ", cmd.args[0]); + error("Invalid touch action: " + cmd.args[0]); return; } await touchX( @@ -1337,7 +1338,7 @@ async function execMacro( swipeAction = SwipeAction.NoDown; break; default: - console.error("Invalid swipe action: ", cmd.args[0]); + error("Invalid swipe action: " + cmd.args[0]); return; } await swipe({ @@ -1365,11 +1366,12 @@ async function execMacro( } break; default: - console.error("Invalid command: ", cmd); + error("Invalid command: " + cmd); return; } } catch (e) { - console.error("Invalid command: ", cmd, e); + error(`Invalid command: ${cmd}, ${e}`); + console.error(e); return; } } @@ -1528,13 +1530,14 @@ function applyKeyMappingConfigShortcuts( case "Fire": break; default: - console.error("Invalid item type: ", item); + error("Invalid item type: " + item); break; } } return true; } catch (e) { - console.error("Invalid keyMappingConfig: ", keyMappingConfig, e); + error("Invalid keyMappingConfig, " + e); + console.error(keyMappingConfig, e); clearShortcuts(); return false; } diff --git a/src/tools/websocket.ts b/src/tools/websocket.ts index 9e90c53..01d515c 100644 --- a/src/tools/websocket.ts +++ b/src/tools/websocket.ts @@ -2,6 +2,7 @@ import { useMessage } from "naive-ui"; import { useGlobalStore } from "../store/global"; import { sendKey, shutdown, swipe, touch } from "../frontcommand/scrcpyMaskCmd"; import { useI18n } from "vue-i18n"; +import { error } from "@tauri-apps/plugin-log"; let ws: WebSocket; let sharedMessage: ReturnType; @@ -58,10 +59,11 @@ async function handleMessage(event: MessageEvent) { await shutdown(); sharedStore.controledDevice = null; } else { - console.error("Invalid message received", msg); + error("Invalid message received: " + msg); } - } catch (error) { - console.error("Message received failed", error); + } catch (e) { + error("Message received failed, " + e); + console.error(e); } }