rust-lang / log

Logging implementation for Rust
https://docs.rs/log
Apache License 2.0
2.16k stars 250 forks source link

[question]: Use `Log` as instance instead of global singelton style? #541

Closed gabyx closed 1 year ago

gabyx commented 1 year ago

Is there a possibility to use a created Log as an instance instead as in a global singlton style?

use simple_logger::SimpleLogger;

fn main() {
    let log = SimpleLogger::new().env().with_colors(true);
    log.warn!("This is an example message.");
}
Thomasdezeeuw commented 1 year ago

Is there a possibility to use a created Log as an instance instead as in a global singlton style?

Yes, you can use the Log trait directly. But you can't use the macros, you'll have to redefine those yourself to accept an additional arguments which would be the Log implementation. Or build the log Records manually and use the trait directly.

gabyx commented 1 year ago

Thanks for the answer. I am kind of newbie in Rust. Would that mean defining my own MyLog trait to support macros on it? (basically redefining them) and then assign to let log: MyLog = ... and then log.info! ?

gabyx commented 1 year ago

Wouldnt it make sense to provide such a trait too or directly providing it in the Log trait?

Thomasdezeeuw commented 1 year ago

Thanks for the answer. I am kind of newbie in Rust. Would that mean defining my own MyLog trait to support macros on it? (basically redefining them) and then assign to let log: MyLog = ... and then log.info! ?

No, I meant redefining the macros to not use the global logger, but a logged you provide in the macro call. The log! macro calls __private_api_log here: https://github.com/rust-lang/log/blob/dc32ab999f52805d5ce579b526bd9d9684c38d1a/src/macros.rs#L33-L43, which in turn calls logger to get the global logger here: https://github.com/rust-lang/log/blob/dc32ab999f52805d5ce579b526bd9d9684c38d1a/src/lib.rs#L1438-L1460

Instead of getting the global logger your implementation would get one passed in the macro call, so instead of info!("my message") it would be info!(my_logger, "my message"). Note that it's not possible to define macros on a type, so logger.info! is not supported.

Wouldnt it make sense to provide such a trait too or directly providing it in the Log trait?

I'm not sure what your asking here, can you elaborate?

gabyx commented 1 year ago

Thanks!

I mean basically it boils down to not having global stuff in my application as best practice. And a singleton log is just that. I adapted the macro log::log! which works to my needs but then realized that is uses again log::max_level() which basically is again a global variable hidden.

Technically that should be stored in the log instance etc etc... :) I guess https://docs.rs/slog-term/latest/slog_term/ is better suited here.

NobodyXu commented 1 year ago

And a singleton log is just that. I adapted the macro log::log! which works to my needs but then realized that is uses again log::max_level() which basically is again a global variable hidden.

You can simply call Log::enabled instead to filter out logging messages below the max level, most logger supports this.

KodrAus commented 1 year ago

Just coming back through some triage. This issue hasn’t seen any activity in a while so I’ll go ahead and close it now since there’s nothing actionable for log here.

Thanks for the support @Thomasdezeeuw and @NobodyXu 🙏