I would like to wrap the creation of a logger and all its associated configuration, formatters and handlers in a separate module, so that from my application I would just write:
import my_logger
test_logger = my_logger.getlogger("logger_name")
This logger will be used in a unit testing framework using unittest.TestCase
for logging purposes.
I use a QueueHandler
and a QueueListener
on one handler (as per https://docs.python.org/3/howto/logging-cookbook.html#dealing-with-handlers-that-block), as the handler is using the Telegram API and I would like to avoid hanging the whole application while waiting for the Telegram server to be available (for whatever reason).
The (perhaps silly) question is:
how can I automatically handle the start and stop of the QueueListener
when I start and stop the execution of the tests? Do I have to subclass a class of the logging module (which one?) to add, say, a start/stop method?
Thank you very much.
UPDATED (01)
I think I was not complete in my question. I already have the wrapper for the logger, you will find it below:
import logging
from logging.handlers import QueueHandler
from logging.handlers import QueueListener
import queue
from time import strftime
from notifiers.logging import NotificationHandler
def getLogger(name):
LOG_DIR = "logs"
_test_logger = logging.getLogger(name)
_test_logger.setLevel(logging.INFO)
# Create a file handler for the test logger.
# This handler will create the log file of the tests.
# TODO: create the LOG_DIR if it does not exist
now = strftime("%Y%m%d_%H%M%S")
# TODO: use os.path methods instead of directly writing path into filenames
_tl_fh = logging.FileHandler("..\\{}\\{}_{}.txt".format(LOG_DIR, now, name))
_tl_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
_tl_fh.setFormatter(_tl_formatter)
_test_logger.addHandler(_tl_fh)
# Create a console handler for the test logger.
# This is the logger to the console
_tl_console = logging.StreamHandler()
_test_logger.addHandler(_tl_console)
# Create a notifier logger. This will notify via Telegram:
# * start of a test suite
# * Stop of a test suite
# * Test suite and test case errors
# Create an unlimited size queue and attach it to a queue handler
que = queue.Queue(-1)
queue_handler = QueueHandler(que)
# Create a Telegram notification handler.
hdlr = NotificationHandler("telegram", defaults=defaults)
# On the other side of the queue attach a queue listener
_listener = QueueListener(que, hdlr)
queue_handler.setLevel(logging.ERROR)
_test_logger.addHandler(queue_handler)
formatter = logging.Formatter("%(asctime)s - %(levelno)s - %(levelname)s - %(message)s")
hdlr.setFormatter(formatter)
#=======================================================================
# Start the queue listener
#=======================================================================
_listener.start()
return _test_logger
The "problem" is the _listener.start()
line. How can I stop the listener at the end of the test?
Is it possible to add a start/stop methods to the loggers, so that I can write something like?
import my_logger
test_logger = my_logger.getlogger("logger_name")
[...] execute some test here
test_logger.stop()