Skip to content

Commit

Permalink
Add environment variable for logging to file
Browse files Browse the repository at this point in the history
Fixes #795
  • Loading branch information
nightkr committed Jun 20, 2024
1 parent d0ab773 commit 764af40
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
25 changes: 25 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 crates/stackable-operator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ tracing-opentelemetry.workspace = true
tracing-subscriber.workspace = true
tracing.workspace = true
url.workspace = true
tracing-appender = "0.2.3"

[dev-dependencies]
rstest.workspace = true
Expand Down
75 changes: 73 additions & 2 deletions crates/stackable-operator/src/logging/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
use std::{
io::{sink, Sink},
path::PathBuf,
};

use tracing;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry};
use tracing_appender::rolling::RollingFileAppender;
use tracing_subscriber::{
fmt::{
writer::{EitherWriter, MakeWriterExt as _},
MakeWriter,
},
layer::SubscriberExt,
util::SubscriberInitExt,
EnvFilter, Registry,
};

pub mod controller;
mod k8s_events;
Expand All @@ -22,14 +36,27 @@ impl Default for TracingTarget {
/// We force users to provide a variable name so it can be different per product.
/// We encourage it to be the product name plus `_LOG`, e.g. `FOOBAR_OPERATOR_LOG`.
/// If no environment variable is provided, the maximum log level is set to INFO.
///
/// Log output can be copied to a file by setting `{env}_DIRECTORY` (e.g. `FOOBAR_OPERATOR_DIRECTORY`)
/// to a directory path. This file will be rotated regularly.
pub fn initialize_logging(env: &str, app_name: &str, tracing_target: TracingTarget) {
let filter = match EnvFilter::try_from_env(env) {
Ok(env_filter) => env_filter,
_ => EnvFilter::try_new(tracing::Level::INFO.to_string())
.expect("Failed to initialize default tracing level to INFO"),
};

let fmt = tracing_subscriber::fmt::layer();
let file_appender_directory = std::env::var_os(format!("{env}_DIRECTORY")).map(PathBuf::from);
let file_appender =
OptionalMakeWriter::from(file_appender_directory.as_deref().map(|log_dir| {
RollingFileAppender::builder()
.filename_suffix(format!("{app_name}.log"))
.max_log_files(6)
.build(log_dir)
.expect("failed to initialize rolling file appender")
}));

let fmt = tracing_subscriber::fmt::layer().with_writer(std::io::stdout.and(file_appender));
let registry = Registry::default().with(filter).with(fmt);

match tracing_target {
Expand All @@ -45,6 +72,50 @@ pub fn initialize_logging(env: &str, app_name: &str, tracing_target: TracingTarg
registry.with(opentelemetry).init();
}
}

// need to delay logging until after tracing is initialized
match file_appender_directory {
Some(dir) => tracing::info!(log.file.directory = %dir.display(), "file logging enabled"),
None => tracing::debug!("file logging disabled, because no log directory set"),
}
}

/// Like [`EitherWriter`] but implements [`MakeWriter`] instead of [`std::io::Write`].
/// For selecting writers depending on dynamic configuration.
enum EitherMakeWriter<A, B> {
A(A),
B(B),
}
impl<'a, A, B> MakeWriter<'a> for EitherMakeWriter<A, B>
where
A: MakeWriter<'a>,
B: MakeWriter<'a>,
{
type Writer = EitherWriter<A::Writer, B::Writer>;

fn make_writer(&'a self) -> Self::Writer {
match self {
Self::A(a) => EitherWriter::A(a.make_writer()),
Self::B(b) => EitherWriter::B(b.make_writer()),
}
}

fn make_writer_for(&'a self, meta: &tracing::Metadata<'_>) -> Self::Writer {
match self {
Self::A(a) => EitherWriter::A(a.make_writer_for(meta)),
Self::B(b) => EitherWriter::B(b.make_writer_for(meta)),
}
}
}

type OptionalMakeWriter<T> = EitherMakeWriter<T, fn() -> Sink>;
impl<T> From<Option<T>> for OptionalMakeWriter<T> {
fn from(value: Option<T>) -> Self {
match value {
Some(t) => Self::A(t),
None => Self::B(sink),
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit 764af40

Please sign in to comment.