Merge pull request #1045 from freqtrade/xmatt_verbosity

Add more verbosity levels
This commit is contained in:
Janne Sinivirta 2018-07-19 08:11:32 +03:00 committed by GitHub
commit aaa58a956d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 47 deletions

View File

@ -3,7 +3,6 @@ This module contains the argument manager class
""" """
import argparse import argparse
import logging
import os import os
import re import re
from typing import List, NamedTuple, Optional from typing import List, NamedTuple, Optional
@ -64,11 +63,10 @@ class Arguments(object):
""" """
self.parser.add_argument( self.parser.add_argument(
'-v', '--verbose', '-v', '--verbose',
help='be verbose', help='verbose mode (-vv for more, -vvv to get all messages)',
action='store_const', action='count',
dest='loglevel', dest='loglevel',
const=logging.DEBUG, default=0,
default=logging.INFO,
) )
self.parser.add_argument( self.parser.add_argument(
'--version', '--version',

View File

@ -12,10 +12,22 @@ from jsonschema import Draft4Validator, validate
from jsonschema.exceptions import ValidationError, best_match from jsonschema.exceptions import ValidationError, best_match
from freqtrade import OperationalException, constants from freqtrade import OperationalException, constants
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def set_loggers(log_level: int = 0) -> None:
"""
Set the logger level for Third party libs
:return: None
"""
logging.getLogger('requests').setLevel(logging.INFO if log_level <= 1 else logging.DEBUG)
logging.getLogger("urllib3").setLevel(logging.INFO if log_level <= 1 else logging.DEBUG)
logging.getLogger('ccxt.base.exchange').setLevel(
logging.INFO if log_level <= 2 else logging.DEBUG)
logging.getLogger('telegram').setLevel(logging.INFO)
class Configuration(object): class Configuration(object):
""" """
Class to read and init the bot configuration Class to read and init the bot configuration
@ -81,9 +93,10 @@ class Configuration(object):
if 'loglevel' in self.args and self.args.loglevel: if 'loglevel' in self.args and self.args.loglevel:
config.update({'loglevel': self.args.loglevel}) config.update({'loglevel': self.args.loglevel})
logging.basicConfig( logging.basicConfig(
level=config['loglevel'], level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
) )
set_loggers(config['loglevel'])
logger.info('Log level set to %s', logging.getLevelName(config['loglevel'])) logger.info('Log level set to %s', logging.getLevelName(config['loglevel']))
# Add dynamic_whitelist if found # Add dynamic_whitelist if found

View File

@ -10,7 +10,7 @@ from typing import List
from freqtrade import OperationalException from freqtrade import OperationalException
from freqtrade.arguments import Arguments from freqtrade.arguments import Arguments
from freqtrade.configuration import Configuration from freqtrade.configuration import Configuration, set_loggers
from freqtrade.freqtradebot import FreqtradeBot from freqtrade.freqtradebot import FreqtradeBot
from freqtrade.state import State from freqtrade.state import State
from freqtrade.rpc import RPCMessageType from freqtrade.rpc import RPCMessageType
@ -84,16 +84,6 @@ def reconfigure(freqtrade: FreqtradeBot, args: Namespace) -> FreqtradeBot:
return freqtrade return freqtrade
def set_loggers() -> None:
"""
Set the logger level for Third party libs
:return: None
"""
logging.getLogger('requests.packages.urllib3').setLevel(logging.INFO)
logging.getLogger('ccxt.base.exchange').setLevel(logging.INFO)
logging.getLogger('telegram').setLevel(logging.INFO)
if __name__ == '__main__': if __name__ == '__main__':
set_loggers() set_loggers()
main(sys.argv[1:]) main(sys.argv[1:])

View File

@ -5,7 +5,6 @@ Unit test file for arguments.py
""" """
import argparse import argparse
import logging
import pytest import pytest
@ -35,7 +34,7 @@ def test_parse_args_defaults() -> None:
args = Arguments([], '').get_parsed_arg() args = Arguments([], '').get_parsed_arg()
assert args.config == 'config.json' assert args.config == 'config.json'
assert args.dynamic_whitelist is None assert args.dynamic_whitelist is None
assert args.loglevel == logging.INFO assert args.loglevel == 0
def test_parse_args_config() -> None: def test_parse_args_config() -> None:
@ -53,10 +52,10 @@ def test_parse_args_db_url() -> None:
def test_parse_args_verbose() -> None: def test_parse_args_verbose() -> None:
args = Arguments(['-v'], '').get_parsed_arg() args = Arguments(['-v'], '').get_parsed_arg()
assert args.loglevel == logging.DEBUG assert args.loglevel == 1
args = Arguments(['--verbose'], '').get_parsed_arg() args = Arguments(['--verbose'], '').get_parsed_arg()
assert args.loglevel == logging.DEBUG assert args.loglevel == 1
def test_scripts_options() -> None: def test_scripts_options() -> None:
@ -153,7 +152,7 @@ def test_parse_args_backtesting_custom() -> None:
call_args = Arguments(args, '').get_parsed_arg() call_args = Arguments(args, '').get_parsed_arg()
assert call_args.config == 'test_conf.json' assert call_args.config == 'test_conf.json'
assert call_args.live is True assert call_args.live is True
assert call_args.loglevel == logging.INFO assert call_args.loglevel == 0
assert call_args.subparser == 'backtesting' assert call_args.subparser == 'backtesting'
assert call_args.func is not None assert call_args.func is not None
assert call_args.ticker_interval == '1m' assert call_args.ticker_interval == '1m'
@ -170,7 +169,7 @@ def test_parse_args_hyperopt_custom() -> None:
call_args = Arguments(args, '').get_parsed_arg() call_args = Arguments(args, '').get_parsed_arg()
assert call_args.config == 'test_conf.json' assert call_args.config == 'test_conf.json'
assert call_args.epochs == 20 assert call_args.epochs == 20
assert call_args.loglevel == logging.INFO assert call_args.loglevel == 0
assert call_args.subparser == 'hyperopt' assert call_args.subparser == 'hyperopt'
assert call_args.spaces == ['buy'] assert call_args.spaces == ['buy']
assert call_args.func is not None assert call_args.func is not None

View File

@ -6,6 +6,7 @@ Unit test file for configuration.py
import json import json
from argparse import Namespace from argparse import Namespace
from copy import deepcopy from copy import deepcopy
import logging
from unittest.mock import MagicMock from unittest.mock import MagicMock
import pytest import pytest
@ -13,7 +14,7 @@ from jsonschema import ValidationError
from freqtrade import OperationalException from freqtrade import OperationalException
from freqtrade.arguments import Arguments from freqtrade.arguments import Arguments
from freqtrade.configuration import Configuration from freqtrade.configuration import Configuration, set_loggers
from freqtrade.constants import DEFAULT_DB_DRYRUN_URL, DEFAULT_DB_PROD_URL from freqtrade.constants import DEFAULT_DB_DRYRUN_URL, DEFAULT_DB_PROD_URL
from freqtrade.tests.conftest import log_has from freqtrade.tests.conftest import log_has
@ -402,3 +403,57 @@ def test_check_exchange(default_conf) -> None:
match=r'.*Exchange "unknown_exchange" not supported.*' match=r'.*Exchange "unknown_exchange" not supported.*'
): ):
configuration.check_exchange(conf) configuration.check_exchange(conf)
def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None:
"""
Test Configuration.load_config() with cli params used
"""
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
read_data=json.dumps(default_conf)))
# Prevent setting loggers
mocker.patch('freqtrade.configuration.set_loggers', MagicMock)
arglist = ['-vvv']
args = Arguments(arglist, '').get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
assert validated_conf.get('loglevel') == 3
assert log_has('Log level set to Level 3', caplog.record_tuples)
def test_set_loggers() -> None:
"""
Test set_loggers() update the logger level for third-party libraries
"""
previous_value1 = logging.getLogger('requests').level
previous_value2 = logging.getLogger('ccxt.base.exchange').level
previous_value3 = logging.getLogger('telegram').level
set_loggers()
value1 = logging.getLogger('requests').level
assert previous_value1 is not value1
assert value1 is logging.INFO
value2 = logging.getLogger('ccxt.base.exchange').level
assert previous_value2 is not value2
assert value2 is logging.INFO
value3 = logging.getLogger('telegram').level
assert previous_value3 is not value3
assert value3 is logging.INFO
set_loggers(log_level=2)
assert logging.getLogger('requests').level is logging.DEBUG
assert logging.getLogger('ccxt.base.exchange').level is logging.INFO
assert logging.getLogger('telegram').level is logging.INFO
set_loggers(log_level=3)
assert logging.getLogger('requests').level is logging.DEBUG
assert logging.getLogger('ccxt.base.exchange').level is logging.DEBUG
assert logging.getLogger('telegram').level is logging.INFO

View File

@ -2,7 +2,6 @@
Unit test file for main.py Unit test file for main.py
""" """
import logging
from copy import deepcopy from copy import deepcopy
from unittest.mock import MagicMock from unittest.mock import MagicMock
@ -11,7 +10,7 @@ import pytest
from freqtrade import OperationalException from freqtrade import OperationalException
from freqtrade.arguments import Arguments from freqtrade.arguments import Arguments
from freqtrade.freqtradebot import FreqtradeBot from freqtrade.freqtradebot import FreqtradeBot
from freqtrade.main import main, reconfigure, set_loggers from freqtrade.main import main, reconfigure
from freqtrade.state import State from freqtrade.state import State
from freqtrade.tests.conftest import log_has, patch_exchange from freqtrade.tests.conftest import log_has, patch_exchange
@ -27,7 +26,7 @@ def test_parse_args_backtesting(mocker) -> None:
call_args = backtesting_mock.call_args[0][0] call_args = backtesting_mock.call_args[0][0]
assert call_args.config == 'config.json' assert call_args.config == 'config.json'
assert call_args.live is False assert call_args.live is False
assert call_args.loglevel == 20 assert call_args.loglevel == 0
assert call_args.subparser == 'backtesting' assert call_args.subparser == 'backtesting'
assert call_args.func is not None assert call_args.func is not None
assert call_args.ticker_interval is None assert call_args.ticker_interval is None
@ -42,29 +41,11 @@ def test_main_start_hyperopt(mocker) -> None:
assert hyperopt_mock.call_count == 1 assert hyperopt_mock.call_count == 1
call_args = hyperopt_mock.call_args[0][0] call_args = hyperopt_mock.call_args[0][0]
assert call_args.config == 'config.json' assert call_args.config == 'config.json'
assert call_args.loglevel == 20 assert call_args.loglevel == 0
assert call_args.subparser == 'hyperopt' assert call_args.subparser == 'hyperopt'
assert call_args.func is not None assert call_args.func is not None
def test_set_loggers() -> None:
"""
Test set_loggers() update the logger level for third-party libraries
"""
previous_value1 = logging.getLogger('requests.packages.urllib3').level
previous_value2 = logging.getLogger('telegram').level
set_loggers()
value1 = logging.getLogger('requests.packages.urllib3').level
assert previous_value1 is not value1
assert value1 is logging.INFO
value2 = logging.getLogger('telegram').level
assert previous_value2 is not value2
assert value2 is logging.INFO
def test_main_fatal_exception(mocker, default_conf, caplog) -> None: def test_main_fatal_exception(mocker, default_conf, caplog) -> None:
""" """
Test main() function Test main() function