Mountain/Binary/Build/LoggingPlugin.rs
1//! # Logging Plugin Module
2//!
3//! Configures and creates the Tauri logging plugin with appropriate targets and
4//! filters.
5
6use log::LevelFilter;
7use tauri::plugin::TauriPlugin;
8use tauri_plugin_log::{RotationStrategy, Target, TargetKind, TimezoneStrategy};
9
10use crate::IPC::DevLog;
11
12/// Compress a Rust module target path to its final segment.
13///
14/// `D::Binary::Main::Entry` → `Entry`
15/// `D::Environment::StorageProvider` → `StorageProvider`
16fn CompressTarget(Target:&str) -> &str { Target.rsplit("::").next().unwrap_or(Target) }
17
18/// Creates and configures the logging plugin with multi-target output and level
19/// filtering.
20///
21/// # Arguments
22///
23/// * `LogLevel` - The desired log level (Trace, Debug, Info, Warn, Error)
24///
25/// # Returns
26///
27/// A configured `tauri_plugin_log::TauriPlugin` instance.
28///
29/// # Logging Strategy
30///
31/// - Release default: Info (low noise) unless RUST_LOG overrides
32/// - Debug default: Debug (high fidelity) unless RUST_LOG overrides
33/// - Very noisy dependencies are capped using level_for(...) and filter(...)
34///
35/// # Short Mode
36///
37/// When `LAND_DEV_LOG=short`:
38/// - Module targets compressed to last segment
39/// - Long app-data paths aliased to `$APP`
40/// - Storage key-by-key logs suppressed (batch count only)
41///
42/// # Targets
43///
44/// - Stdout: Console output for development/terminal viewing
45/// - LogDir: Persistent log file (Mountain.log) in the app's log directory
46/// - Webview: Logs sent to the webview console for frontend debugging
47///
48/// # Noise Filtering
49///
50/// The following noisy dependencies are capped at Info level regardless of
51/// RUST_LOG:
52/// - hyper: HTTP library verbose logs
53/// - mio: Async I/O polling logs
54/// - tao: Windowing system logs
55/// - tracing: Structured logging internal logs
56///
57/// Additionally, the following targets are filtered out entirely:
58/// - polling: File watcher events (very noisy)
59/// - tokio_reactor: Async reactor events
60/// - want: Connection readiness logs
61pub fn LoggingPlugin<R:tauri::Runtime>(LogLevel:LevelFilter) -> TauriPlugin<R> {
62 tauri_plugin_log::Builder::new()
63 // Configure output targets
64 .targets([
65 Target::new(TargetKind::Stdout),
66 Target::new(TargetKind::LogDir {
67 file_name: Some("Mountain.log".into()),
68 }),
69 Target::new(TargetKind::Webview),
70 ])
71 // Configure file rotation and timezone
72 .timezone_strategy(TimezoneStrategy::UseLocal)
73 .rotation_strategy(RotationStrategy::KeepAll)
74 // Set base log level
75 .level(LogLevel)
76 // Cap very noisy dependencies at Info level
77 .level_for("hyper", LevelFilter::Info)
78 .level_for("mio", LevelFilter::Info)
79 .level_for("tao", LevelFilter::Info)
80 .level_for("tracing", LevelFilter::Info)
81 // Filter out extremely noisy targets
82 .filter(|Metadata| {
83 !Metadata.target().starts_with("polling")
84 && !Metadata.target().starts_with("tokio_reactor")
85 && !Metadata.target().starts_with("want")
86 })
87 // Format logs with category-like structure: [LEVEL] [TARGET] message
88 .format(|out, message, record| {
89 if DevLog::IsShort() {
90 let ShortTarget = CompressTarget(record.target());
91 let RawMessage = format!("{}", message);
92 let Aliased = DevLog::AliasPath(&RawMessage);
93 out.finish(format_args!(
94 "[{:<5}] [{}] {}",
95 record.level(),
96 ShortTarget,
97 Aliased
98 ))
99 } else {
100 out.finish(format_args!(
101 "[{:<5}] [{}] {}",
102 record.level(),
103 record.target(),
104 message
105 ))
106 }
107 })
108 .build()
109}