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)}] '; +}