Why logging behaves this way in python

So, I recently experienced some strange behavior in my project, so I did a little test to reproduce the behavior. Here is the complete code:

import logging
from logging import config

config.dictConfig({
    'version': 1,
    'formatters': {
        'fmt_root':    {'format': '[ /        ] - %(levelname)s - %(name)s - %(message)s'},
        'fmt_pkg':     {'format': '[ /pkg     ] - %(levelname)s - %(name)s - %(message)s'},
        'fmt_pkg_sub': {'format': '[ /pkg/sub ] - %(levelname)s - %(name)s - %(message)s'},
    },
    'handlers': {
        'hnd_root': {
            'class': 'logging.StreamHandler',
            'level': logging.DEBUG,
            'stream': 'ext://sys.stdout',
            'formatter': 'fmt_root',
        },
        'hnd_pkg': {
            'class': 'logging.StreamHandler',
            'level': logging.DEBUG,
            'stream': 'ext://sys.stdout',
            'formatter': 'fmt_pkg',
        },
        'hnd_pkg_sub': {
            'class': 'logging.StreamHandler',
            'level': logging.DEBUG,
            'stream': 'ext://sys.stdout',
            'formatter': 'fmt_pkg_sub',
        },
    },
    'root': {
        'handlers': ['hnd_root'],
        'level': logging.DEBUG,
    },
    'loggers': {
        'pkg': {
            'handlers': ['hnd_pkg'],
            'level': logging.WARNING,
            'propagate': True,
        },
        'pkg.sub': {
            'handlers': ['hnd_pkg_sub'],
            'level': logging.INFO,
            'propagate': True,
        },
    },
})

logging.getLogger().info('message 1')
logging.getLogger('pkg').info('message 2')
logging.getLogger('pkg.sub').info('message 3')

The output of this small program:

[ /        ] - INFO - root - message 1
[ /pkg/sub ] - INFO - pkg.sub - message 3
[ /pkg     ] - INFO - pkg.sub - message 3
[ /        ] - INFO - pkg.sub - message 3

Now this is not the result that I naturally expected. Why is message 2 not logged in the root log (message level is information, root accepts the debug level) and why is message 3 logged in the pkg log (message level is information, pkg accepts a warning)?

, , , - , . . ? ? ?

PS: , , , , :

[ /        ] - INFO - root - message 1
[ /        ] - INFO - pkg - message 2
[ /pkg/sub ] - INFO - pkg.sub - message 3
[ /        ] - INFO - pkg.sub - message 3
+4
1

, go/no go. , . , FileHandler, INFO SMTPHandler, CRITICAL.
, , - True, , , .

, message 2 , , message 3 3 , , INFO', \, pkg pgk.sub , INFO.

, " ?" " // ..?".

1.

Logger  | Logger level | Handler Level
/       | CRITICAL     | DEBUG
pkg     | CRITICAL     | DEBUG
pkg.sub | DEBUG        | DEBUG

logging.getLogger('pkg.sub').debug('message 3') :

[ /pkg/sub ] - DEBUG - pkg.sub - message 3
[ /pkg     ] - DEBUG - pkg.sub - message 3
[ /        ] - DEBUG - pkg.sub - message 3

2.

Logger  | Logger level | Handler Level
/       | CRITICAL     | INFO
pkg     | CRITICAL     | DEBUG
pkg.sub | DEBUG        | DEBUG

logging.getLogger('pkg.sub').debug('message 3') :

[ /pkg     ] - DEBUG - pkg.sub - message 3
[ /        ] - DEBUG - pkg.sub - message 3

3.

Logger  | Logger level | Handler Level
/       | CRITICAL     | DEBUG
pkg     | CRITICAL     | INFO
pkg.sub | DEBUG        | DEBUG

logging.getLogger('pkg.sub').debug('message 3') :

[ /pkg/sub ] - DEBUG - pkg.sub - message 3
[ /        ] - DEBUG - pkg.sub - message 3

, :

Logger  | Logger level | Handler Level
/       | DEBUG        | DEBUG
pkg     | INFO         | WARNING
pkg.sub | INFO         | DEBUG
+3

Source: https://habr.com/ru/post/1536429/


All Articles