diff --git a/scrapy/utils/log.py b/scrapy/utils/log.py index cc2f0b164..d3fde097c 100644 --- a/scrapy/utils/log.py +++ b/scrapy/utils/log.py @@ -101,12 +101,25 @@ def configure_logging(settings=None, install_root_handler=True): logging.root.addHandler(handler) +def _import_hander(name): + """Return class from dotted name""" + import importlib + module_name, class_name = name.rsplit('.', 1) + module = importlib.import_module(module_name) + return getattr(module, class_name) + + def _get_handler(settings): """ Return a log handler object according to settings """ filename = settings.get('LOG_FILE') if filename: encoding = settings.get('LOG_ENCODING') - handler = logging.FileHandler(filename, encoding=encoding) + handler = settings.get('LOG_HANDLER') + if handler: + Handler = _import_hander(handler) + else: + Handler = logging.FileHandler + handler = Handler(filename, encoding=encoding) elif settings.getbool('LOG_ENABLED'): handler = logging.StreamHandler() else: diff --git a/tests/test_utils_log_handler.py b/tests/test_utils_log_handler.py new file mode 100644 index 000000000..fecb70630 --- /dev/null +++ b/tests/test_utils_log_handler.py @@ -0,0 +1,29 @@ +from logging import FileHandler +from logging.handlers import TimedRotatingFileHandler +from scrapy.utils import log +import unittest + + +class TestCase(unittest.TestCase): + + + def test_import_handler(self): + """Test function: _import_handler""" + name = 'logging.handlers.TimedRotatingFileHandler' + self.assertEqual(log._import_hander(name), TimedRotatingFileHandler) + + def test_get_handler(self): + """Test function: _get_handler with LOG_FILE""" + # First create log file path + import os + import tempfile + file_path = tempfile.mkstemp()[1] + settings = {'LOG_FILE': file_path, 'LOG_ENCODIUNG': 'utf-8', 'LOG_LEVEL': 'DEBUG'} + handler = log._get_handler(settings) + self.assertIsInstance(handler, FileHandler) + # Adding LOG_HANDLER to settings should update the handler + settings['LOG_HANDLER'] = 'logging.handlers.TimedRotatingFileHandler' + handler = log._get_handler(settings) + self.assertIsInstance(handler, TimedRotatingFileHandler) + # Remove log file + os.remove(file_path)