diff --git a/freqtrade/loggers/__init__.py b/freqtrade/loggers/__init__.py index 1cc0590a1..7e18d3cba 100644 --- a/freqtrade/loggers/__init__.py +++ b/freqtrade/loggers/__init__.py @@ -1,6 +1,7 @@ import logging from logging import Formatter from logging.handlers import RotatingFileHandler, SysLogHandler +from pathlib import Path from freqtrade.constants import Config from freqtrade.exceptions import OperationalException @@ -86,11 +87,23 @@ def setup_logging(config: Config) -> None: 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, - ) + try: + logfile_path = Path(logfile) + logfile_path.parent.mkdir(parents=True, exist_ok=True) + handler_rf = RotatingFileHandler( + logfile_path, + maxBytes=1024 * 1024 * 10, # 10Mb + backupCount=10, + ) + except PermissionError: + raise OperationalException( + f'Failed to create or access log file "{logfile_path.absolute()}". ' + "Please make sure you have the write permission to the log file or its parent " + "directories. If you're running freqtrade using docker, you see this error " + "message probably because you've logged in as the root user, please switch to " + "non-root user, delete and recreate the directories you need, and then try " + "again." + ) handler_rf.setFormatter(Formatter(LOGFORMAT)) logging.root.addHandler(handler_rf) diff --git a/tests/test_log_setup.py b/tests/test_log_setup.py index 142134b34..6dc88b79d 100644 --- a/tests/test_log_setup.py +++ b/tests/test_log_setup.py @@ -86,7 +86,7 @@ def test_set_loggers_Filehandler(tmp_path): logger = logging.getLogger() orig_handlers = logger.handlers logger.handlers = [] - logfile = tmp_path / "ft_logfile.log" + logfile = tmp_path / "logs/ft_logfile.log" config = { "verbosity": 2, "logfile": str(logfile), @@ -107,6 +107,29 @@ def test_set_loggers_Filehandler(tmp_path): logger.handlers = orig_handlers +@pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows") +def test_set_loggers_Filehandler_without_permission(tmp_path): + logger = logging.getLogger() + orig_handlers = logger.handlers + logger.handlers = [] + + try: + tmp_path.chmod(0o400) + logfile = tmp_path / "logs/ft_logfile.log" + config = { + "verbosity": 2, + "logfile": str(logfile), + } + + setup_logging_pre() + with pytest.raises(OperationalException): + setup_logging(config) + + logger.handlers = orig_handlers + finally: + tmp_path.chmod(0o700) + + @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()