Search code examples
rustrust-tokioactix-weblog-level

Programatically get the logging level in rust


I have one rust application (actix-web framework used). How can I get the logging level defined. Requirement is to execute one method to log something if the logging level is "Debug", otherwise not.

what should be the body of following is_degug_log_enabled method

#[tokio::main]
async fn main() {
    SimpleLogger::new().env().with_level(LevelFilter::Error).init().unwrap();
    
    if is_degug_log_enabled() {
      any_logging_method();
    }
}

fn is_degug_log_enabled() -> bool {
    // in this case it should return false as logging level is 'Error'
}

Solution

  • A SimpleLogger is one of many implementations for the log crate. Once initialized, it can only be interacted through the Log trait which is retrievable via log::logger().

    However, that does not expose a "current level" since that is too narrow a metric for what users often want to log. Context is also important. In particular, the Log implementation decides what to log based on the Metadata that encompasses a level and a target. The target being the module path (i.e. some_crate::nested::module). So to check if something would be logged, you need to get or recreate the Metadata for it and call .enabled(). Fortunately, this is handled for you.

    Use log_enabled!():

    This can be used to avoid expensive computation of log message arguments if the message would be ignored anyway.

    if log::log_enabled!(Debug) {
        any_logging_method();
    }
    

    This is tangential but worth pointing out the other de-facto logging crate, tracing, works pretty much the exact same way: it has Subscriber as its interface which has an enabled() method that takes in some Metadata. The metadata and interacting with the subscriber are more complicated due to enhanced customization, structured logging, and spans; but the concept is the same that subscribers/users may want to filter logs based on more than just level.

    Fortunately, you don't have to worry about that either and can just use one of the enabled! macros. Below, I used event_enabled! since log messages are "events" in tracing's parlance:

    if tracing::event_enabled!(Level::DEBUG) {
        any_logging_method();
    }
    

    You can read through the documentation for more info for spans or structured logging.


    Actix-Web uses the log crate as far as I'm aware but you can configure it with your own tracing middleware or simply configure tracing to ingest logs from the log crate macros or vice versa (documentation).