Configuration#

The logging package contains many facilities to set up the configuration for it. There is even a separate module for it, logging.config. This page is focused on such options.

Check documentation of the logging.config module.

import logging

dictionary#

By using logging.config.dictConfig function you can cofigure your logging system using python dictionaries. As a consequence, any other format chasing the key:value format can be used (yaml, json, xml and so on).

It’s the configuration method recommended by official documentation for new applications and deployments.

Note it may seem that converting yaml, json, etc. into dictionaries and then using dictConfig is a crutch, but this is the method recommended by the official documentation.

yaml to dict#

It’s pretty trivial task all you need is:

The following cell defines a yaml file that can be converted to a dictionary with logging configuration. It’ll be a logger that prints to the error stream with the pattern <-- %(message)s -->.

%%writefile configuration_files/example.yaml
version: 1
formatters:
    simpleFormatter :
        format : "<-- %(message)s -->"
handlers:
    consoleHandler:
        class: "logging.StreamHandler"
        formatter: "simpleFormatter"
loggers:
    simpleExample:
        level: DEBUG
        handlers:
            - "consoleHandler"
Overwriting configuration_files/example.yaml

The next cell loads the previous yaml as a dictionary and shows that all is well.

import yaml
with open("configuration_files/example.yaml", "r") as f:
    conf_dict = yaml.safe_load(f)


logging.config.dictConfig(conf_dict)
logger = logging.getLogger("simpleExample")
logger.warning("wow it finally works")
<-- wow it finally works -->

ini file#

You can store your configuration in the .ini files.

Read more about .ini files:

Here is example of suck .ini file.

%%writefile configuration_files/example_logging.ini
[loggers]
keys=root,simpleExample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
Overwriting configuration_files/example_logging.ini

You can use the logging.config.fileConfig function to load the configuration file - all it’s entities will be added to your program. The following cell uses the config from the previous cell to define it’s loggers.

logging.config.fileConfig('configuration_files/example_logging.ini')
logger = logging.getLogger('simpleExample')
logger.debug("test")
2024-05-07 15:34:09,986 - simpleExample - DEBUG - test

disable_existing_loggers#

When you set up the configuration, all previous non-root loggers are disabled (read more about disabled property).

The following cell shows how the disabled property is created before the application of the configuration module changes.

basic_logger = logging.getLogger("disable_existing_logger")

print("before configuration", basic_logger.disabled)
logging.config.dictConfig({
    "version" : 1,
    "loggers" : {
        "simpleExample" : {}
    },
    #"disable_existing_loggers" : True
})
print("after configuration", basic_logger.disabled)
before configuration False
after configuration True

However, if you pass the disable_existing_loggers key with the value False, previously created loggers won’t be disabled. The following example show how it works.

basic_logger = logging.getLogger("disable_existing_logger")
basic_logger.disabled = False

print("before configuration", basic_logger.disabled)
logging.config.dictConfig({
    "version" : 1,
    "loggers" : {
        "simpleExample" : {}
    },
    "disable_existing_loggers" : False
})
print("after configuration", basic_logger.disabled)
before configuration False
after configuration False

The basic_logger remembers it’s disabled value even after the configuration has been applied.

Note that if you’re using fileConfig, you must pass disable_existing_loggers as an argument to the python function - not in the config file.