Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add logging with tracing #1041

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 139 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ is-terminal = "0.4"
path-absolutize = "3.1.0"
human-sort = "0.2.2"
regex = "1.10"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde", "serde_json"] }
tracing-error = "0.2.0"
directories = "5.0.1"

[target.'cfg(windows)'.dependencies]
windows = { version = "0.58.0", features = ["Win32_Foundation", "Win32_UI_Shell", "Win32_Security", "Win32_System_JobObjects", "Win32_System_Console", "Win32_System_Threading", "Services_Store", "Foundation", "Foundation_Collections", "Web_Http", "Web_Http_Headers", "Storage_Streams", "Management_Deployment"] }
Expand Down
69 changes: 69 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,77 @@
use anyhow::{anyhow, bail, Context, Result};
use semver::{BuildMetadata, Version};
use std::path::PathBuf;
use tracing_error::ErrorLayer;
use tracing_subscriber::{
self, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt,
};
use url::Url;

/// Returns the project directories.
/// Uses the `ProjectDirs` struct from the `directories` crate to define a directory
/// structure for the project with "org" as the organization, "julialang" as the application,
/// and "install" as the qualifier. This is a standard approach for determining data storage paths.
fn project_dirs() -> Option<directories::ProjectDirs> {
directories::ProjectDirs::from("org", "julialang", "install")
}

/// Returns the default data directory for the application.
/// First, it checks the environment variable `JULIAUP_DATA_HOME`.
/// If the environment variable is not set, it falls back to the data directory
/// provided by `project_dirs`, which is typically platform-specific.
/// If both fail, it defaults to a `.data` directory in the current working directory.
pub fn default_data_dir() -> PathBuf {
std::env::var("JULIAUP_DATA_HOME")
.map(PathBuf::from)
.or_else(|_| {
project_dirs()
.map(|dirs| dirs.data_local_dir().to_path_buf())
.ok_or(())
})
.unwrap_or(PathBuf::from(".").join(".data"))
}

/// Initializes logging for the application.
/// Creates the default data directory if it doesn't already exist.
/// A log file named after the package is created in this directory.
/// The `tracing_subscriber` library is then used to configure logging to the file,
/// including file and line numbers in log entries, while disabling ANSI coloring.
/// The log level for specific libraries (`tokio_util`, `hyper`, `reqwest`) is turned off.
pub fn init_logging() -> Result<()> {
// Get the default data directory
let directory = default_data_dir();

// Create the directory (and any missing parent directories) if it doesn't exist
std::fs::create_dir_all(directory.clone())?;

// Create a log file named after the package
let log_file = format!("{}.log", env!("CARGO_PKG_NAME"));
let log_path = directory.join(log_file);
let log_file = std::fs::File::create(log_path)?;

// Set up a logging subscriber that writes to the log file, with specific configurations
let file_subscriber = tracing_subscriber::fmt::layer()
.with_file(true) // Include source file name in logs
.with_line_number(true) // Include line number in logs
.with_writer(log_file) // Log to the created file
.with_target(false) // Disable logging target (e.g., module paths)
.with_ansi(false); // Disable ANSI color codes

// Initialize the tracing subscriber with filters for specific libraries
tracing_subscriber::registry()
.with(file_subscriber)
.with(ErrorLayer::default()) // Add error handling layer
.with(
tracing_subscriber::filter::EnvFilter::from_default_env()
.add_directive("tokio_util=off".parse().unwrap()) // Disable logging for `tokio_util`
.add_directive("hyper=off".parse().unwrap()) // Disable logging for `hyper`
.add_directive("reqwest=off".parse().unwrap()), // Disable logging for `reqwest`
)
.init();

Ok(())
}

pub fn get_juliaserver_base_url() -> Result<Url> {
let base_url = if let Ok(val) = std::env::var("JULIAUP_SERVER") {
if val.ends_with('/') {
Expand Down