Commit dac1c31c authored by Stéphane KANSCHINE's avatar Stéphane KANSCHINE

Merge branch 'logging-parameters' into 'master'

Make logging more adaptative refs #1772

See merge request !2
parents 7cf52e8c 01d4eaab
......@@ -5,25 +5,43 @@ import os
from django.conf import settings
def get_logger(log_name):
def get_logger(log_name) -> logging.Logger:
"""Return logger object which own two handlers at differents log level."""
os.makedirs(settings.LOG_DIR, exist_ok=True)
logfile_handler = logging.handlers.TimedRotatingFileHandler(settings.LOG_DIR + "/" + log_name,
logger = logging.getLogger(log_name)
logfile_handler = logging.handlers.TimedRotatingFileHandler(os.path.join(settings.LOG_DIR, log_name),
when="midnight",
interval=1,
backupCount=30)
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
logfile_handler.setFormatter(formatter)
logfile_handler.suffix = "%Y-%m-%d"
# Critical errors go to stderr, useful for cron commands
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.CRITICAL)
logfile_formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S')
logfile_handler.setLevel(logging.INFO)
logfile_handler.setFormatter(logfile_formatter)
logfile_handler.suffix = "%Y-%m-%d"
logger = logging.getLogger(log_name)
# logfile_handler is created only if they are no
# handler instance with same type and file target.
rotating_file_handler_exist = any([type(handler) == logging.handlers.TimedRotatingFileHandler
for handler in logger.handlers
if getattr(handler, 'baseFilename', '') == logfile_handler.baseFilename])
if not logger.handlers:
if not rotating_file_handler_exist:
logger.addHandler(logfile_handler)
# Console handler added only if they are no console handlers ever attached to 'logger'
if logging.StreamHandler not in [type(handler) for handler in logger.handlers]:
console_handler = logging.StreamHandler()
console_formatter = logging.Formatter('[%(levelname)s] %(message)s')
console_handler.setFormatter(console_formatter)
console_handler.setLevel(logging.CRITICAL)
if settings.DEBUG:
console_handler.setLevel(logging.DEBUG)
logger.addHandler(console_handler)
# Only handlers define log level, parent logger set at the lowest level
if settings.DEBUG:
logger.setLevel(logging.DEBUG)
else:
......
# -*- coding: utf-8 -*-
import logging
from unittest import mock
import shutil
import tempfile
from django.test import TestCase, override_settings
from django.conf import settings
from hexack.utils.logging import get_logger
@mock.patch('os.makedirs', new=mock.Mock())
class LoggingTestCase(TestCase):
def setUp(self):
self.temporary_folder = tempfile.mkdtemp(prefix='hexack-utils-tests')
settings.LOG_DIR = self.temporary_folder
def tearDown(self):
shutil.rmtree(self.temporary_folder)
def test_get_logger(self):
'''
Test logging using our get_logger().
'''
logger = get_logger('test')
# Two handlers have been created.
self.assertEqual(len(logger.handlers), 2)
self.assertEqual(logger.level, logging.INFO)
with self.assertLogs(logger, level=logging.CRITICAL):
......@@ -29,3 +38,13 @@ class LoggingTestCase(TestCase):
'''
logger = get_logger('debug')
self.assertEqual(logger.level, logging.DEBUG)
def test_loggers_not_duplicate(self):
'''
Twice `get_loger` calls with same name may not create duplicates handlers.
'''
logger1 = get_logger('debug')
handlers1 = [id(handler) for handler in logger1.handlers]
logger2 = get_logger('debug')
handlers2 = [id(handler) for handler in logger2.handlers]
self.assertEqual(handlers1, handlers2)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment