diff --git a/src/e3/log.py b/src/e3/log.py index d67f60fb..d72b44a5 100644 --- a/src/e3/log.py +++ b/src/e3/log.py @@ -4,6 +4,7 @@ from dataclasses import dataclass import logging +import os import re import sys import time @@ -30,6 +31,7 @@ Mapping, ) from logging import _ExcInfoType + from argparse import ArgumentParser, _ArgumentGroup, Namespace T = TypeVar("T") @@ -308,6 +310,95 @@ def add_log_handlers( logging.getLogger("").addHandler(handler) +def add_logging_argument_group( + argument_parser: ArgumentParser, default_level: int = logging.WARNING, +) -> _ArgumentGroup: + """Add an argument group with logging options to the argument parser. + + To be used with `e3.log.activate_with_args`. + + :param argument_parser: the parser in which the group will be created + :param default_level: the logging level that will be used by default + """ + log_group = argument_parser.add_argument_group(title="logging arguments") + log_group.add_argument( + "-v", + "--verbose", + action="count", + default=0, + help="make the log output to the console more verbose", + ) + log_group.add_argument( + "--log-file", + metavar="FILE", + default=None, + help="store all the logs into the specified file", + ) + log_group.add_argument( + "--loglevel", + default=default_level, + help="set the console log level", + choices={ + "DEBUG": logging.DEBUG, + "INFO": logging.INFO, + "WARNING": logging.WARNING, + "ERROR": logging.ERROR, + "CRITICAL": logging.CRITICAL, + }, + ) + log_group.add_argument( + "--nocolor", + default=False, + action="store_true", + help="disable color and progress bars", + ) + log_group.add_argument( + "--json-logs", + default="json-logs" in os.environ.get("E3_ENABLE_FEATURE", "").split(","), + action="store_true", + help="enable JSON formatted logs. They can be activated as well by" + " setting the env var E3_ENABLE_FEATURE=json-logs.", + ) + log_group.add_argument( + "--console-logs", + metavar="LINE_PREFIX", + help="disable color, progress bars, and redirect as much as" + " possible to stdout, starting lines with the given prefix.", + ) + + return log_group + + +def activate_with_args(args: Namespace, default_level: int = logging.WARNING) -> None: + """Activate the e3 log using argument parsed. + + To be used with `e3.log.add_logging_argument_group`. + + :param args: the result of parsing arguments + :param default_level: the logging level assumed by default + """ + global console_logs + global pretty_cli + + if args.verbose > 0: + level = default_level - 10 * args.verbose + else: + level = args.loglevel + + if args.console_logs: + console_logs = args.console_logs + + if args.nocolor: + pretty_cli = False + + activate( + level=level, + filename=args.log_file, + json_format=args.json_logs, + e3_debug=level == logging.DEBUG, + ) + + def activate( stream_format: str = log_config.stream_fmt, file_format: str = log_config.file_fmt, diff --git a/src/e3/main.py b/src/e3/main.py index cb4575da..b76b4659 100644 --- a/src/e3/main.py +++ b/src/e3/main.py @@ -81,54 +81,10 @@ def __init__( if argument_parser is None: argument_parser = ArgumentParser() - log_group = argument_parser.add_argument_group(title="Logging arguments") - log_group.add_argument( - "-v", - "--verbose", - action="count", - default=0, - help="make the log outputted on the console more verbose (this " - "sets the log level to DEBUG)", - ) - log_group.add_argument( - "--log-file", - metavar="FILE", - default=None, - help="store all the logs into the specified file", - ) - log_group.add_argument( - "--loglevel", - default=logging.INFO, - help="set the console log level", - choices={ - "DEBUG": logging.DEBUG, - "INFO": logging.INFO, - "ERROR": logging.ERROR, - "CRITICAL": logging.CRITICAL, - }, - ) - log_group.add_argument( - "--nocolor", - default=False, - action="store_true", - help="disable color and progress bars", - ) - log_group.add_argument( - "--json-logs", - default="json-logs" in os.environ.get("E3_ENABLE_FEATURE", "").split(","), - action="store_true", - help="enable JSON formatted logs. They can be activated as well by" - " setting the env var E3_ENABLE_FEATURE=json-logs.", - ) - log_group.add_argument( - "--console-logs", - metavar="LINE_PREFIX", - help="disable color, progress bars, and redirect as much as" - " possible to stdout, starting lines with the given prefix.", - ) + e3.log.add_logging_argument_group(argument_parser, default_level=logging.INFO) if platform_args: - plat_group = argument_parser.add_argument_group(title="Platform arguments") + plat_group = argument_parser.add_argument_group(title="platform arguments") plat_group.add_argument( "--build", default=None, # to force autodetection @@ -193,25 +149,8 @@ def parse_args( else: self.args = self.argument_parser.parse_args(args) - if self.args.nocolor: - e3.log.pretty_cli = False - if not self.__log_handlers_set: - # First set level of verbosity - if self.args.verbose: - level = logging.DEBUG - else: - level = self.args.loglevel - - if self.args.console_logs: - e3.log.console_logs = self.args.console_logs - - e3.log.activate( - level=level, - filename=self.args.log_file, - json_format=self.args.json_logs, - e3_debug=self.args.verbose > 1, - ) + e3.log.activate_with_args(self.args, logging.INFO) self.__log_handlers_set = True # Export options to env diff --git a/tests/tests_e3/main/main_test.py b/tests/tests_e3/main/main_test.py index 7a33974a..312d1cf2 100644 --- a/tests/tests_e3/main/main_test.py +++ b/tests/tests_e3/main/main_test.py @@ -79,6 +79,7 @@ def test_mainprog_with_console_logs(): r"^mymain:.*:.*: DEBUG this is an info line\r?\n" "mymain:.*:.* DEBUG this is a debug line", p.out, + re.MULTILINE, )