From 99b67348b206a75556d35f3994ec293b3d543dac Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Nov 2020 14:30:58 +0100 Subject: [PATCH 1/4] Add test for double-logging --- tests/test_configuration.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 9594b6413..47d393860 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -678,6 +678,9 @@ def test_set_loggers_syslog(mocker): assert [x for x in logger.handlers if type(x) == logging.handlers.SysLogHandler] assert [x for x in logger.handlers if type(x) == logging.StreamHandler] assert [x for x in logger.handlers if type(x) == logging.handlers.BufferingHandler] + # setting up logging again should NOT cause the loggers to be added a second time. + setup_logging(config) + assert len(logger.handlers) == 3 # reset handlers to not break pytest logger.handlers = orig_handlers From 0104c9fde68601e694969006029cd1b17e8c015c Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Nov 2020 14:31:34 +0100 Subject: [PATCH 2/4] Fix double logging --- freqtrade/loggers.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/freqtrade/loggers.py b/freqtrade/loggers.py index 169cd2610..fbb05d879 100644 --- a/freqtrade/loggers.py +++ b/freqtrade/loggers.py @@ -37,6 +37,13 @@ def _set_loggers(verbosity: int = 0, api_verbosity: str = 'info') -> None: ) +def get_existing_handlers(handlertype): + """ + Returns Existing handler or None (if the handler has not yet been added to the root handlers). + """ + return next((h for h in logging.root.handlers if isinstance(h, handlertype)), None) + + def setup_logging_pre() -> None: """ Early setup for logging. @@ -71,18 +78,24 @@ def setup_logging(config: Dict[str, Any]) -> None: # config['logfilename']), which defaults to '/dev/log', applicable for most # of the systems. address = (s[1], int(s[2])) if len(s) > 2 else s[1] if len(s) > 1 else '/dev/log' - handler = SysLogHandler(address=address) + handler_sl = get_existing_handlers(SysLogHandler) + if handler_sl: + logging.root.removeHandler(handler_sl) + handler_sl = SysLogHandler(address=address) # No datetime field for logging into syslog, to allow syslog # to perform reduction of repeating messages if this is set in the # syslog config. The messages should be equal for this. - handler.setFormatter(Formatter('%(name)s - %(levelname)s - %(message)s')) - logging.root.addHandler(handler) + handler_sl.setFormatter(Formatter('%(name)s - %(levelname)s - %(message)s')) + logging.root.addHandler(handler_sl) elif s[0] == 'journald': try: from systemd.journal import JournaldLogHandler except ImportError: raise OperationalException("You need the systemd python package be installed in " "order to use logging to journald.") + handler_jd = get_existing_handlers(JournaldLogHandler) + if handler_jd: + logging.root.removeHandler(handler_jd) handler_jd = JournaldLogHandler() # No datetime field for logging into journald, to allow syslog # to perform reduction of repeating messages if this is set in the @@ -90,6 +103,9 @@ def setup_logging(config: Dict[str, Any]) -> None: handler_jd.setFormatter(Formatter('%(name)s - %(levelname)s - %(message)s')) logging.root.addHandler(handler_jd) else: + handler_rf = get_existing_handlers(RotatingFileHandler) + if handler_rf: + logging.root.removeHandler(handler_rf) handler_rf = RotatingFileHandler(logfile, maxBytes=1024 * 1024 * 10, # 10Mb backupCount=10) From b9980330a5469aa99160c8e40815a0c8707e0482 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Nov 2020 14:53:25 +0100 Subject: [PATCH 3/4] Add explicit test for FileHandler --- tests/test_configuration.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 47d393860..3501f1f3d 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -663,7 +663,7 @@ def test_set_loggers() -> None: @pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows") -def test_set_loggers_syslog(mocker): +def test_set_loggers_syslog(): logger = logging.getLogger() orig_handlers = logger.handlers logger.handlers = [] @@ -685,6 +685,30 @@ def test_set_loggers_syslog(mocker): logger.handlers = orig_handlers +def test_set_loggers_Filehandler(tmpdir): + logger = logging.getLogger() + orig_handlers = logger.handlers + logger.handlers = [] + logfile = Path(tmpdir) / 'ft_logfile.log' + config = {'verbosity': 2, + 'logfile': str(logfile), + } + + setup_logging_pre() + setup_logging(config) + assert len(logger.handlers) == 3 + assert [x for x in logger.handlers if type(x) == logging.handlers.RotatingFileHandler] + assert [x for x in logger.handlers if type(x) == logging.StreamHandler] + assert [x for x in logger.handlers if type(x) == logging.handlers.BufferingHandler] + # setting up logging again should NOT cause the loggers to be added a second time. + setup_logging(config) + assert len(logger.handlers) == 3 + # reset handlers to not break pytest + if logfile.exists: + logfile.unlink() + logger.handlers = orig_handlers + + @pytest.mark.skip(reason="systemd is not installed on every system, so we're not testing this.") def test_set_loggers_journald(mocker): logger = logging.getLogger() From 46389e343bc0314427823023604c55bf212686e2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 25 Nov 2020 15:10:17 +0100 Subject: [PATCH 4/4] Skip filehandler test on windows - as that causes a permission-error --- tests/test_configuration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 3501f1f3d..e6c91a96e 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -685,6 +685,7 @@ def test_set_loggers_syslog(): logger.handlers = orig_handlers +@pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows") def test_set_loggers_Filehandler(tmpdir): logger = logging.getLogger() orig_handlers = logger.handlers