From df75d3a135cbfb8645a6cbd88969faedd3f229ce Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Thu, 18 Jun 2026 21:56:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(client):=20=E6=A1=8C=E9=9D=A2=E7=AB=AF?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=8A=A0=E6=9C=AC=E5=9C=B0=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=88=B3=E5=89=8D=E7=BC=80=20[HH:MM:SS.mmm]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 log_time.dart(共享 logTime() helper),DesktopKernel / DesktopVpnBridge 所有日志行首打 [时:分:秒.毫秒],便于排查连接时序。 Co-Authored-By: Claude Opus 4.8 --- client/lib/bridge/desktop_vpn_bridge.dart | 23 ++++++++++++----------- client/lib/bridge/kernel_process.dart | 3 ++- client/lib/bridge/log_time.dart | 8 ++++++++ 3 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 client/lib/bridge/log_time.dart diff --git a/client/lib/bridge/desktop_vpn_bridge.dart b/client/lib/bridge/desktop_vpn_bridge.dart index 356b9ad..cf17ac8 100644 --- a/client/lib/bridge/desktop_vpn_bridge.dart +++ b/client/lib/bridge/desktop_vpn_bridge.dart @@ -25,6 +25,7 @@ import 'dart:convert'; import 'dart:io'; import 'kernel_process.dart'; +import 'log_time.dart'; import 'vpn_bridge.dart'; /// 桌面端 VPN 桥接实现(macOS / Linux / Windows PoC)。 @@ -100,9 +101,9 @@ class DesktopVpnBridge implements VpnBridge { // 3. 写 config 到应用支持目录(0600 权限) final configPath = await writeConfig(enrichedJson); - print('[DesktopVpnBridge] config written: $configPath'); - print('[DesktopVpnBridge] clash_api port=$port secret_len=${secret.length}'); - print('[DesktopVpnBridge] killSwitch=$_killSwitchEnabled'); + print('${logTime()}[DesktopVpnBridge] config written: $configPath'); + print('${logTime()}[DesktopVpnBridge] clash_api port=$port secret_len=${secret.length}'); + print('${logTime()}[DesktopVpnBridge] killSwitch=$_killSwitchEnabled'); // 4. 启动内核子进程(blocking until Clash API ready or error) await _kernel.spawn(configPath); @@ -141,7 +142,7 @@ class DesktopVpnBridge implements VpnBridge { try { await _kernel.clashApiClient.selectProxy('proxy', tag); } catch (e) { - print('[DesktopVpnBridge] selectOutbound(tag=$tag) error: $e'); + print('${logTime()}[DesktopVpnBridge] selectOutbound(tag=$tag) error: $e'); rethrow; } } @@ -177,11 +178,11 @@ class DesktopVpnBridge implements VpnBridge { Future setKillSwitch({required bool on}) async { if (_killSwitchEnabled == on) return; _killSwitchEnabled = on; - print('[DesktopVpnBridge] setKillSwitch=$on'); + print('${logTime()}[DesktopVpnBridge] setKillSwitch=$on'); // 若内核正在运行,用新设置重载(会有约 1~2s 重连) if (_kernel.isRunning && _lastUserConfigJson != null) { - print('[DesktopVpnBridge] reloading kernel for killSwitch change'); + print('${logTime()}[DesktopVpnBridge] reloading kernel for killSwitch change'); // 暂停自动重连,避免 kill 触发重连定时器 final wasAutoReconnect = _shouldAutoReconnect; _shouldAutoReconnect = false; @@ -230,17 +231,17 @@ class DesktopVpnBridge implements VpnBridge { _reconnectAttempt++; print( - '[DesktopVpnBridge] auto-reconnect in ${delaySec}s (attempt $_reconnectAttempt)'); + '${logTime()}[DesktopVpnBridge] auto-reconnect in ${delaySec}s (attempt $_reconnectAttempt)'); _reconnectTimer = Timer(Duration(seconds: delaySec), () async { if (!_shouldAutoReconnect || _lastUserConfigJson == null) return; try { - print('[DesktopVpnBridge] auto-reconnect: attempting start...'); + print('${logTime()}[DesktopVpnBridge] auto-reconnect: attempting start...'); await start(_lastUserConfigJson!); _reconnectAttempt = 0; // 成功后重置退避计数 - print('[DesktopVpnBridge] auto-reconnect: success'); + print('${logTime()}[DesktopVpnBridge] auto-reconnect: success'); } catch (e) { - print('[DesktopVpnBridge] auto-reconnect: start failed: $e'); + print('${logTime()}[DesktopVpnBridge] auto-reconnect: start failed: $e'); // start() 失败(内核未能启动)→ 手动调度下一次重试 if (_shouldAutoReconnect) _scheduleReconnect(); } @@ -341,7 +342,7 @@ class DesktopVpnBridge implements VpnBridge { try { await Process.run('chmod', ['600', file.path]); } catch (_) { - print('[DesktopVpnBridge] warning: chmod 600 failed for ${file.path}'); + print('${logTime()}[DesktopVpnBridge] warning: chmod 600 failed for ${file.path}'); } } return file.path; diff --git a/client/lib/bridge/kernel_process.dart b/client/lib/bridge/kernel_process.dart index 5fe8c4c..85b1203 100644 --- a/client/lib/bridge/kernel_process.dart +++ b/client/lib/bridge/kernel_process.dart @@ -30,6 +30,7 @@ import 'dart:math' as math; import 'package:http/http.dart' as http; +import 'log_time.dart'; import 'vpn_bridge.dart'; // ══════════════════════════════════════════════════════════════════ @@ -481,7 +482,7 @@ class DesktopKernelProcess implements KernelProcess { } void _log(String msg) { - print('[DesktopKernel] $msg'); + print('${logTime()}[DesktopKernel] $msg'); if (!_logCtrl.isClosed) _logCtrl.add(msg); } diff --git a/client/lib/bridge/log_time.dart b/client/lib/bridge/log_time.dart new file mode 100644 index 0000000..867d0f1 --- /dev/null +++ b/client/lib/bridge/log_time.dart @@ -0,0 +1,8 @@ +// log_time.dart — 桌面端日志统一时间戳前缀。 +// 返回本地时间 "[HH:MM:SS.mmm] ",拼在日志行首便于排查时序。 + +String logTime() { + final n = DateTime.now(); + String p(int v, [int w = 2]) => v.toString().padLeft(w, '0'); + return '[${p(n.hour)}:${p(n.minute)}:${p(n.second)}.${p(n.millisecond, 3)}] '; +}