Python Logging - How to inherit root logger level & handler
Asked Answered
S

1

21

I am a python newbie, trying to implement logging into my code. I have two modules

main.py submodule.py

main.py

import logging
from logging.handlers import RotatingFileHandler
import submodule


import logging
from logging.handlers import RotatingFileHandler

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

fh = RotatingFileHandler('master.log', maxBytes=2000000, backupCount=10)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

logger.debug('DEBUG LEVEL - MAIN MODULE')
logger.info('INFO LEVEL - MAIN MODULE')

submodule.loggerCall()

submodule.py

import logging
from logging.handlers import RotatingFileHandler


def loggerCall():
    logger = logging.getLogger(__name__)
#    logger.setLevel(logging.DEBUG)

    fh = RotatingFileHandler('master.log', maxBytes=2000000, backupCount=10)
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(formatter)
    logger.addHandler(fh)

    logger.debug('SUBMODULE: DEBUG LOGGING MODE : ')
    logger.info('Submodule: INFO LOG')

    return

I thought as longs as I call the getLogger from my submodule, it should inherit the log level & handler details from root logger. However, in my case, I have to specify log level and handler again in submodule to get them print to same log file.

Also, If I have lots of methods, and classes inside my submodule. How can I go about it without having to define my log level & handler again.

Idea is to have a single log file with main, and sub modules printing in the same log based on the log level set in the main module.

Statolith answered 21/11, 2017 at 21:3 Comment(0)
C
38

The problem here is that you're not initializing the root logger; you're initializing the logger for your main module.

Try this for main.py:

import logging
from logging.handlers import RotatingFileHandler
import submodule

logger = logging.getLogger()  # Gets the root logger
logger.setLevel(logging.DEBUG)

fh = RotatingFileHandler('master.log', maxBytes=2000000, backupCount=10)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

logger.debug('DEBUG LEVEL - MAIN MODULE')
logger.info('INFO LEVEL - MAIN MODULE')

submodule.loggerCall()

Then try this for submodule.py:

def loggerCall():
    logger = logging.getLogger(__name__)
    logger.debug('SUBMODULE: DEBUG LOGGING MODE : ')
    logger.info('Submodule: INFO LOG')
    return

Since you said you wanted to send log messages from all your submodules to the same place, you should initialize the root logger and then simply use the message logging methods (along with setlevel() calls, as appropriate). Because there's no explicit handler for your submodule, logging.getLogger(__name__) will traverse the tree to the root, where it will find the handler you established in main.py.

Cavefish answered 22/3, 2018 at 21:36 Comment(3)
It is not valid for kivy.Logger. I could not logger inherit from different module in kivy application. Is there anyone that how to solve this problem in kivy?Shadwell
I found the solution. For kivy application, logging.getLogger() do not get root logger. So you must use logger = logging.getLogger().parentShadwell
This is a great answer! I especially appreciate that you mentioned "Because there is no explicit handler... traverse the tree to the root". That is precisely the information that I needed. :-)Adaptable

© 2022 - 2024 — McMap. All rights reserved.