Skip to content

Commit

Permalink
refactor: layouts and encoders should be nested to appenders (#64)
Browse files Browse the repository at this point in the history
Signed-off-by: tison <[email protected]>
  • Loading branch information
tisonkun authored Oct 17, 2024
1 parent a4c1ae5 commit f8cfddd
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 198 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ fn main() {
Logger::new().dispatch(
Dispatch::new()
.filter(LevelFilter::Trace)
.layout(TextLayout::default())
.append(append::Stdout),
.append(append::Stdout::default()),
)
.apply()
.unwrap();
Expand Down
4 changes: 1 addition & 3 deletions examples/env_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

use logforth::append;
use logforth::filter::EnvFilter;
use logforth::layout::TextLayout;
use logforth::Dispatch;
use logforth::Logger;

Expand All @@ -23,8 +22,7 @@ fn main() {
.dispatch(
Dispatch::new()
.filter(EnvFilter::from_default_env())
.layout(TextLayout::default())
.append(append::Stdout),
.append(append::Stdout::default()),
)
.apply()
.unwrap();
Expand Down
9 changes: 5 additions & 4 deletions examples/fn_layout_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ fn main() {
FilterResult::Reject
}
}))
.layout(CustomLayout::new(|record, f| {
f(format_args!("[system alert] {}", record.args()))
}))
.append(append::Stdout),
.append(
append::Stdout::default().with_layout(CustomLayout::new(|record| {
Ok(format!("[system alert] {}", record.args()).into_bytes())
})),
),
)
.apply()
.unwrap();
Expand Down
3 changes: 1 addition & 2 deletions examples/json_stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ fn main() {
.dispatch(
Dispatch::new()
.filter(LevelFilter::Trace)
.layout(JsonLayout::default())
.append(append::Stdout),
.append(append::Stdout::default().with_layout(JsonLayout::default())),
)
.apply()
.unwrap();
Expand Down
6 changes: 2 additions & 4 deletions examples/rolling_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use logforth::append::rolling_file::RollingFileWriter;
use logforth::append::rolling_file::Rotation;
use logforth::append::Stdout;
use logforth::layout::JsonLayout;
use logforth::layout::TextLayout;
use logforth::Dispatch;
use logforth::Logger;

Expand All @@ -38,10 +37,9 @@ fn main() {
.dispatch(
Dispatch::new()
.filter(LevelFilter::Trace)
.layout(JsonLayout::default())
.append(RollingFile::new(writer)),
.append(RollingFile::new(writer).with_layout(JsonLayout::default()))
.append(Stdout::default()),
)
.dispatch(Dispatch::new().layout(TextLayout::default()).append(Stdout))
.apply()
.unwrap();

Expand Down
11 changes: 2 additions & 9 deletions examples/simple_stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

use log::LevelFilter;
use logforth::append;
use logforth::layout::TextLayout;
use logforth::Dispatch;
use logforth::Logger;

Expand All @@ -23,14 +22,8 @@ fn main() {
.dispatch(
Dispatch::new()
.filter(LevelFilter::Trace)
.layout(TextLayout::default())
.append(append::Stdout),
)
.dispatch(
Dispatch::new()
.filter(LevelFilter::Trace)
.layout(TextLayout::default().no_color())
.append(append::Stderr),
.append(append::Stdout::default())
.append(append::Stderr::default()),
)
.apply()
.unwrap();
Expand Down
4 changes: 3 additions & 1 deletion src/append/fastrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ use crate::layout::collect_kvs;

/// An appender that adds log records to fastrace as an event associated to the current span.
#[derive(Default, Debug, Clone)]
pub struct FastraceEvent;
pub struct FastraceEvent {
_private: (), // suppress structure literal syntax
}

impl Append for FastraceEvent {
fn append(&self, record: &Record) -> anyhow::Result<()> {
Expand Down
8 changes: 0 additions & 8 deletions src/append/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ pub use self::opentelemetry::OpentelemetryLog;
pub use self::rolling_file::RollingFile;
pub use self::stdio::Stderr;
pub use self::stdio::Stdout;
use crate::layout::IdenticalLayout;
use crate::layout::Layout;

#[cfg(feature = "fastrace")]
mod fastrace;
Expand All @@ -41,10 +39,4 @@ pub trait Append: fmt::Debug + Send + Sync + 'static {

/// Flushes any buffered records.
fn flush(&self) {}

/// Default layout to use when [`Dispatch`][crate::logger::Dispatch] does not configure a
/// preferred layout.
fn default_layout(&self) -> Layout {
Layout::Identical(IdenticalLayout)
}
}
49 changes: 32 additions & 17 deletions src/append/opentelemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use opentelemetry_sdk::logs::LogRecord;
use opentelemetry_sdk::logs::LoggerProvider;

use crate::append::Append;
use crate::Layout;

/// The communication protocol to opentelemetry that used when exporting data.
///
Expand All @@ -52,6 +53,7 @@ pub struct OpentelemetryLogBuilder {
endpoint: String,
protocol: Protocol,
labels: Vec<(Cow<'static, str>, Cow<'static, str>)>,
layout: Option<Layout>,
}

impl OpentelemetryLogBuilder {
Expand All @@ -62,6 +64,7 @@ impl OpentelemetryLogBuilder {
endpoint: otlp_endpoint.into(),
protocol: Protocol::Grpc,
labels: vec![],
layout: None,
}
}

Expand Down Expand Up @@ -100,13 +103,20 @@ impl OpentelemetryLogBuilder {
self
}

/// Set the layout to use when formatting log records.
pub fn layout(mut self, layout: impl Into<Layout>) -> Self {
self.layout = Some(layout.into());
self
}

/// Build the [`OpentelemetryLog`] appender.
pub fn build(self) -> Result<OpentelemetryLog, opentelemetry::logs::LogError> {
let OpentelemetryLogBuilder {
name,
endpoint,
protocol,
labels,
layout,
} = self;

let collector_timeout =
Expand Down Expand Up @@ -140,6 +150,7 @@ impl OpentelemetryLogBuilder {

Ok(OpentelemetryLog {
name,
layout,
library,
provider,
})
Expand All @@ -150,30 +161,34 @@ impl OpentelemetryLogBuilder {
#[derive(Debug)]
pub struct OpentelemetryLog {
name: String,
layout: Option<Layout>,
library: Arc<InstrumentationLibrary>,
provider: LoggerProvider,
}

impl Append for OpentelemetryLog {
fn append(&self, log_record: &Record) -> anyhow::Result<()> {
fn append(&self, record: &Record) -> anyhow::Result<()> {
let provider = self.provider.clone();
let logger = provider.library_logger(self.library.clone());

let mut record = LogRecord::default();
record.observed_timestamp = Some(SystemTime::now());
record.severity_number = Some(log_level_to_otel_severity(log_record.level()));
record.severity_text = Some(log_record.level().as_str());
record.target = Some(log_record.target().to_string().into());
record.body = Some(AnyValue::from(log_record.args().to_string()));

if let Some(module_path) = log_record.module_path() {
record.add_attribute("module_path", module_path.to_string());
let mut log_record_ = LogRecord::default();
log_record_.observed_timestamp = Some(SystemTime::now());
log_record_.severity_number = Some(log_level_to_otel_severity(record.level()));
log_record_.severity_text = Some(record.level().as_str());
log_record_.target = Some(record.target().to_string().into());
log_record_.body = Some(AnyValue::Bytes(Box::new(match self.layout.as_ref() {
None => record.args().to_string().into_bytes(),
Some(layout) => layout.format(record)?,
})));

if let Some(module_path) = record.module_path() {
log_record_.add_attribute("module_path", module_path.to_string());
}
if let Some(file) = log_record.file() {
record.add_attribute("file", file.to_string());
if let Some(file) = record.file() {
log_record_.add_attribute("file", file.to_string());
}
if let Some(line) = log_record.line() {
record.add_attribute("line", line);
if let Some(line) = record.line() {
log_record_.add_attribute("line", line);
}

struct KvExtractor<'a> {
Expand All @@ -193,11 +208,11 @@ impl Append for OpentelemetryLog {
}

let mut extractor = KvExtractor {
record: &mut record,
record: &mut log_record_,
};
log_record.key_values().visit(&mut extractor).ok();
record.key_values().visit(&mut extractor).ok();

logger.emit(record);
logger.emit(log_record_);
Ok(())
}

Expand Down
20 changes: 18 additions & 2 deletions src/append/rolling_file/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,39 @@ use log::Record;

use crate::append::rolling_file::non_blocking::NonBlocking;
use crate::append::Append;
use crate::layout::TextLayout;
use crate::Layout;

/// An appender that writes log records to a file that rolls over when it reaches a certain date
/// time.
#[derive(Debug)]
pub struct RollingFile {
layout: Layout,
writer: NonBlocking,
}

impl RollingFile {
/// Creates a new `RollingFile` appender that writes log records to the given writer.
///
/// This appender by default uses [`TextLayout`] to format log records as bytes.
pub fn new(writer: NonBlocking) -> Self {
Self { writer }
Self {
layout: TextLayout::default().no_color().into(),
writer,
}
}

/// Sets the layout used to format log records as bytes.
pub fn with_layout(mut self, layout: impl Into<Layout>) -> Self {
self.layout = layout.into();
self
}
}

impl Append for RollingFile {
fn append(&self, record: &Record) -> anyhow::Result<()> {
let bytes = format!("{}\n", record.args()).into_bytes();
let mut bytes = self.layout.format(record)?;
bytes.push(b'\n');
self.writer.send(bytes)?;
Ok(())
}
Expand Down
52 changes: 46 additions & 6 deletions src/append/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,35 @@
use std::io::Write;

use crate::append::Append;
use crate::layout::TextLayout;
use crate::Layout;

/// An appender that prints log records to stdout.
#[derive(Default, Debug)]
pub struct Stdout;
#[derive(Debug)]
pub struct Stdout {
layout: Layout,
}

impl Default for Stdout {
fn default() -> Self {
Self {
layout: TextLayout::default().into(),
}
}
}

impl Stdout {
/// Creates a new `Stdout` appender with the given layout.
pub fn with_layout(mut self, layout: impl Into<Layout>) -> Self {
self.layout = layout.into();
self
}
}

impl Append for Stdout {
fn append(&self, record: &log::Record) -> anyhow::Result<()> {
let bytes = format!("{}\n", record.args()).into_bytes();
let mut bytes = self.layout.format(record)?;
bytes.push(b'\n');
std::io::stdout().write_all(&bytes)?;
Ok(())
}
Expand All @@ -33,12 +54,31 @@ impl Append for Stdout {
}

/// An appender that prints log records to stderr.
#[derive(Default, Debug)]
pub struct Stderr;
#[derive(Debug)]
pub struct Stderr {
layout: Layout,
}

impl Default for Stderr {
fn default() -> Self {
Self {
layout: TextLayout::default().into(),
}
}
}

impl Stderr {
/// Creates a new `Stderr` appender with the given layout.
pub fn with_layout(mut self, encoder: impl Into<Layout>) -> Self {
self.layout = encoder.into();
self
}
}

impl Append for Stderr {
fn append(&self, record: &log::Record) -> anyhow::Result<()> {
let bytes = format!("{}\n", record.args()).into_bytes();
let mut bytes = self.layout.format(record)?;
bytes.push(b'\n');
std::io::stderr().write_all(&bytes)?;
Ok(())
}
Expand Down
Loading

0 comments on commit f8cfddd

Please sign in to comment.