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

add tracing-appender for log to files and rolling logs #1578

Merged
merged 2 commits into from
Jul 3, 2023
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- Added `NAMADA_LOG_DIR` env var for logging to file(s) and `NAMADA_LOG_ROLLING`
for setting rolling logs frequency. The rolling frequency can be set to
never, minutely, hourly or daily. If not set, the default is never.
([\#1578](https://github.com/anoma/namada/pull/1578))
13 changes: 13 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ tower = "0.4"
# Also, using the same version of tendermint-rs as we do here.
tower-abci = {git = "https://github.com/heliaxdev/tower-abci.git", rev = "367d8d958b83c501ed2c09e9c4595f8bf75a0b01"}
tracing = "0.1.30"
tracing-appender = "0.2.2"
tracing-log = "0.1.2"
tracing-subscriber = {version = "0.3.7", default-features = false, features = ["env-filter", "fmt"]}
wasmparser = "0.83.0"
Expand Down
1 change: 1 addition & 0 deletions apps/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ toml.workspace = true
tonic.workspace = true
tower-abci.workspace = true
tower.workspace = true
tracing-appender.workspace = true
tracing-log.workspace = true
tracing-subscriber = { workspace = true, features = ["std", "json", "ansi", "tracing-log"]}
tracing.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion apps/src/bin/namada-client/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ async fn main() -> Result<()> {
color_eyre::install()?;

// init logging
logging::init_from_env_or(LevelFilter::INFO)?;
let _log_guard = logging::init_from_env_or(LevelFilter::INFO)?;

// run the CLI
cli::main().await
Expand Down
2 changes: 1 addition & 1 deletion apps/src/bin/namada-node/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn main() -> Result<()> {
color_eyre::install()?;

// init logging
logging::init_from_env_or(LevelFilter::INFO)?;
let _log_guard = logging::init_from_env_or(LevelFilter::INFO)?;

// run the CLI
cli::main()
Expand Down
2 changes: 1 addition & 1 deletion apps/src/bin/namada/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fn main() -> Result<()> {
color_eyre::install()?;

// init logging
logging::init_from_env_or(LevelFilter::INFO)?;
let _log_guard = logging::init_from_env_or(LevelFilter::INFO)?;

// run the CLI
cli::main()
Expand Down
110 changes: 90 additions & 20 deletions apps/src/lib/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::env;

use color_eyre::eyre::Result;
use eyre::WrapErr;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_log::LogTracer;
use tracing_subscriber::filter::{Directive, EnvFilter};
use tracing_subscriber::fmt::Subscriber;
Expand All @@ -13,6 +14,12 @@ pub const ENV_KEY: &str = "NAMADA_LOG";
const COLOR_ENV_KEY: &str = "NAMADA_LOG_COLOR";
// Env var to log formatting (one of "full" (default), "json", "pretty")
const FMT_ENV_KEY: &str = "NAMADA_LOG_FMT";
// Env var to append logs to file(s) in the given dir
const DIR_ENV_KEY: &str = "NAMADA_LOG_DIR";
// Env var to set rolling log frequency
const ROLLING_ENV_KEY: &str = "NAMADA_LOG_ROLLING";

const LOG_FILE_NAME_PREFIX: &str = "namada.log";

#[derive(Clone, Debug)]
enum Fmt {
Expand All @@ -27,10 +34,18 @@ impl Default for Fmt {
}
}

pub fn init_from_env_or(default: impl Into<Directive>) -> Result<()> {
/// When logging to a file is enabled, returns a guard that handles flushing of
/// remaining logs on termination.
///
/// Important: The returned guard, if any, must be assigned to a binding that is
/// not _, as _ will result in the WorkerGuard being dropped immediately.
pub fn init_from_env_or(
default: impl Into<Directive>,
) -> Result<Option<WorkerGuard>> {
let filter = filter_from_env_or(default);
set_subscriber(filter)?;
init_log_tracer()
let guard = set_subscriber(filter)?;
init_log_tracer()?;
Ok(guard)
}

pub fn filter_from_env_or(default: impl Into<Directive>) -> EnvFilter {
Expand All @@ -39,7 +54,11 @@ pub fn filter_from_env_or(default: impl Into<Directive>) -> EnvFilter {
.unwrap_or_else(|_| EnvFilter::default().add_directive(default.into()))
}

pub fn set_subscriber(filter: EnvFilter) -> Result<()> {
pub fn init_log_tracer() -> Result<()> {
LogTracer::init().wrap_err("Failed to initialize log adapter")
}

pub fn set_subscriber(filter: EnvFilter) -> Result<Option<WorkerGuard>> {
let with_color = if let Ok(val) = env::var(COLOR_ENV_KEY) {
val.to_ascii_lowercase() != "false"
} else {
Expand All @@ -54,28 +73,79 @@ pub fn set_subscriber(filter: EnvFilter) -> Result<()> {
_ => None,
})
.unwrap_or_default();
let log_dir = env::var(DIR_ENV_KEY).ok();

let builder = Subscriber::builder()
.with_ansi(with_color)
.with_env_filter(filter);
match format {
Fmt::Full => {
let my_collector = builder.with_ansi(with_color).finish();
tracing::subscriber::set_global_default(my_collector)
.wrap_err("Failed to set log subscriber")
}
Fmt::Json => {
let my_collector = builder.json().finish();
tracing::subscriber::set_global_default(my_collector)
.wrap_err("Failed to set log subscriber")

// We're using macros here to help as the `format` match arms and `log_dir`
// if/else branches have incompatible types.
macro_rules! finish {
($($builder:tt)*) => {
{
let my_collector = $($builder)*.finish();
tracing::subscriber::set_global_default(my_collector)
.wrap_err("Failed to set log subscriber")
}
}
Fmt::Pretty => {
let my_collector = builder.pretty().finish();
tracing::subscriber::set_global_default(my_collector)
.wrap_err("Failed to set log subscriber")
}
macro_rules! select_format {
($($builder:tt)*) => {
{
match format {
Fmt::Full => finish!($($builder)*),
Fmt::Json => finish!($($builder)*.json()),
Fmt::Pretty => finish!($($builder)*.pretty()),
}
}
}
}

if let Some(dir) = log_dir {
use tracing_appender::rolling::{self, RollingFileAppender};

let rolling_fn: fn(_, _) -> RollingFileAppender = match rolling_freq() {
RollingFreq::Never => rolling::never,
RollingFreq::Minutely => rolling::minutely,
RollingFreq::Hourly => rolling::hourly,
RollingFreq::Daily => rolling::daily,
};
let file_appender = rolling_fn(dir, LOG_FILE_NAME_PREFIX);
let (non_blocking, guard) =
tracing_appender::non_blocking(file_appender);
let builder = builder.with_writer(non_blocking);
select_format!(builder)?;
Ok(Some(guard))
} else {
select_format!(builder)?;
Ok(None)
}
}

pub fn init_log_tracer() -> Result<()> {
LogTracer::init().wrap_err("Failed to initialize log adapter")
enum RollingFreq {
Never,
Minutely,
Hourly,
Daily,
}

/// Get the rolling frequency from env var or default to `Never`.
fn rolling_freq() -> RollingFreq {
if let Ok(freq) = env::var(ROLLING_ENV_KEY) {
match freq.to_ascii_lowercase().as_str() {
"never" => RollingFreq::Never,
"minutely" => RollingFreq::Minutely,
"hourly" => RollingFreq::Hourly,
"daily" => RollingFreq::Daily,
_ => {
panic!(
"Unrecognized option set for {ROLLING_ENV_KEY}. Expecing \
one of: never, minutely, hourly, daily. Default is never."
);
}
}
} else {
RollingFreq::Never
}
}