在桌面应用开发中,日志是排查问题、监控状态最重要的工具。但 Tauri 应用天然存在两个运行环境:前端(WebView 中的 JavaScript)和后端(Rust 原生代码)。如果两边的日志各自为战——前端用 console.log 输出只能在 DevTools 里看到,Rust 用 println! 或 log 库输出在终端——那么在真实用户环境中很难统一追踪一个请求从 UI 到系统调用的完整链路。
为此,统一收集前端和 Rust 的日志,将它们汇聚到一个地方(文件、控制台或远程服务),对生产环境排错至关重要。Tauri 的插件体系和 Rust 的 log 生态让这件事实现起来非常简单。
1. 总体思路
- 前端通过 Tauri 提供的 IPC 通道,将日志消息发送给 Rust 后端;
- Rust 后端同时接收来自自身的日志(通过
log或tracing宏)和前端提交的日志,统一格式化后写入文件或输出到 stdout; - 可以通过 Cargo features 和配置文件灵活控制日志级别、输出目标。
2. 实现步骤
2.1 添加依赖
在 src-tauri/Cargo.toml 中加入:
[dependencies]
log = "0.4"
env_logger = "0.10" # 用于控制台输出
tauri-plugin-log = "2" # Tauri 日志插件
若需要同时将日志写入文件,可增加 simplelog 或其他日志库,这里以 env_logger 为例。
2.2 在 Rust 侧初始化日志系统
在 src-tauri/src/main.rs 中设置统一的日志订阅者,并注册 Tauri 的日志插件:
use tauri::Manager;
fn main() {
// 初始化 env_logger,使所有 log 级别的消息都打印到 stdout
env_logger::builder()
.filter_level(log::LevelFilter::Info) // 根据需求调整
.init();
tauri::Builder::default()
.plugin(tauri_plugin_log::Builder::new().build()) // 启用前端日志收集
.setup(|app| {
// 可以在 setup 中记录一条 Rust 日志测试
log::info!("Application started");
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
tauri-plugin-log 插件内部做的就是:监听前端通过 @tauri-apps/plugin-log 发送的日志请求,然后使用 Rust 的 log crate 记录它们,从而与 Rust 自身的日志共享同一个输出目标。
2.3 前端发送日志
在前端项目中安装对应的 JavaScript 插件:
npm install @tauri-apps/plugin-log
在需要记录日志的地方调用:
import { trace, info, warn, error } from '@tauri-apps/plugin-log';
// 用法和 console 类似
info('User clicked save button');
warn('API response is slow');
error('File write failed', { path: '/tmp/data.txt' });
这些函数调用会自动通过 IPC 把日志级别和消息发送给 Rust 后端,然后由 Rust 的统一日志系统处理(例如输出到终端、写入文件等)。
3. 进阶:日志写入文件
如果想在生产环境中持久化日志,可改用 simplelog 库,将日志同时输出到文件和终端:
use simplelog::{CombinedLogger, WriteLogger, Config, LevelFilter};
use std::fs::File;
fn main() {
let log_file = File::create("app.log").unwrap();
CombinedLogger::init(
vec![
WriteLogger::new(LevelFilter::Info, Config::default(), log_file),
// 也可以加上 TermLogger 输出到控制台
]
).unwrap();
// ... 其余 Tauri 初始化代码相同
}
前端通过 info! / error! 发送的消息,与 log::info! / log::error! 一样,都会进入同一个 CombinedLogger,最终整齐地出现在 app.log 文件中。
4. 实际效果
在一个真实的 Tauri 应用中,日志文件可能如下所示:
[2025-03-17T10:23:01 INFO app] Application started
[2025-03-17T10:23:02 INFO app] [frontend] User clicked save button
[2025-03-17T10:23:02 INFO app] Saving document to disk...
[2025-03-17T10:23:02 WARN app] [frontend] API response took 2.1s
所有消息按时间顺序排列,前端日志统一用 [frontend] 标记(由插件自动添加),方便过滤。这样,无论问题发生在 UI 交互还是 Rust 处理逻辑中,都能从同一个日志流中快速定位。
5. 注意事项
- 生产环境务必控制日志级别:避免
trace或debug级别的消息过多影响性能。可通过环境变量RUST_LOG动态调整。 - 敏感数据脱敏:前端调用日志 API 时,注意不要直接打印明文密码或个人信息。
- 日志文件轮转:长期运行的应用建议搭配
logrotate或使用file-rotator等库,防止单个日志文件过大。
通过这套“前端插件 + Rust 日志门面”的模式,Tauri 应用可以非常自然地实现前后端日志统一收集,既保留了开发时的便利,也满足了生产环境的诊断需求。