Print traces to files with ROC_LOGTO

This commit is contained in:
Ayaz Hafiz 2022-08-23 15:37:33 -05:00
parent b3f8ead89d
commit 963911814f
No known key found for this signature in database
GPG Key ID: 0E2A37416A25EF58
4 changed files with 63 additions and 14 deletions

12
Cargo.lock generated
View File

@ -4143,6 +4143,7 @@ name = "roc_tracing"
version = "0.0.1"
dependencies = [
"tracing",
"tracing-appender",
"tracing-subscriber",
]
@ -5080,6 +5081,17 @@ dependencies = [
"tracing-core",
]
[[package]]
name = "tracing-appender"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e"
dependencies = [
"crossbeam-channel",
"time 0.3.11",
"tracing-subscriber",
]
[[package]]
name = "tracing-attributes"
version = "0.1.22"

View File

@ -25,7 +25,7 @@ use std::ffi::{OsStr, OsString};
use roc_cli::build;
fn main() -> io::Result<()> {
roc_tracing::setup_tracing!();
let _tracing_guards = roc_tracing::setup_tracing!();
let matches = build_app().get_matches();

View File

@ -9,3 +9,4 @@ description = "Utilities for setting up tracing at various executable entry poin
[dependencies]
tracing = { version = "0.1.36", features = ["release_max_level_off"] }
tracing-subscriber = { version = "0.3.15", features = ["env-filter"] }
tracing-appender = "0.2.2"

View File

@ -1,6 +1,10 @@
//! Utilities for turning on tracing in user-facing or test executables of the Roc compiler.
//!
//! Tracing always writes to stderr, and is controlled with the ROC_LOG environment variable.
//! Tracing is controlled with the ROC_LOG environment variable.
//! If ROC_LOG is specified, logs are written to stderr. If ROC_LOGTO=<filepath> is also specified,
//! logs are instead written to <filepath>.
//!
//! See [directive-syntax] for the filtering directive syntax.
//!
//! Rather than using the Rust `tracing` crate (or any other tracing crate) directly,
//! you should use the exposed members of `roc_tracing` for your tracing needs.
@ -8,19 +12,21 @@
//!
//! Tracing is only turned on in debug builds. Use the provided [setup_tracing] macro to turn on
//! tracing at an executable's entry point.
//!
//! [directive-syntax]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
/// Sets up tracing of a Roc executable.
/// Sets up tracing of a Roc executable. The value of this macro must be bound to a variable that
/// is not dropped until tracing has completed.
///
/// This macro should only be invoked at an executable's entry point.
/// Tracing will only be enabled in debug builds.
/// Tracing is controlled with the `ROC_LOG` environment variable. See [directive-syntax] for the filtering directive syntax.
///
/// [directive-syntax]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
#[macro_export]
macro_rules! setup_tracing {
() => {
if cfg!(debug_assertions) {
$crate::setup_tracing();
$crate::setup_tracing()
} else {
$crate::TracingGuards::NONE
}
};
}
@ -29,14 +35,44 @@ pub use tracing::debug;
pub use tracing::info;
const ENV_FILTER: &str = "ROC_LOG";
const LOGTO_VAR: &str = "ROC_LOGTO";
use tracing_subscriber::{fmt, prelude::*, EnvFilter, Layer, Registry};
#[doc(hidden)]
pub fn setup_tracing() {
let stderr_layer = fmt::Layer::default()
.with_writer(std::io::stderr)
.with_filter(EnvFilter::from_env(ENV_FILTER));
Registry::default().with(stderr_layer).init();
/// Guards issued by the underlying library used for tracing.
/// Must not be dropped until all tracing is complete.
pub struct TracingGuards {
_file_appender_guard: Option<tracing_appender::non_blocking::WorkerGuard>,
}
impl TracingGuards {
pub const NONE: TracingGuards = TracingGuards {
_file_appender_guard: None,
};
}
#[must_use]
pub fn setup_tracing() -> TracingGuards {
if let Ok(file) = std::env::var(LOGTO_VAR) {
let file_appender = tracing_appender::rolling::never(".", file);
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
let file_layer = fmt::Layer::default()
.with_writer(non_blocking)
.with_ansi(false)
.with_filter(EnvFilter::from_env(ENV_FILTER));
Registry::default().with(file_layer).init();
TracingGuards {
_file_appender_guard: Some(guard),
}
} else {
let stderr_layer = fmt::Layer::default()
.with_writer(std::io::stderr)
.with_filter(EnvFilter::from_env(ENV_FILTER));
Registry::default().with(stderr_layer).init();
TracingGuards::NONE
}
}