Skip to main content

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}