Skip to content

Commit

Permalink
Implement RuntimePattern
Browse files Browse the repository at this point in the history
  • Loading branch information
SpriteOvO committed Oct 25, 2023
1 parent 9d754cf commit 044111d
Show file tree
Hide file tree
Showing 10 changed files with 753 additions and 350 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'windows-latest', 'macos-latest']
fn_features: ['', 'log native libsystemd multi-thread']
fn_features: ['', 'log native libsystemd multi-thread runtime-pattern']
cfg_feature: ['', 'flexible-string', 'source-location']
runs-on: ${{ matrix.os }}
steps:
Expand Down
5 changes: 4 additions & 1 deletion spdlog/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,21 @@ source-location = []
native = []
libsystemd = ["libsystemd-sys"]
multi-thread = ["crossbeam"]
runtime-pattern = ["spdlog-internal"]

[dependencies]
arc-swap = "1.5.1"
atomic = "0.5.1"
cfg-if = "1.0.0"
chrono = "0.4.22"
crossbeam = { version = "0.8.2", optional = true }
dyn-clone = "1.0.14"
flexible-string = { version = "0.1.0", optional = true }
if_chain = "1.0.2"
is-terminal = "0.4"
log = { version = "0.4.8", optional = true }
once_cell = "1.16.0"
spdlog-internal = { version = "=0.1.0", path = "../spdlog-internal" }
spdlog-internal = { version = "=0.1.0", path = "../spdlog-internal", optional = true }
spdlog-macros = { version = "0.1.0", path = "../spdlog-macros" }
spin = "0.9.8"
static_assertions = "1.1.0"
Expand Down Expand Up @@ -78,6 +80,7 @@ flexi_logger = "=0.24.1"
tracing = "=0.1.37"
tracing-subscriber = "=0.3.16"
tracing-appender = "=0.2.2"
paste = "1.0.14"

[build-dependencies]
rustc_version = "0.4.0"
Expand Down
268 changes: 75 additions & 193 deletions spdlog/benches/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ extern crate test;

use std::{cell::RefCell, sync::Arc};

use paste::paste;
use spdlog::{
formatter::{pattern, Formatter, FullFormatter, Pattern, PatternFormatter},
formatter::{pattern, Formatter, FullFormatter, Pattern, PatternFormatter, RuntimePattern},
prelude::*,
sink::Sink,
Record, StringBuf,
Expand Down Expand Up @@ -76,15 +77,7 @@ fn bench_pattern(bencher: &mut Bencher, pattern: impl Pattern + Clone + 'static)
bench_formatter(bencher, PatternFormatter::new(pattern));
}

#[bench]
fn bench_1_full_formatter(bencher: &mut Bencher) {
bench_formatter(bencher, FullFormatter::new())
}

#[bench]
fn bench_2_full_pattern(bencher: &mut Bencher) {
let pattern = pattern!("[{date} {time}.{millisecond}] [{level}] {payload}{eol}");

fn bench_full_pattern(bencher: &mut Bencher, pattern: impl Pattern + Clone + 'static) {
let full_formatter = Arc::new(StringSink::with(|b| {
b.formatter(Box::new(FullFormatter::new()))
}));
Expand All @@ -103,192 +96,81 @@ fn bench_2_full_pattern(bencher: &mut Bencher) {
bench_pattern(bencher, pattern)
}

#[bench]
fn bench_weekday_name(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{weekday_name}"))
}

#[bench]
fn bench_weekday_name_full(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{weekday_name_full}"))
}

#[bench]
fn bench_month_name(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{month_name}"))
}

#[bench]
fn bench_month_name_full(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{month_name_full}"))
}

#[bench]
fn bench_datetime(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{datetime}"))
}

#[bench]
fn bench_year_short(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{year_short}"))
}

#[bench]
fn bench_year(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{year}"))
}

#[bench]
fn bench_date_short(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{date_short}"))
}

#[bench]
fn bench_date(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{date}"))
}

#[bench]
fn bench_month(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{month}"))
}

#[bench]
fn bench_day(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{day}"))
}

#[bench]
fn bench_hour(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{hour}"))
}

#[bench]
fn bench_hour_12(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{hour_12}"))
}

#[bench]
fn bench_minute(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{minute}"))
}

#[bench]
fn bench_second(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{second}"))
}

#[bench]
fn bench_millsecond(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{millisecond}"))
}

#[bench]
fn bench_microsecond(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{microsecond}"))
}

#[bench]
fn bench_nanosecond(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{nanosecond}"))
}

#[bench]
fn bench_am_pm(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{am_pm}"))
}

#[bench]
fn bench_time_12(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{time_12}"))
}

#[bench]
fn bench_time_short(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{time_short}"))
}

#[bench]
fn bench_time(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{time}"))
}

#[bench]
fn bench_tz_offset(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{tz_offset}"))
}

#[bench]
fn bench_unix_timestamp(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{unix_timestamp}"))
}

#[bench]
fn bench_full(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{full}"))
}

#[bench]
fn bench_level(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{level}"))
}

#[bench]
fn bench_level_short(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{level_short}"))
}
//

#[bench]
fn bench_source(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{source}"))
}

#[bench]
fn bench_file_name(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{file_name}"))
}

#[bench]
fn bench_file(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{file}"))
}

#[bench]
fn bench_line(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{line}"))
}

#[bench]
fn bench_column(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{column}"))
}

#[bench]
fn bench_module_path(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{module_path}"))
}

#[bench]
fn bench_logger(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{logger}"))
}

#[bench]
fn bench_payload(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{payload}"))
}

#[bench]
fn bench_pid(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{pid}"))
}

#[bench]
fn bench_tid(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{tid}"))
fn bench_1_full_formatter(bencher: &mut Bencher) {
bench_formatter(bencher, FullFormatter::new())
}

#[bench]
fn bench_eol(bencher: &mut Bencher) {
bench_pattern(bencher, pattern!("{eol}"))
fn bench_2_full_pattern_ct(bencher: &mut Bencher) {
bench_full_pattern(
bencher,
pattern!("[{date} {time}.{millisecond}] [{level}] {payload}{eol}"),
)
}

#[bench]
fn bench_3_full_pattern_rt(bencher: &mut Bencher) {
bench_full_pattern(
bencher,
RuntimePattern::new("[{date} {time}.{millisecond}] [{level}] {payload}{eol}").unwrap(),
)
}

macro_rules! bench_patterns {
( $(($name:ident, $placeholder:literal)),+ $(,)? ) => {
$(paste! {
#[bench]
fn [<bench_4_ct_ $name>](bencher: &mut Bencher) {
bench_pattern(bencher, pattern!($placeholder))
}
#[bench]
fn [<bench_5_rt_ $name>](bencher: &mut Bencher) {
bench_pattern(bencher, RuntimePattern::new($placeholder).unwrap())
}
})+
};
}

bench_patterns! {
(weekday_name, "{weekday_name}"),
(weekday_name_full, "{weekday_name_full}"),
(month_name, "{month_name}"),
(month_name_full, "{month_name_full}"),
(datetime, "{datetime}"),
(year_short, "{year_short}"),
(year, "{year}"),
(date_short, "{date_short}"),
(date, "{date}"),
(month, "{month}"),
(day, "{day}"),
(hour, "{hour}"),
(hour_12, "{hour_12}"),
(minute, "{minute}"),
(second, "{second}"),
(millsecond, "{millisecond}"),
(microsecond, "{microsecond}"),
(nanosecond, "{nanosecond}"),
(am_pm, "{am_pm}"),
(time_12, "{time_12}"),
(time_short, "{time_short}"),
(time, "{time}"),
(tz_offset, "{tz_offset}"),
(unix_timestamp, "{unix_timestamp}"),
(full, "{full}"),
(level, "{level}"),
(level_short, "{level_short}"),
(source, "{source}"),
(file_name, "{file_name}"),
(file, "{file}"),
(line, "{line}"),
(column, "{column}"),
(module_path, "{module_path}"),
(logger, "{logger}"),
(payload, "{payload}"),
(pid, "{pid}"),
(tid, "{tid}"),
(eol, "{eol}"),
}
34 changes: 34 additions & 0 deletions spdlog/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ pub enum Error {
#[cfg(feature = "multi-thread")]
#[error("failed to send message to channel: {0}")]
SendToChannel(SendToChannelError, SendToChannelErrorDropped),

/// The variant returned by [`RuntimePatternBuilder::build`] when the
/// pattern is failed to be built at runtime.
///
/// [`RuntimePatternBuilder::build`]: crate::formatter::RuntimePatternBuilder::build
#[cfg(feature = "runtime-pattern")]
#[error("failed to build pattern at runtime: {0}")]
BuildPattern(BuildPatternError),
}

/// This error type contains a variety of possible invalid arguments.
Expand Down Expand Up @@ -119,6 +127,16 @@ pub enum InvalidArgumentError {
ThreadPoolCapacity(String),
}

#[cfg(feature = "runtime-pattern")]
impl Error {
pub(crate) fn err_build_pattern(err: BuildPatternErrorInner) -> Self {
Self::BuildPattern(BuildPatternError(err))
}
pub(crate) fn err_build_pattern_internal(err: spdlog_internal::pattern_parser::Error) -> Self {
Self::BuildPattern(BuildPatternError(BuildPatternErrorInner::Internal(err)))
}
}

/// This error indicates that an invalid logger name was set.
///
/// See the documentation of [`LoggerBuilder::name`] for the name requirements.
Expand Down Expand Up @@ -214,6 +232,22 @@ impl SendToChannelErrorDropped {
}
}

/// This error indicates that an error occurred while building a pattern at
/// compile-time.
#[cfg(feature = "runtime-pattern")]
#[derive(Error, Debug)]
#[error("{0}")]
pub struct BuildPatternError(BuildPatternErrorInner);

#[cfg(feature = "runtime-pattern")]
#[derive(Error, Debug)]
pub(crate) enum BuildPatternErrorInner {
#[error("{0}")]
Internal(spdlog_internal::pattern_parser::Error),
#[error("invalid placeholder for custom pattern '{0}'")]
InvalidCustomPlaceholder(String),
}

/// The result type of this crate.
pub type Result<T> = result::Result<T, Error>;

Expand Down
Loading

0 comments on commit 044111d

Please sign in to comment.