Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Logging - How to inherit root logger level & handler

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.

Thanks in advance

I am sorry, as this could be a duplicate question and I did go through those similar questions, but couldn't figure out how this works. Hence posting this question. I am not intentionally creating a duplicate bcz I didn't lookup for it.

like image 284
Dvusrgme Avatar asked Nov 21 '17 21:11

Dvusrgme


People also ask

How do you inherit a log in Python?

Inheritance in Logging If you have the logger called my_package. logger1 it will inherit the settings defined for my_package . If you have a specific logging setting for a particular logger and you don't want it to be handled by the parent's setting you have to set propagate attribute to False .

What are the five levels of logging in Python?

In Python, the built-in logging module can be used to log events. Log messages can have 5 levels - DEBUG, INGO, WARNING, ERROR and CRITICAL. They can also include traceback information for exceptions. Logs can be especially useful in case of errors to help identify their cause.

What is root in Python logging?

On top of the hierarchy is the root logger, which can be accessed via logging. root. This logger is called when methods like logging. debug() is used. By default, the root log level is WARN, so every log with lower level (for example via logging.info("info") ) will be ignored.


1 Answers

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.

like image 54
GLRoman Avatar answered Oct 19 '22 03:10

GLRoman