From bb5a310aec09fd9c2f961f32a78fa86bb97bb411 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 29 Mar 2019 20:12:44 +0100 Subject: [PATCH 1/4] Add --logfile argument --- freqtrade/arguments.py | 7 +++++++ freqtrade/configuration.py | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/freqtrade/arguments.py b/freqtrade/arguments.py index 604386426..8d7dac4bc 100644 --- a/freqtrade/arguments.py +++ b/freqtrade/arguments.py @@ -71,6 +71,13 @@ class Arguments(object): dest='loglevel', default=0, ) + self.parser.add_argument( + '--logfile', + help='Log to the file specified', + dest='logfile', + type=str, + metavar='FILE' + ) self.parser.add_argument( '--version', action='version', diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index ba7a0e200..adaf7a59b 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -4,7 +4,9 @@ This module contains the configuration class import json import logging import os +import sys from argparse import Namespace +from logging.handlers import RotatingFileHandler from typing import Any, Dict, Optional import ccxt @@ -12,8 +14,8 @@ from jsonschema import Draft4Validator, validate from jsonschema.exceptions import ValidationError, best_match from freqtrade import OperationalException, constants -from freqtrade.state import RunMode from freqtrade.misc import deep_merge_dicts +from freqtrade.state import RunMode logger = logging.getLogger(__name__) @@ -116,9 +118,22 @@ class Configuration(object): config.update({'verbosity': self.args.loglevel}) else: config.update({'verbosity': 0}) + + # Log to stdout, not stderr + log_handlers = [logging.StreamHandler(sys.stdout)] + if 'logfile' in self.args and self.args.logfile: + config.update({'logfile': self.args.logfile}) + + # Allow setting this as either configuration or argument + if 'logfile' in config: + log_handlers.append(RotatingFileHandler(config['logfile'], + maxBytes=1024 * 1024, # 1Mb + backupCount=10)) + logging.basicConfig( level=logging.INFO if config['verbosity'] < 1 else logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + handlers=log_handlers ) set_loggers(config['verbosity']) logger.info('Verbosity set to %s', config['verbosity']) From d4ffdaffc2a19d4a5f54a0b1cee6d00a8534e258 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 29 Mar 2019 20:16:41 +0100 Subject: [PATCH 2/4] Correctly add types --- freqtrade/configuration.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/configuration.py b/freqtrade/configuration.py index adaf7a59b..fdd71f2f5 100644 --- a/freqtrade/configuration.py +++ b/freqtrade/configuration.py @@ -7,7 +7,7 @@ import os import sys from argparse import Namespace from logging.handlers import RotatingFileHandler -from typing import Any, Dict, Optional +from typing import Any, Dict, List, Optional import ccxt from jsonschema import Draft4Validator, validate @@ -120,7 +120,7 @@ class Configuration(object): config.update({'verbosity': 0}) # Log to stdout, not stderr - log_handlers = [logging.StreamHandler(sys.stdout)] + log_handlers: List[logging.Handler] = [logging.StreamHandler(sys.stdout)] if 'logfile' in self.args and self.args.logfile: config.update({'logfile': self.args.logfile}) From e5008fbf9347d5d8234a70afc2f65c1049b695ab Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 29 Mar 2019 20:16:52 +0100 Subject: [PATCH 3/4] Add test for logfile attribute --- freqtrade/tests/test_configuration.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/freqtrade/tests/test_configuration.py b/freqtrade/tests/test_configuration.py index 21547d205..45e539c2f 100644 --- a/freqtrade/tests/test_configuration.py +++ b/freqtrade/tests/test_configuration.py @@ -5,6 +5,7 @@ import logging from argparse import Namespace from copy import deepcopy from unittest.mock import MagicMock +from pathlib import Path import pytest from jsonschema import Draft4Validator, ValidationError, validate @@ -547,6 +548,23 @@ def test_set_loggers() -> None: assert logging.getLogger('telegram').level is logging.INFO +def test_set_logfile(default_conf, mocker): + mocker.patch('freqtrade.configuration.open', + mocker.mock_open(read_data=json.dumps(default_conf))) + + arglist = [ + '--logfile', 'test_file.log', + ] + args = Arguments(arglist, '').get_parsed_arg() + configuration = Configuration(args) + validated_conf = configuration.load_config() + + assert validated_conf['logfile'] == "test_file.log" + f = Path("test_file.log") + assert f.is_file() + f.unlink() + + def test_load_config_warn_forcebuy(default_conf, mocker, caplog) -> None: default_conf['forcebuy_enable'] = True mocker.patch('freqtrade.configuration.open', mocker.mock_open( From 12066411db802e942bd990cb3c461280ed4adb51 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 29 Mar 2019 20:19:40 +0100 Subject: [PATCH 4/4] Update docs with logfile methods --- README.md | 8 +++++--- docs/bot-usage.md | 7 ++++--- docs/configuration.md | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ade62ce94..8f7578561 100644 --- a/README.md +++ b/README.md @@ -68,9 +68,9 @@ For any other type of installation please refer to [Installation doc](https://ww ### Bot commands ``` -usage: freqtrade [-h] [-v] [--version] [-c PATH] [-d PATH] [-s NAME] - [--strategy-path PATH] [--dynamic-whitelist [INT]] - [--db-url PATH] +usage: freqtrade [-h] [-v] [--logfile FILE] [--version] [-c PATH] [-d PATH] + [-s NAME] [--strategy-path PATH] [--dynamic-whitelist [INT]] + [--db-url PATH] [--sd-notify] {backtesting,edge,hyperopt} ... Free, open source crypto trading bot @@ -84,6 +84,7 @@ positional arguments: optional arguments: -h, --help show this help message and exit -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified --version show program's version number and exit -c PATH, --config PATH Specify configuration file (default: None). Multiple @@ -100,6 +101,7 @@ optional arguments: --db-url PATH Override trades database URL, this is useful if dry_run is enabled or in custom deployments (default: None). + --sd-notify Notify systemd service manager. ``` ### Telegram RPC commands diff --git a/docs/bot-usage.md b/docs/bot-usage.md index 35e4a776d..5ec390d5c 100644 --- a/docs/bot-usage.md +++ b/docs/bot-usage.md @@ -6,9 +6,9 @@ This page explains the different parameters of the bot and how to run it. ## Bot commands ``` -usage: freqtrade [-h] [-v] [--version] [-c PATH] [-d PATH] [-s NAME] - [--strategy-path PATH] [--dynamic-whitelist [INT]] - [--db-url PATH] +usage: freqtrade [-h] [-v] [--logfile FILE] [--version] [-c PATH] [-d PATH] + [-s NAME] [--strategy-path PATH] [--dynamic-whitelist [INT]] + [--db-url PATH] [--sd-notify] {backtesting,edge,hyperopt} ... Free, open source crypto trading bot @@ -22,6 +22,7 @@ positional arguments: optional arguments: -h, --help show this help message and exit -v, --verbose Verbose mode (-vv for more, -vvv to get all messages). + --logfile FILE Log to the file specified --version show program's version number and exit -c PATH, --config PATH Specify configuration file (default: None). Multiple diff --git a/docs/configuration.md b/docs/configuration.md index 11b941220..75843ef4a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -70,6 +70,7 @@ Mandatory Parameters are marked as **Required**. | `strategy` | DefaultStrategy | Defines Strategy class to use. | `strategy_path` | null | Adds an additional strategy lookup path (must be a folder). | `internals.process_throttle_secs` | 5 | **Required.** Set the process throttle. Value in second. +| `logfile` | | Specify Logfile. Uses a rolling strategy of 10 files, with 1Mb per file. | `internals.sd_notify` | false | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details. ### Parameters in the strategy