From 88a8652d7b4b17a743805e3f4815ae4a76e11856 Mon Sep 17 00:00:00 2001 From: JoeAllen <2494136784@qq.com> Date: Tue, 29 Sep 2026 00:30:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=A5=E5=85=A5=E8=87=AA=E5=BB=BA=20?= =?UTF-8?q?Sentry=20=E9=94=99=E8=AF=AF=E4=B8=8A=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DSN 指向 rustrak 自建 Sentry(项目 8),release 标记 mqttx@版本 - panic 路径:sentry-panic 链式钩子捕获 + 外层钩子 flush 5s, 确保 panic=abort 终止进程前事件送出 - 存储层 elog! 持久化错误同步 capture_message 上报 - 传输用 reqwest+rustls,避免 openssl 依赖 --- Cargo.lock | 378 +++++++++++++++++++++++++++++++++++++++++- gpui-app/Cargo.toml | 9 + gpui-app/src/main.rs | 24 +++ gpui-app/src/store.rs | 11 +- 4 files changed, 417 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72e9df0..2073baf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1043,6 +1043,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "combine" +version = "4.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "compression-codecs" version = "0.4.43" @@ -1388,6 +1398,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid", +] + [[package]] name = "deranged" version = "0.5.8" @@ -3079,6 +3099,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hostname" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd" +dependencies = [ + "cfg-if", + "libc", + "windows-link 0.2.1", +] + [[package]] name = "html5ever" version = "0.27.0" @@ -3132,6 +3163,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "hybrid-array" version = "0.4.15" @@ -3184,6 +3221,7 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddc03d96684f9226b8a787cdb71488417b53ab5ea8fdb1dac946cb9431cc8bff" dependencies = [ + "base64 0.23.1", "bytes", "futures-channel", "futures-util", @@ -3191,7 +3229,9 @@ dependencies = [ "http-body", "httparse", "hyper", + "ipnet", "libc", + "percent-encoding", "pin-project-lite", "socket2", "tokio", @@ -3538,6 +3578,36 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.21", + "walkdir", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + [[package]] name = "jni-sys" version = "0.3.1" @@ -4078,13 +4148,14 @@ dependencies = [ "rumqttc-v5-next", "rustls", "rustls-native-certs", + "sentry", "serde", "serde_json", "sha1", "sha2 0.10.9", "smol", "tokio", - "ureq", + "ureq 2.12.1", "uuid", ] @@ -4135,6 +4206,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "no_std_io2" version = "0.9.4" @@ -4703,6 +4786,27 @@ dependencies = [ "objc2-foundation 0.3.2", ] +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.13.2", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-cloud-kit", + "objc2-core-data 0.3.2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image 0.3.2", + "objc2-core-location", + "objc2-core-text", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", + "objc2-user-notifications", +] + [[package]] name = "objc2-user-notifications" version = "0.3.2" @@ -4825,6 +4929,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "os_info" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b" +dependencies = [ + "android_system_properties", + "log", + "nix", + "objc2 0.6.4", + "objc2-foundation 0.3.2", + "objc2-ui-kit", + "serde", + "windows-sys 0.61.2", +] + [[package]] name = "parking" version = "2.2.1" @@ -5286,6 +5406,7 @@ version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9746dbde176634f4f2f1faf2404e30a31b2bc1e9cafb5329c95d8177a18c9fc" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.4.3", "lru-slab", @@ -5644,6 +5765,45 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "reqwest" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a1cfa75cc186dd73d5818e510e042e40927bccc9c236b061cea97e1eb08029" +dependencies = [ + "base64 0.23.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "resvg" version = "0.45.1" @@ -5992,6 +6152,33 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1167586491e2b18b8bfbb293e8180ec17c201c4f076d7cb3070ca964e7598f98" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eec689c0bc40ff2458a5977b6619cb718087084a18e02a131c599b62d05e1a5f" + [[package]] name = "rustls-webpki" version = "0.103.15" @@ -6158,6 +6345,103 @@ dependencies = [ "serde_core", ] +[[package]] +name = "sentry" +version = "0.49.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa951f4e644464ebfd2347a7ab03b0828c512d2448a76262cad2607b343dff4" +dependencies = [ + "cfg_aliases", + "httpdate", + "reqwest", + "rustls", + "sentry-backtrace", + "sentry-contexts", + "sentry-core", + "sentry-panic", + "sentry-tracing", + "tokio", + "ureq 3.4.2", +] + +[[package]] +name = "sentry-backtrace" +version = "0.49.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f27cf048aa63ccd5bc94c29989133eabb82e9c6bf7441b58e9d4a95837a105" +dependencies = [ + "backtrace", + "regex", + "sentry-core", +] + +[[package]] +name = "sentry-contexts" +version = "0.49.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5ed680585dbdacdf9859c2b4dc53358ff02bd256766882e22e343836db36b22" +dependencies = [ + "hostname", + "libc", + "os_info", + "rustc_version", + "sentry-core", + "uname", +] + +[[package]] +name = "sentry-core" +version = "0.49.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ed398494bb8fc412a11a182c1883a10ae147587b8f6314abd222d1d626f31b" +dependencies = [ + "rand 0.10.3", + "sentry-types", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "sentry-panic" +version = "0.49.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7153e68642b761ed3aa62c022795c11b2facc728b2db7484084492373c944f9" +dependencies = [ + "sentry-backtrace", + "sentry-core", +] + +[[package]] +name = "sentry-tracing" +version = "0.49.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e7db1aefdf623f4e48e21ec9e4af535024187aeafb2a4cc7e29d035def5a13" +dependencies = [ + "bitflags 2.13.2", + "sentry-backtrace", + "sentry-core", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sentry-types" +version = "0.49.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c18bf7b159bdfc7c8f97816f476b4947a1937fb6bea9d38d3479e58631614ac" +dependencies = [ + "debugid", + "hex", + "rand 0.10.3", + "serde", + "serde_json", + "thiserror 2.0.21", + "time", + "url", + "uuid", +] + [[package]] name = "serde" version = "1.0.229" @@ -6375,6 +6659,16 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + [[package]] name = "simd_helpers" version = "0.1.0" @@ -6933,6 +7227,7 @@ dependencies = [ "powerfmt", "serde_core", "time-core", + "time-macros", ] [[package]] @@ -6941,6 +7236,16 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -7161,6 +7466,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.13.2", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -7298,6 +7621,15 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", +] + [[package]] name = "unicase" version = "2.9.0" @@ -7400,6 +7732,34 @@ dependencies = [ "webpki-roots 0.26.11", ] +[[package]] +name = "ureq" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a7ac20be9b7726e0bbdbf974c059676d9acb1cd414961f570a4e8231cacd7fc" +dependencies = [ + "base64 0.23.1", + "log", + "percent-encoding", + "rustls", + "rustls-pki-types", + "ureq-proto", + "utf8-zero", + "webpki-roots 1.0.9", +] + +[[package]] +name = "ureq-proto" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86fd172ccca569e458f61b6bdd6220965a9ef36e672a6852953b51a0e1583be" +dependencies = [ + "base64 0.23.1", + "http", + "httparse", + "log", +] + [[package]] name = "url" version = "2.5.8" @@ -7410,6 +7770,7 @@ dependencies = [ "idna", "percent-encoding", "serde", + "serde_derive", ] [[package]] @@ -7472,6 +7833,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-zero" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -7810,6 +8177,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.11" diff --git a/gpui-app/Cargo.toml b/gpui-app/Cargo.toml index fa54b13..2a697dc 100644 --- a/gpui-app/Cargo.toml +++ b/gpui-app/Cargo.toml @@ -43,3 +43,12 @@ rfd = "0.17" # OTA 自更新:Gitea Release 检查/下载(ureq 用 rustls,与 rumqttc 依赖同源) ureq = { version = "2", features = ["json"] } sha2 = "0.10" + +# 错误上报(自建 Sentry):panic 捕获 + 持久化错误;rustls 传输避免 openssl 依赖 +sentry = { version = "0.49", default-features = false, features = [ + "backtrace", + "contexts", + "panic", + "reqwest", + "rustls", +] } diff --git a/gpui-app/src/main.rs b/gpui-app/src/main.rs index aa054ac..9791f6e 100644 --- a/gpui-app/src/main.rs +++ b/gpui-app/src/main.rs @@ -4,6 +4,19 @@ use gpui_kit::*; use mqttx_desktop::ui; use mqttx_desktop::update; +/// 自建 Sentry(rustrak):panic 与关键错误上报。 +const SENTRY_DSN: &str = + "https://9853b05c2a3a4fce921c650587168f49@api.rustrak.sentry.heavenlybook.cn/8"; + +/// 返回的 guard 必须在程序整个生命周期内存活,drop 即停用上报。 +fn init_sentry() -> sentry::ClientInitGuard { + sentry::init( + sentry::ClientOptions::new() + .dsn(SENTRY_DSN) + .release(format!("mqttx@{}", env!("CARGO_PKG_VERSION"))), + ) +} + fn main() { // OTA 收尾:清理遗留文件;若暂存区有待安装的新版本(用户上次同意安装), // 在进入 UI 前完成自替换并重启。 @@ -15,6 +28,17 @@ fn main() { std::process::exit(0); } + let _sentry_guard = init_sentry(); + // sentry 的 panic 钩子只捕获不等待传输;再包一层在钩子末尾 flush, + // 保证 panic=abort 立即终止进程前事件已送出。 + let chained_panic_hook = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |info| { + chained_panic_hook(info); + if let Some(client) = sentry::Hub::current().client() { + client.flush(Some(std::time::Duration::from_secs(5))); + } + })); + application() // AllAssets 嵌入全量 Lucide 图标;Assets 只含 default-icons.txt 的 101 个, // 其余 IconName(MailOpen/SlidersHorizontal 等)运行时会渲染空白 diff --git a/gpui-app/src/store.rs b/gpui-app/src/store.rs index cc60a05..e51c9e9 100644 --- a/gpui-app/src/store.rs +++ b/gpui-app/src/store.rs @@ -4,13 +4,16 @@ //! //! 刻意与官方 Electron MQTTX 的 `MQTTX/` 目录区分,避免互相覆盖数据。 -/// 存储层诊断输出到 stderr(避免仅为文件持久化引入日志框架)。 +/// 存储层诊断输出到 stderr(避免仅为文件持久化引入日志框架), +/// 并同步上报 Sentry(未初始化时为空操作)。 macro_rules! elog { - ($($arg:tt)*) => { + ($($arg:tt)*) => {{ + let msg = format!($($arg)*); eprintln!("[store][{}] {}", chrono::Local::now().format("%H:%M:%S"), - format!($($arg)*)) - }; + msg); + sentry::capture_message(&msg, sentry::Level::Error); + }}; } use std::path::{Path, PathBuf};