Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom log levels #636

Open
koraa opened this issue Jul 10, 2024 · 3 comments
Open

Custom log levels #636

koraa opened this issue Jul 10, 2024 · 3 comments

Comments

@koraa
Copy link

koraa commented Jul 10, 2024

Hi,

thank you all for writing a fantastic piece of software.

I am aware of #334.

My particular use case is having a log level "responsive" between warn and info.

rosenpass/rosenpass#326

Our goal is to be:

  • As silent as possible
  • Provide essentially a single line of output that we would otherwise mark log level info

Essentially be responsive without polluting logs.

Some ideas how to – cleanly – implement custom log levels:

  • Would it be possible to uniquely identify a particular log level through a constant variable? I.e. for instance ::log_level_critical::CRITICAL or log level ::rosenpass::util::log::level::RESPONSIVE which would be distinct from ::log_level_responsive::RESPONSIVE. This would allow clean reasoning about custom log levels across crates.
  • Would it be possible to specify constraints about how log level relate to each other?
    use log_custom_levels::{LogLevel, levels::INFO, Sort};
    
    // enum Sort {
    //     Lower,
    //     Equal,
    //     Higher,
    // }
    
    struct LogLevelResponsive {
        _phantom_private: ()
    }
    
    
    impl LogLevel for LogLevelResponsive {
        fn log_level_priority<Otr: LogLevelResponsive>(otr: Otr) -> Sort {
            use Sort::*;
            match INFO.log_level_priority(otr) {
                Lower  => Lower,
                Equal  => Higher,
                Higher => Higher,
            }
        }
    }
    
    const RESPONSIVE : LogLevelResponsive = LogLevelResponsive { _phantom_private: () };
@KodrAus
Copy link
Contributor

KodrAus commented Aug 2, 2024

Hi @koraa 👋

That’s an interesting design direction. I don’t think we’re likely to complicate level management in log; it’s intended to be a direct and straightforward library and using a fixed set of coarse grained levels lets us do things like compile-time filtering.

This is something you could possibly use the existing target field on log records for. They’re populated with the module name by default but can be set to anything through the macros. If you wanted, you could write your own wrapper over the log macros that set it to your custom level and still get very cheap filtering.

I think we could also benefit from potentially enhancing our Metadata type, which is used for filtering, by adding key-values to it so you can filter on those too.

@koraa
Copy link
Author

koraa commented Aug 3, 2024

Hi @KodrAus

thanks for the detailed response!

An elegant way to add Key/Value type data to your metadata type would be great; this could directly be used to implement sublevels.

A mechanism based on static or dynamic polymorphism instead of a hash map would be optimal to avoid heap allocations during logging. This would also help to globally identify keys. If arbitrary strings where used as keys, there is a danger to get keys from different crates mixed up.

Anyway, thanks for the hard work on this crate!

@Thomasdezeeuw
Copy link
Collaborator

An elegant way to add Key/Value type data to your metadata type would be great; this could directly be used to implement sublevels.

Take a look at the kv module documentation: https://docs.rs/log/latest/log/kv/index.html.

A mechanism based on static or dynamic polymorphism instead of a hash map would be optimal to avoid heap allocations during logging. This would also help to globally identify keys. If arbitrary strings where used as keys, there is a danger to get keys from different crates mixed up.

I've used special targets in my create to "add" additonal log levels. Some examples:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants