SpriteOvO / spdlog-rs

Fast, highly configurable Rust logging crate
https://crates.io/crates/spdlog-rs
Apache License 2.0
109 stars 12 forks source link

Implement `config` feature #47

Open SpriteOvO opened 11 months ago

SpriteOvO commented 11 months ago

This is an early implementation of #25 in progress. It is currently very incomplete, just for previewing its API and approach.

Note to self: Remember to change the base branch to main or main-dev before merging.


We mainly introduced a new trait:

pub trait Configurable: Sized {
    type Params: DeserializeOwned + Default + Send;

    fn metadata() -> ComponentMetadata;
    fn build(params: Self::Params) -> Result<Self>;
}

then we implement it for built-in sinks and formatters like:

impl Configurable for FileSink {
    type Params = FileSinkParams;

    fn metadata() -> ComponentMetadata {
        ComponentMetadata { name: "FileSink" }
    }

    fn build(params: Self::Params) -> Result<Self> {
        let mut builder = FileSink::builder()
            .level_filter(params.0.common_builder_impl.level_filter)
            .path(params.0.path)
            .truncate(params.0.truncate);
        if let Some(formatter) = params.0.common_builder_impl.formatter {
            builder = builder.formatter(formatter);
        }
        builder.build()
    }
}
impl Configurable for PatternFormatter<RuntimePattern> {
    type Params = PatternFormatterRuntimePatternParams;

    fn metadata() -> ComponentMetadata {
        ComponentMetadata {
            name: "PatternFormatter",
        }
    }

    fn build(params: Self::Params) -> Result<Self> {
        Ok(Self::new(RuntimePattern::new(params.template)?))
    }
}

Of course, users can implement this trait for their own sinks and formatters.

With the power of erased-serde, we can cast the type Params to a dyn erased_serde::Deserializer to be used later. (Check config/registry.rs)

When we deserializing a sink or formatter, we will first read the name field, then look it up from the registry, if found, deserializing the rest of the fields using the erased stored Deserializer. (Check config/parse.rs)


This whole deserialization process will be very hidden to users! trait Configurable and .register_xxx() is the only thing they need to care about if they have their own sink / formatter.

SpriteOvO commented 6 months ago

There's still a lot of work to be done on this, and I'd like to delay it to v0.5.0. This way we can release v0.4.0 earlier to provide many of the small fixes, since backporting existing fixes has been a bit difficult.