Skip to content

Commit

Permalink
feat(stackable-telemetry): Add a settings builder and implement it fo…
Browse files Browse the repository at this point in the history
…r console logging
  • Loading branch information
NickLarsenNZ committed Oct 24, 2024
1 parent 6fbe323 commit a2d2ee2
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ use opentelemetry_sdk::{
trace, Resource,
};
use opentelemetry_semantic_conventions::resource;
use settings::ConsoleLogSettings;
use snafu::{ResultExt as _, Snafu};
use tracing::{level_filters::LevelFilter, subscriber::SetGlobalDefaultError};
use tracing_subscriber::{filter::Directive, layer::SubscriberExt, EnvFilter, Layer, Registry};

pub mod settings;

type Result<T, E = Error> = std::result::Result<T, E>;

#[allow(missing_docs)]
#[derive(Debug, Snafu)]
pub enum Error {
#[snafu(display("unable to install opentelemetry trace exporter"))]
Expand Down Expand Up @@ -358,15 +362,14 @@ impl TracingBuilder<builder_state::Config> {
/// variable.
pub fn with_console_output(
self,
env_var: &'static str,
default_level_filter: LevelFilter,
settings: ConsoleLogSettings,
) -> TracingBuilder<builder_state::Config> {
TracingBuilder {
service_name: self.service_name,
console_log_config: SubscriberConfig {
enabled: true,
env_var,
default_level_filter,
enabled: settings.common_settings.enabled,
env_var: settings.common_settings.environment_variable,
default_level_filter: settings.common_settings.default_level,
},
otlp_log_config: self.otlp_log_config,
otlp_trace_config: self.otlp_trace_config,
Expand Down Expand Up @@ -447,6 +450,8 @@ fn env_filter_builder(env_var: &str, default_directive: impl Into<Directive>) ->

#[cfg(test)]
mod test {
use settings::{Build as _, Settings};

use super::*;

#[test]
Expand All @@ -460,8 +465,20 @@ mod test {
fn builder_with_console_output() {
let trace_guard = Tracing::builder()
.service_name("test")
.with_console_output("ABC_A", LevelFilter::TRACE)
.with_console_output("ABC_B", LevelFilter::DEBUG)
.with_console_output(
Settings::builder()
.env_var("ABC_A")
.default_level(LevelFilter::TRACE)
.enabled(true)
.build(),
)
.with_console_output(
Settings::builder()
.env_var("ABC_B")
.default_level(LevelFilter::DEBUG)
.enabled(true)
.build(),
)
.build();

assert_eq!(
Expand All @@ -480,7 +497,13 @@ mod test {
fn builder_with_all() {
let trace_guard = Tracing::builder()
.service_name("test")
.with_console_output("ABC_CONSOLE", LevelFilter::INFO)
.with_console_output(
Settings::builder()
.env_var("ABC_CONSOLE")
.default_level(LevelFilter::INFO)
.enabled(true)
.build(),
)
.with_otlp_log_exporter("ABC_OTLP_LOG", LevelFilter::DEBUG)
.with_otlp_trace_exporter("ABC_OTLP_TRACE", LevelFilter::TRACE)
.build();
Expand Down
32 changes: 32 additions & 0 deletions crates/stackable-telemetry/src/tracing/settings/console.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use super::{Format, Settings};

#[derive(Debug, Default, PartialEq)]
pub struct ConsoleLogSettings {
pub common_settings: Settings,
pub log_format: Format,
}

pub struct ConsoleLogSettingsBuilder {
pub(crate) common_settings: Settings,
pub(crate) log_format: Format,
}

impl ConsoleLogSettingsBuilder {
pub fn log_format(mut self, format: Format) -> Self {
self.log_format = format;
self
}

pub fn build(self) -> ConsoleLogSettings {
self.into()
}
}

impl From<ConsoleLogSettingsBuilder> for ConsoleLogSettings {
fn from(value: ConsoleLogSettingsBuilder) -> Self {
Self {
common_settings: value.common_settings,
log_format: value.log_format,
}
}
}
144 changes: 144 additions & 0 deletions crates/stackable-telemetry/src/tracing/settings/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use tracing::level_filters::LevelFilter;

pub mod console;
pub use console::*;

#[derive(Debug, PartialEq)]
pub struct Settings {
pub environment_variable: &'static str,

pub enabled: bool,

pub default_level: LevelFilter,
}

impl Settings {
pub fn builder() -> SettingsBuilder {
SettingsBuilder::default()
}
}

impl Default for Settings {
fn default() -> Self {
SettingsBuilder::default().into()
}
}

pub struct SettingsBuilder {
environment_variable: &'static str,
enabled: bool,
default_level: LevelFilter,
}

pub trait Build<T> {
fn build(self) -> T;
}

impl Build<Settings> for SettingsBuilder {
fn build(self) -> Settings {
self.into()
}
}

impl Build<ConsoleLogSettings> for SettingsBuilder {
fn build(self) -> ConsoleLogSettings {
ConsoleLogSettings {
common_settings: self.into(),
..Default::default()
}
}
}

impl SettingsBuilder {
pub fn env_var(mut self, name: &'static str) -> Self {
self.environment_variable = name;
self
}

pub fn enabled(mut self, enabled: bool) -> Self {
self.enabled = enabled;
self
}

pub fn default_level(mut self, level: impl Into<LevelFilter>) -> Self {
self.default_level = level.into();
self
}

// consider making generic build functions for each type of settings
// pub fn build(self) -> Settings {
// self.into()
// }

pub fn console_builder(self) -> ConsoleLogSettingsBuilder {
self.into()
}

// pub fn xxx_builder(self) -> XxxSettingsBuilder {
// self.into()
// }
}

impl Default for SettingsBuilder {
fn default() -> Self {
Self {
environment_variable: "RUST_LOG",
enabled: false,
default_level: LevelFilter::OFF,
}
}
}

impl From<SettingsBuilder> for Settings {
fn from(value: SettingsBuilder) -> Self {
Self {
environment_variable: value.environment_variable,
enabled: value.enabled,
default_level: value.default_level,
}
}
}

impl From<SettingsBuilder> for ConsoleLogSettingsBuilder {
fn from(value: SettingsBuilder) -> Self {
Self {
common_settings: value.into(),
log_format: Format::default(),
}
}
}

#[derive(Debug, Default, PartialEq)]
pub enum Format {
#[default]
Plain,
// Json { pretty: bool },
// LogFmt,
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn builds_console_settings() {
let expected = ConsoleLogSettings {
common_settings: Settings {
environment_variable: "hello",
enabled: true,
default_level: LevelFilter::DEBUG,
},
log_format: Format::Plain,
};
let result: ConsoleLogSettings = Settings::builder()
.enabled(true)
.env_var("hello")
.default_level(LevelFilter::DEBUG)
.console_builder()
.log_format(Format::Plain)
// color
.build();

assert_eq!(expected, result);
}
}

0 comments on commit a2d2ee2

Please sign in to comment.