Skip to content
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Breaking changes

* Rename `DefaultTrap` to `BestEffortTrap` for better clarity.
* Rename `logforth_core::record::Metadata` to `FilterCriteria`.
* Redesign `LevelFilter` to allow different comparison methods.
* Redesign `Level` as opentelemetry severity numbers.
* Add `Level::Fatal` variant to represent fatal level logs.
Expand Down
6 changes: 3 additions & 3 deletions bridges/log/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use logforth_core::Logger;
use logforth_core::default_logger;
use logforth_core::kv::Key;
use logforth_core::kv::Value;
use logforth_core::record::MetadataBuilder;
use logforth_core::record::FilterCriteria;
use logforth_core::record::RecordBuilder;

fn level_to_level(level: log::Level) -> logforth_core::record::Level {
Expand Down Expand Up @@ -100,12 +100,12 @@ impl log::Log for OwnedLogProxy {
}

fn forward_enabled(logger: &Logger, metadata: &Metadata) -> bool {
let metadata = MetadataBuilder::default()
let criteria = FilterCriteria::builder()
.target(metadata.target())
.level(level_to_level(metadata.level()))
.build();

Logger::enabled(logger, &metadata)
Logger::enabled(logger, &criteria)
}

fn forward_log(logger: &Logger, record: &Record) {
Expand Down
8 changes: 4 additions & 4 deletions core/src/filter/env_filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ use crate::Diagnostic;
use crate::Error;
use crate::Filter;
use crate::filter::FilterResult;
use crate::record::FilterCriteria;
use crate::record::Level;
use crate::record::LevelFilter;
use crate::record::Metadata;

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -110,9 +110,9 @@ impl EnvFilter {
}

impl Filter for EnvFilter {
fn enabled(&self, metadata: &Metadata, _: &[Box<dyn Diagnostic>]) -> FilterResult {
let level = metadata.level();
let target = metadata.target();
fn enabled(&self, criteria: &FilterCriteria, _: &[Box<dyn Diagnostic>]) -> FilterResult {
let level = criteria.level();
let target = criteria.target();

// search for the longest match, the vector is assumed to be pre-sorted
for directive in self.directives.iter().rev() {
Expand Down
7 changes: 4 additions & 3 deletions core/src/filter/env_filter/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ use crate::filter::env_filter::Directive;
use crate::filter::env_filter::EnvFilterBuilder;
use crate::filter::env_filter::ParseResult;
use crate::filter::env_filter::parse_spec;
use crate::record::FilterCriteria;
use crate::record::Level;
use crate::record::LevelFilter;
use crate::record::MetadataBuilder;

impl EnvFilter {
fn rejected(&self, level: Level, target: &str) -> bool {
let metadata = MetadataBuilder::default()
let criteria = FilterCriteria::builder()
.level(level)
.target(target)
.build();
matches!(Filter::enabled(self, &metadata, &[]), FilterResult::Reject)

matches!(Filter::enabled(self, &criteria, &[]), FilterResult::Reject)
}
}

Expand Down
15 changes: 10 additions & 5 deletions core/src/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
use std::fmt;

use crate::Diagnostic;
use crate::record::FilterCriteria;
use crate::record::LevelFilter;
use crate::record::Metadata;
use crate::record::Record;

pub mod env_filter;
Expand All @@ -39,17 +39,22 @@ pub enum FilterResult {
/// A filter that can be applied to log records.
pub trait Filter: fmt::Debug + Send + Sync + 'static {
/// Whether the record is filtered by its given metadata.
fn enabled(&self, metadata: &Metadata, diags: &[Box<dyn Diagnostic>]) -> FilterResult;
fn enabled(&self, criteria: &FilterCriteria, diags: &[Box<dyn Diagnostic>]) -> FilterResult;

/// Whether the record is filtered.
fn matches(&self, record: &Record, diags: &[Box<dyn Diagnostic>]) -> FilterResult {
self.enabled(record.metadata(), diags)
let criteria = FilterCriteria::builder()
.level(record.level())
.target(record.target())
.build();

self.enabled(&criteria, diags)
}
}

impl Filter for LevelFilter {
fn enabled(&self, metadata: &Metadata, _: &[Box<dyn Diagnostic>]) -> FilterResult {
if self.test(metadata.level()) {
fn enabled(&self, criteria: &FilterCriteria, _: &[Box<dyn Diagnostic>]) -> FilterResult {
if self.test(criteria.level()) {
FilterResult::Neutral
} else {
FilterResult::Reject
Expand Down
34 changes: 12 additions & 22 deletions core/src/kv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,18 @@

//! Key-value pairs in a log record or a diagnostic context.

// This file is derived from https://github.com/SpriteOvO/spdlog-rs/blob/788bda33/spdlog/src/kv.rs

pub extern crate value_bag;

use std::borrow::Cow;
use std::fmt;
use std::slice;
use std::sync::Arc;

use value_bag::OwnedValueBag;
use value_bag::ValueBag;

use crate::Error;
use crate::str::Str;
use crate::str::OwnedStr;
use crate::str::RefStr;

/// A visitor to walk through key-value pairs.
pub trait Visitor {
Expand All @@ -40,20 +38,18 @@ pub type Value<'a> = ValueBag<'a>;

/// A key in a key-value pair.
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Key<'a>(Str<'a>);
pub struct Key<'a>(RefStr<'a>);

impl Key<'static> {
/// Create a new key from a static `&str`.
pub const fn new(k: &'static str) -> Key<'static> {
Key(Str::new(k))
Key(RefStr::Static(k))
}
}

/// Create a new key from a shared value.
///
/// Cloning the key will involve cloning the `Arc`, which may be cheaper than cloning the
/// value itself.
pub fn new_shared(key: impl Into<Arc<str>>) -> Self {
Key(Str::new_shared(key))
impl fmt::Display for Key<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}

Expand All @@ -62,17 +58,17 @@ impl<'a> Key<'a> {
///
/// The [`Key::new`] method should be preferred where possible.
pub const fn new_ref(k: &'a str) -> Key<'a> {
Key(Str::new_ref(k))
Key(RefStr::Borrowed(k))
}

/// Convert to an owned key.
pub fn to_owned(&self) -> KeyOwned {
KeyOwned(self.0.to_shared())
KeyOwned(self.0.into_owned())
}

/// Convert to a `Cow` str.
pub fn to_cow(&self) -> Cow<'static, str> {
self.0.to_cow()
self.0.into_cow_static()
}

/// Get the key string.
Expand All @@ -81,18 +77,12 @@ impl<'a> Key<'a> {
}
}

impl fmt::Display for Key<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}

/// An owned value in a key-value pair.
pub type ValueOwned = OwnedValueBag;

/// An owned key in a key-value pair.
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct KeyOwned(Str<'static>);
pub struct KeyOwned(OwnedStr);

impl KeyOwned {
/// Create a `Key` ref.
Expand Down
10 changes: 5 additions & 5 deletions core/src/logger/log_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::Diagnostic;
use crate::Error;
use crate::Filter;
use crate::filter::FilterResult;
use crate::record::Metadata;
use crate::record::FilterCriteria;
use crate::record::Record;

static DEFAULT_LOGGER: OnceLock<Logger> = OnceLock::new();
Expand Down Expand Up @@ -99,10 +99,10 @@ impl Logger {

impl Logger {
/// Determine if a log message with the specified metadata would be logged.
pub fn enabled(&self, metadata: &Metadata) -> bool {
pub fn enabled(&self, criteria: &FilterCriteria) -> bool {
self.dispatches
.iter()
.any(|dispatch| dispatch.enabled(metadata))
.any(|dispatch| dispatch.enabled(criteria))
}

/// Log the [`Record`].
Expand Down Expand Up @@ -165,11 +165,11 @@ impl Dispatch {
}
}

fn enabled(&self, metadata: &Metadata) -> bool {
fn enabled(&self, criteria: &FilterCriteria) -> bool {
let diagnostics = &self.diagnostics;

for filter in &self.filters {
match filter.enabled(metadata, diagnostics) {
match filter.enabled(criteria, diagnostics) {
FilterResult::Reject => return false,
FilterResult::Accept => return true,
FilterResult::Neutral => {}
Expand Down
Loading
Loading