I am using the Python standard logging configuration, combined with yaml
to load a config file with the dictConfig()
function:
import logging
import yaml
with open('logging.yaml','r') as f:
logConfig = yaml.safe_load(f.read())
logging.config.dictConfig(logConfig)
Since an incremental logging configuration in python limits the capabilities, every logging file has to contain a minimum amount of information, something like this:
version: 1
formatters:
simple:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
loggers:
my_module:
level: ERROR
root:
level: INFO
handlers: [console]
Which either forces one to learn this by heart, store it somewhere, or look it up each time. Since neither of these really work for me, I would like to find a way to generate it. This brings me to the question:
Is there a way to get the current (or basic) logging config as a dictionary?
This would make it easy to make an initial config file by running the following code once, and just remove/edit what you want:
import logging
import yaml
logConfig = logging.get_current_config_as_a_dictionary()
with open('logging.yaml','w') as f:
f.write(yaml.dump(logConfig))
Yaml is just my personal preference of course, the same question could be posted for something like JSON.
I'm not sure if there's a clean way do to this through any public logging
function. Looking through the package CPython source, the defaults aren't set aside and neatly defined in any structure (such as a dict). Instead, they're hardcoded into the function logging.basicConfig
. Specifically, this function contains some common "default" setup keywords, but unfortunately for your purposes, these are hardcoded into the function. For example:
style = kwargs.pop("style", '%')
This uses the root
logger (which itself is root = RootLogger(logging.WARNING)
) and adds some config to it.
One way to work with that, which is really not ideal, would be to look at the "before and after" config tied to logging.root
before and after you call logging.basicConfig()
*. For example:
>>> root = logging.root
>>> root.handlers
[]
>>> logging.basicConfig()
>>> root.handlers
[<StreamHandler <stderr> (NOTSET)>]
Lastly, I would mention that the default style comes from:
logging._STYLES['%']
which works out to %(levelname)s:%(name)s:%(message)s
.
*If you call this function with no arguments, there is really not a whole lot done; the main change is adding a StreamHandler
(stdout) to the root logger and then adding a Formatter
to that.
I don't see a complete solution for you, but the logging_tree package looks like a step in the right direction. If you look at its source code, you may be able to change its output to match the dictionary you're looking for.
Here's the output it currently generates, from its home page:
>>> logging.getLogger('a')
>>> logging.getLogger('a.b').setLevel(logging.DEBUG)
>>> logging.getLogger('x.c')
>>> from logging_tree import printout
>>> printout()
<--""
Level WARNING
|
o<--"a"
| Level NOTSET so inherits level WARNING
| |
| o<--"a.b"
| Level DEBUG
|
o<--[x]
|
o<--"x.c"
Level NOTSET so inherits level WARNING
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With