refactor(log): in-place writer lifecycle and span-based core observability (#7889)

* refactor(log): migrate logging to tracing-estuary pipeline

Swap flexi_logger + clash-verge-logger wiring for the tracing-estuary
crate: buffered file sink with explicit panic/exit drains, live level
switching, and tokio-trace/chrome-trace behind crate features.

AsyncLogger moves in-house (VecDeque ring); file format and rotation
stay unchanged.

* fix(log): reset sidecar writer in place and re-pin service-ipc v2.6.7

Rebuilding the sidecar FileLogWriter on config changes leaked flexi's
unstoppable flusher thread plus an fd each time; the writer is now flushed
and reset in place, matching what the service crate does.
get_clash_logs_by_service drops the CompactString conversion layer now that
service-ipc v2.6.7 returns plain Vec<String>, and AsyncLogger is renamed
LogRing to match.

* refactor(log): span-based observability and log noise cleanup

Instrument spans carry the structure flat lines never could: the core-start
spine (mode, readiness/owner generations, pid, config file), proxy apply and
clear routes with guard generations, service IPC sessions with refusal codes
and outcomes, profile-switch terminal outcomes, subscription fetch strategies,
core upgrades with per-proxy version probes, backup flows, timer tasks, config
generation uids, and the startup setup flow; running-mode changes emit one
guarded transition event each.
~90 hand-written noise lines are gone or demoted (entry+success pairs, polled
getter echoes, phase brackets, window sub-steps, platform install chatter);
errors keep their anyhow chain, operation name, and item id, and swallowed
retry results surface per attempt.
This commit is contained in:
Tunglies
2026-09-08 05:51:04 +08:00
committed by GitHub
parent f8b69b5d62
commit 2f370d6490
43 changed files with 807 additions and 797 deletions
+6 -6
View File
@@ -33,7 +33,7 @@ async fn delete_snapshot_logs(log_dir: &Path) -> Result<()> {
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) == Some("log") {
let _ = path.remove_if_exists().await;
logging!(info, Type::Setup, "delete snapshot log file: {}", path.display());
logging!(debug, Type::Setup, "delete snapshot log file: {}", path.display());
}
}
}
@@ -69,7 +69,7 @@ pub async fn delete_log() -> Result<()> {
_ => return Ok(()),
};
logging!(info, Type::Setup, "try to delete log files, day: {}", day);
logging!(debug, Type::Setup, "try to delete log files, day: {}", day);
let parse_time_str = |s: &str| {
let sa: Vec<&str> = s.split('-').collect();
@@ -102,7 +102,7 @@ pub async fn delete_log() -> Result<()> {
let duration = now.signed_duration_since(file_time);
if duration.num_days() > day {
let _ = file.path().remove_if_exists().await;
logging!(info, Type::Setup, "delete log file: {}", file_name);
logging!(debug, Type::Setup, "delete log file: {}", file_name);
}
}
Ok(())
@@ -284,7 +284,7 @@ async fn migrate_legacy_macos_logs() -> Result<()> {
if is_logs_dir_writable(&log_dir).await {
if let Err(e) = migrate_legacy_macos_service_logs(&log_dir).await {
logging!(warn, Type::Setup, "Failed to migrate legacy macOS service logs: {}", e);
logging!(warn, Type::Setup, "Failed to migrate legacy macOS service logs: {e:#}");
}
return Ok(());
}
@@ -489,9 +489,9 @@ pub async fn init_config() -> Result<()> {
AsyncHandler::spawn(|| async {
if let Err(e) = delete_log().await {
logging!(warn, Type::Setup, "Failed to clean old logs: {}", e);
logging!(warn, Type::Setup, "Failed to clean old logs: {e:#}");
}
logging!(info, Type::Setup, "后台日志清理任务完成");
logging!(debug, Type::Setup, "后台日志清理任务完成");
});
Ok(())