Logging Infrastructure and Log Rotation in Universal Android Debloater NG
The Universal Android Debloater NG uses the fern crate combined with log and chrono to write timestamped logs to both the console and a persistent file at CACHE_DIR/uadng.log, but does not implement any automatic log rotation or size-based truncation, requiring manual file management.
The Universal Android Debloater Next Generation (UAD-ng) implements its logging infrastructure through the fern crate to capture diagnostic information from the GUI application. Understanding this logging infrastructure is essential for developers debugging GUI issues and users managing disk space, particularly because the application handles log rotation manually rather than through automated mechanisms.
Logging Backend and Dependencies
The logging infrastructure relies on three primary crates from the Rust ecosystem:
- fern: Provides the dispatch-based logging backend
- log: Supplies the standard logging facade and macros
- chrono: Handles timestamp formatting for log entries
These dependencies are declared in the workspace Cargo.toml, with fern configured to use the colored feature for terminal output.
Log Output Configuration
The setup_logger() function in crates/uad-gui/src/main.rs constructs two independent fern::Dispatch objects that process log records simultaneously.
Console Output (Stdout)
The stdout dispatcher handles colored terminal output for debugging purposes:
- Default level:
Warn - Module-specific level:
Debugfor theuad_guimodule - Formatting: Colored level indicators using
ColoredLevelConfig
File Persistence
The file dispatcher writes plain-text logs to the user's cache directory:
- Location:
CACHE_DIR.join("uadng.log")(e.g.,~/.cache/universal-android-debloater-ng/uadng.logon Linux) - Mode: Opened with
create(true),append(true), andtruncate(false) - Default level:
Warn - Module-specific level:
Debugfor theuad_guimodule
Each log entry follows the format: TIMESTAMP LEVEL [file.rs:line] message.
Log Rotation Behavior
No automatic log rotation is implemented. The logging infrastructure opens the file in append mode and writes indefinitely without size checks or file archiving. The log file continues to grow across application sessions until manually deleted or until the cache directory is cleared during reinstallation.
The codebase does not integrate third-party rotation crates such as log4rs or flexi_logger, nor does it contain logic to rotate, compress, or archive old log files based on age or size thresholds.
Implementation Examples
Setting Up the Logger
The setup_logger() function in crates/uad-gui/src/main.rs configures the dual-output pipeline:
fn setup_logger() -> Result<(), fern::InitError> {
#[cfg(target_os = "windows")] { attach_windows_console(); }
let colors = ColoredLevelConfig::new().info(Color::Green);
// Formatter used for both stdout and file output
let make_formatter = |use_colors: bool| {
move |out: FormatCallback, message: &Arguments, record: &Record| {
out.finish(format_args!(
"{} {} [{}:{}] {}",
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
if use_colors {
format!("{:5}", colors.color(record.level()))
} else {
format!("{:5}", record.level())
},
record.file().unwrap_or("?"),
record.line().map(|l| l.to_string()).unwrap_or_default(),
message
));
}
};
let default_log_level = log::LevelFilter::Warn;
let log_file = OpenOptions::new()
.create(true)
.append(true)
.truncate(false)
.open(CACHE_DIR.join("uadng.log"))?;
// File dispatcher (plain text, no colors)
let file_dispatcher = fern::Dispatch::new()
.format(make_formatter(false))
.level(default_log_level)
.level_for("uad_gui", log::LevelFilter::Debug)
.chain(log_file);
// Stdout dispatcher (colored)
let stdout_dispatcher = fern::Dispatch::new()
.format(make_formatter(true))
.level(default_log_level)
.level_for("uad_gui", log::LevelFilter::Warn)
.chain(std::io::stdout());
// Combine both dispatchers
fern::Dispatch::new()
.chain(stdout_dispatcher)
.chain(file_dispatcher)
.apply()?;
Ok(())
}
Emitting Log Entries
Any module can use standard log macros to write to the configured dispatchers:
use log::{debug, info, warn};
fn some_function() {
info!("Starting operation");
debug!("Detailed debug data: {:?}", some_data);
warn!("Potential issue detected");
}
Locating the Log File at Runtime
The log file path resolves to the OS-specific cache directory:
let log_path = CACHE_DIR.join("uadng.log");
println!("Log file is stored at: {}", log_path.display());
CACHE_DIR is defined as a LazyLock<PathBuf> that resolves to platform-specific locations such as $XDG_CACHE_HOME/universal-android-debloater-ng on Linux or %LOCALAPPDATA%\universal-android-debloater-ng on Windows.
Summary
- fern provides the underlying logging infrastructure for UAD-ng, dispatching records to multiple outputs simultaneously.
- Logs write to both colored stdout (for debugging) and a plain-text file at
CACHE_DIR/uadng.log(for persistence). - The file appender uses
create(true)andappend(true)withtruncate(false)to preserve historical entries across sessions. - No automatic log rotation exists; the file grows indefinitely until manually deleted or the cache is cleared.
- Users must manually manage the
uadng.logfile to prevent unbounded disk usage.
Frequently Asked Questions
Does Universal Android Debloater NG rotate logs automatically?
No. The application does not implement automatic log rotation, size-based truncation, or log archiving. The uadng.log file opens in append mode and accumulates entries indefinitely until manually removed.
Where are UAD-ng log files stored on different operating systems?
The log file location depends on the operating system's cache directory conventions. On Linux, it typically resides at ~/.cache/universal-android-debloater-ng/uadng.log. On Windows, it uses %LOCALAPPDATA%\universal-android-debloater-ng\uadng.log, and on macOS, it uses ~/Library/Caches/universal-android-debloater-ng/uadng.log. The CACHE_DIR variable in crates/uad-gui/src/main.rs resolves these paths at runtime.
What Rust crates handle the logging infrastructure?
The logging infrastructure uses the fern crate for the dispatch backend, the log crate for the standard logging facade and macros, and chrono for timestamp formatting. These are configured in the workspace Cargo.toml with fern's colored feature enabled for terminal output.
How can I manually clear or truncate the log file?
You can safely delete the uadng.log file while the application is not running, or truncate it using system commands like > ~/.cache/universal-android-debloater-ng/uadng.log on Linux. Since the application uses append mode with create(true), it will recreate the file on the next launch if deleted.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →