Instantiating a non-trivial struct as `'static` for `log::set_logger()`

I am trying to implement my own log::Loger which caches them in a. vec and then pushes them to a remote server.

However, log.set_logger(x) requires x to be a reference with a static lifetime, and I cannot for the life of me figure out how to create a non-trivial struct and tell rust it is static.

My struct:

pub struct LogStoreClient {
    pub logs: Arc<RwLock<Vec<Message>>>,
}

impl log::Log for LogStoreClient {...}

Things I've tried:

  • static LOGGER = LogStoreClient { logs:...} fails because calls in statics are limited to constant functions, tuple structs and tuple variants
  • static LOGGER = LogStoreClient::default() fails for the same reason
  • lazy_static! crate works but rust no longer understands that LogStoreClient implements log::Log
  • banging my head against a different type of wall, but that still hurts

It's driving me insane, and I can't believe I am the first person to ever want my own instance of a log::Log with state.

(The reason for the Arc<RwLock is because log::Log takes in &self not &mut self)

Help :slight_smile:

You can put it in a Box and then leak() it.

1 Like

There’s apparently also the set_boxed_logger function in that crate that will leak the Box for you :smile:

Edit: Actually it’s a bit better: It only leaks the box if the logger wasn’t already set before. Since a logger can only be set once throughout the entire run of the program, this ensures that only a limited amount of memory is ever leaked.

1 Like

thanks both.

https://stackoverflow.com/a/48115258 also provides a solution (&*LOGGER)

1 Like