人人都会AI编程

前端日志与 Rust 日志统一收集

更新时间:2026-07-11

在桌面应用开发中,日志是排查问题、监控状态最重要的工具。但 Tauri 应用天然存在两个运行环境:前端(WebView 中的 JavaScript)和后端(Rust 原生代码)。如果两边的日志各自为战——前端用 console.log 输出只能在 DevTools 里看到,Rust 用 println!log 库输出在终端——那么在真实用户环境中很难统一追踪一个请求从 UI 到系统调用的完整链路。

为此,统一收集前端和 Rust 的日志,将它们汇聚到一个地方(文件、控制台或远程服务),对生产环境排错至关重要。Tauri 的插件体系和 Rust 的 log 生态让这件事实现起来非常简单。


1. 总体思路

  • 前端通过 Tauri 提供的 IPC 通道,将日志消息发送给 Rust 后端;
  • Rust 后端同时接收来自自身的日志(通过 logtracing 宏)和前端提交的日志,统一格式化后写入文件或输出到 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. 注意事项

  • 生产环境务必控制日志级别:避免 tracedebug 级别的消息过多影响性能。可通过环境变量 RUST_LOG 动态调整。
  • 敏感数据脱敏:前端调用日志 API 时,注意不要直接打印明文密码或个人信息。
  • 日志文件轮转:长期运行的应用建议搭配 logrotate 或使用 file-rotator 等库,防止单个日志文件过大。

通过这套“前端插件 + Rust 日志门面”的模式,Tauri 应用可以非常自然地实现前后端日志统一收集,既保留了开发时的便利,也满足了生产环境的诊断需求。