From c379d034ccb4539ebdb67a4014d612a94c3f2ead Mon Sep 17 00:00:00 2001 From: David Brown Date: Thu, 17 Oct 2024 10:06:36 +0000 Subject: [PATCH] feat(run): Added labgrid INFO and Step logging --- labgrid/run/run.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/labgrid/run/run.py b/labgrid/run/run.py index 831ae8e9..78ccee71 100644 --- a/labgrid/run/run.py +++ b/labgrid/run/run.py @@ -2,6 +2,7 @@ from __future__ import annotations from typing import Any +import logging from argparse import REMAINDER, Action, ArgumentParser, ArgumentTypeError, Namespace from dataclasses import dataclass, replace from os import environ, linesep, getenv @@ -27,9 +28,12 @@ from python.runfiles import Runfiles from bazel.labgrid.strategy import transition from bazel.labgrid.util.target import TemporaryDirectory from labgrid import Environment +from labgrid.logging import basicConfig, StepLogger from labgrid.driver.exception import ExecutionError T = TypeVar("T") +logger = logging.getLogger(__name__) +LOG_DEFAULT = logging.ERROR class RunfileNotFoundError(FileNotFoundError): @@ -118,6 +122,27 @@ class StateAction(Action): setattr(namespace, self.dest, state) +class LogLevelAction(Action): + def __call__( + self, + parser: ArgumentParser, + namespace: Namespace, + values: Union[str, Sequence[Any], None], + option_string: Optional[Text] = None, + ) -> None: + assert isinstance(values, str) + setattr(namespace, self.dest, LogLevelAction.coerce(values)) + + def coerce(value: str) -> int: + # The Logging module converts strings to level integers with this (unintuitively named) function + log_level = logging.getLevelName(value) + if isinstance(log_level, str): + # getLevelName will return a string if the level was not recognised + raise ArgumentTypeError(f"Unsupported verbosity envvar: '{value}'") + + return log_level + + def env(arg: str) -> str: key, sep, value = arg.partition("=") if not sep: @@ -189,6 +214,15 @@ def arguments(prsr: ArgumentParser) -> None: action="append", default=[], ) + prsr.add_argument( + "--log-level", + action=LogLevelAction, + help=f"Verbosity level of logging. Uses standard python logging levels (e.g. WARNING, INFO, DEBUG), the default is {logging.getLevelName(LOG_DEFAULT)}. Can also be set with LOG_LEVEL environment variable", + default=LogLevelAction.coerce( + environ.get("LOG_LEVEL", logging.getLevelName(LOG_DEFAULT)) + ), + dest="log_level", + ) def get(value: str) -> Get: @@ -232,6 +266,7 @@ def run( state: State, get: Iterator[Get], env: Iterator[str], + log_level: int, tools: Tools = Tools(), ) -> int: runfiles_dir = None @@ -242,6 +277,12 @@ def run( del environ["RUNFILES_DIR"] except KeyError: pass + + # Activating the StepLogger requires a DEBUG level of verbosity + basicConfig(level=log_level) + if log_level <= logging.DEBUG: + StepLogger.start() + # Start up Docker container with LabGrid target = Environment(str(config)).get_target() strategy = target.get_driver("Strategy") @@ -310,6 +351,7 @@ def main(exe: Path, *args: str) -> int: config=parsed.config, get=parsed.get, env=parsed.env, + log_level=parsed.log_level, ) except CalledProcessError as e: print(f"fatal: subprocess failed: {e}", file=stderr) -- GitLab