Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you add a handler to a Python Logger object globally?

Tags:

python

logging

I want to create a logger for my project which has a custom handler that works across all submodules and which logs uncaught exceptions. Below is my proof-of-concept; note that I am using a file handler as a stand-in for what will eventually be my custom handler.

main.py:

import logging
import sys
from module import divide

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

fh = logging.FileHandler("test.log")
fh.setLevel(logging.INFO)
logger.addHandler(fh)

def uncaught_error(exc_type, exc_value, exc_traceback):
    logger.error("Uncaught Exception", exc_info = (exc_type, exc_value, exc_traceback))
    sys.__excepthook__(exc_type, exc_value, exc_traceback)
    return

sys.excepthook = uncaught_error

if __name__ == '__main__':
    logger.info("first division problem")
    print(divide(5,2))
    logger.info("second division problem")
    print(divide(10,0))
    logger.info("end")

module.py:

import logging

logger = logging.getLogger(__name__)

def divide(a, b):
    logger.info("dividing " + str(a) + " by " + str(b))
    return a/b

After I run main.py, here is the output of test.log:

first division problem
second division problem
Uncaught Exception
Traceback (most recent call last):
  File "main.py", line 23, in <module>
    print(divide(10,0))
  File "/some/path/logging_test/module.py", line 7, in divide
    return a/b
ZeroDivisionError: division by zero

The uncaught exception in module.py was logged beautifully, but the line

logger.info("dividing " + str(a) + " by " + str(b))

apparently did nothing (there was no console output either). What is the mistake?

like image 404
Paul Siegel Avatar asked Oct 16 '25 23:10

Paul Siegel


1 Answers

I just ran into this issue , where my root logging format wasn't being used in other sub-modules. I solved this by changing

logger = logging.getLogger(__name__)

in the main.py module to

logger = logging.getLogger()

so that it actually gets the root logger and not the __main__ logger.

See https://docs.python.org/2/library/logging.html#logging.getLogger

like image 66
ad22 Avatar answered Oct 19 '25 12:10

ad22