One thing I've come to appreciate about the various Java logging frameworks is that they are capable of initializing themselves (generally from system properties and/or resources on the classpath) with user-provided configuration either upon system startup or initial usage, when the very first message is logged. How would you feel about adding similar capability to Timbre?
I have a couple of use-cases in mind with this feature request:
Maintaining a logging configuration for testing/development that overrides the Timbre default configuration. For my deployed code, I can simply put a call to merge-config! first thing in my main function and use whatever mechanism I want to set my user configuration. When running code via unit tests or the REPL, though, there's not a single predictable entrypoint where I can set up my logging configuration. I've taken to setting up a development configuration in a user.clj on my project's :dev-profile classpath, but I don't find this approach entirely satisfactory.
When working with complex dependencies, I frequently run into the situation where dependencies are emitting log messages as part of their own initialization, in extreme cases as a side-effect of a namespace-level :require or :import. When I have to set up logging configuration via an explicit call to merge-config! it's not always possible to structure my program in a way that allows me to capture these messages as part of my own application logs; the only reliable way to capture these messages from dependencies would be to have the logging framework load my application logging config.
One possible approach would be to look for a timbre.edn resource on the classpath, which could either embed a config map for simple configurations, or for more complex configurations could be a namespaced symbol that names a var for Timbre to dereference to obtain a config map. I think the main drawback would be the slight overhead to check the initialization status on every system startup and/or every logging call, but IMO that would be a worthwhile tradeoff.
One thing I've come to appreciate about the various Java logging frameworks is that they are capable of initializing themselves (generally from system properties and/or resources on the classpath) with user-provided configuration either upon system startup or initial usage, when the very first message is logged. How would you feel about adding similar capability to Timbre?
I have a couple of use-cases in mind with this feature request:
merge-config!
first thing in my main function and use whatever mechanism I want to set my user configuration. When running code via unit tests or the REPL, though, there's not a single predictable entrypoint where I can set up my logging configuration. I've taken to setting up a development configuration in auser.clj
on my project's:dev
-profile classpath, but I don't find this approach entirely satisfactory.:require
or:import
. When I have to set up logging configuration via an explicit call tomerge-config!
it's not always possible to structure my program in a way that allows me to capture these messages as part of my own application logs; the only reliable way to capture these messages from dependencies would be to have the logging framework load my application logging config.One possible approach would be to look for a
timbre.edn
resource on the classpath, which could either embed a config map for simple configurations, or for more complex configurations could be a namespaced symbol that names a var for Timbre to dereference to obtain a config map. I think the main drawback would be the slight overhead to check the initialization status on every system startup and/or every logging call, but IMO that would be a worthwhile tradeoff.