rust-lang / log

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

Is it possible to reset the global logger after the program initiates the global logger #560

Closed yaoxin1995 closed 8 months ago

yaoxin1995 commented 1 year ago

Hey, I would like to reset the global logger (replace the old one with a new logger) as follows:


    let a = WriteLogger::new(LevelFilter::Info, config, File::create("benchmark111.log").unwrap());

    log::set_boxed_logger(a).unwrap();

But I got the error SetLoggerError(()).

Do you know how I can replace the logger?

NobodyXu commented 1 year ago

You can create your own newtype logger which allows switching between different loggers:

struct CustomLogger(std::sync::Mutex<Box<dyn Logger + Send + Sync + 'static>>);

impl Logger for CustomLogger {
     // ...
}
Geass-LL commented 1 year ago

Hi, I'm curious why log doesn't support reset the global logger, it's easy to remove the STATE check, so I'm sure I didn't get the real reason. Is there anything I should pay attention to if I want to implement it myself? Thanks.

Thomasdezeeuw commented 1 year ago

Hi, I'm curious why log doesn't support reset the global logger, it's easy to remove the STATE check, so I'm sure I didn't get the real reason. Is there anything I should pay attention to if I want to implement it myself? Thanks.

Because the logger function returns a static lifetime, see https://github.com/rust-lang/log/blob/cab10885defdf445dc730e5a22f67fcec69ca728/src/lib.rs#L1458

If the logging implementation could be de-initialised or switched it could means that the logger would be deallocated while references to it still exists.

A solution for this could be to implement your own logger switcher, e.g. using RwLock<MyLogger>. Of course this will have an impact on performance.

Geass-LL commented 1 year ago

Hi, I'm curious why log doesn't support reset the global logger, it's easy to remove the STATE check, so I'm sure I didn't get the real reason. Is there anything I should pay attention to if I want to implement it myself? Thanks.

Because the logger function returns a static lifetime, see

https://github.com/rust-lang/log/blob/cab10885defdf445dc730e5a22f67fcec69ca728/src/lib.rs#L1458

If the logging implementation could be de-initialised or switched it could means that the logger would be deallocated while references to it still exists.

A solution for this could be to implement your own logger switcher, e.g. using RwLock<MyLogger>. Of course this will have an impact on performance.

Thank you!

NobodyXu commented 1 year ago

P.S. If your log implementation can operate on immutable reference or uses fine-grand locking inside, then you could use ArcSwap which is optimized for read-heavy (immutable-use heavy) scenario.

Geass-LL commented 1 year ago

P.S. If your log implementation can operate on immutable reference or uses fine-grand locking inside, then you could use ArcSwap which is optimized for read-heavy (immutable-use heavy) scenario.

Thanks for your advice!

brummer-simon commented 11 months ago

Hi @yaoxin1995 /@Geass-LL!

I share the same reconfiguration demand and created a solution. Checkout out this crate: https://github.com/brummer-simon/alterable_logger

Thomasdezeeuw commented 8 months ago

Closing this as not possible with the current design.