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

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
}
}