From 3885f148cb62d9af33e9228790fac6e5fb2364f1 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 14:28:02 -0700 Subject: [PATCH 01/20] add wip logging.py --- eng/tools/azure-sdk-tools/azpysdk/main.py | 17 +++++++++ eng/tools/azure-sdk-tools/ci_tools/logging.py | 37 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 eng/tools/azure-sdk-tools/ci_tools/logging.py diff --git a/eng/tools/azure-sdk-tools/azpysdk/main.py b/eng/tools/azure-sdk-tools/azpysdk/main.py index 59f830c205ee..04a55e0749c6 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/main.py +++ b/eng/tools/azure-sdk-tools/azpysdk/main.py @@ -20,6 +20,7 @@ from ci_tools.scenario import install_into_venv, get_venv_python from ci_tools.functions import get_venv_call from ci_tools.variables import discover_repo_root +from ci_tools.logging import logger, configure_logging # right now, we are assuming you HAVE to be in the azure-sdk-tools repo # we assume this because we don't know how a dev has installed this package, and might be @@ -103,6 +104,22 @@ def main(argv: Optional[Sequence[str]] = None) -> int:# parser = build_parser() args = parser.parse_args(argv) + # parse logging args TODO ? + log_parser = argparse.ArgumentParser() + log_parser.add_argument( + "--quiet", + action="store_true", + default=False, + help="Enable quiet mode (only shows ERROR logs)" + ) + log_parser.add_argument( + "--verbose", + action="store_true", + default=False, + help="Enable verbose mode (shows DEBUG logs)" + ) + + if not hasattr(args, "func"): parser.print_help() return 1 diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging.py b/eng/tools/azure-sdk-tools/ci_tools/logging.py new file mode 100644 index 000000000000..d075a6654e30 --- /dev/null +++ b/eng/tools/azure-sdk-tools/ci_tools/logging.py @@ -0,0 +1,37 @@ +import logging +import argparse +import os + +logger = logging.getLogger("azure-sdk-tools") + +def configure_logging( + level: str = "INFO", + fmt: str = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" +) -> None: + """ + Configures the shared logger. Should be called **once** at startup. + """ + + numeric_level = getattr(logging, level.upper(), None) + + # parse cli arg, and compare to numeric level? + parser = argparse.ArgumentParser() + parser.add_argument("--quiet", default=False, help="Enable quiet mode (only shows ERROR logs)") + parser.add_argument("--verbose", default=False, help="Enable verbose mode (shows DEBUG logs)") + parser.add_argument("--log-level", default="INFO", help="Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)") + + args = parser.parse_args() + if args.log_level: + numeric_level = getattr(logging, args.log_level.upper(), None) + + # parse LOG_LEVEL environment variable + log_level_env = os.getenv("LOG_LEVEL") + if log_level_env: + numeric_level = getattr(logging, log_level_env.upper(), None) + + if not isinstance(numeric_level, int): + raise ValueError(f"Invalid log level: {level}") + logger.setLevel(numeric_level) + + # Propagate logger config globally if needed + logging.basicConfig(level=numeric_level, format=fmt) From 8ebc3ad77100cd89aabe0fc2d5a69520e0a190d1 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 14:51:50 -0700 Subject: [PATCH 02/20] pass args to logging --- eng/tools/azure-sdk-tools/azpysdk/main.py | 35 +++++++++++-------- eng/tools/azure-sdk-tools/ci_tools/logging.py | 17 ++++----- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/eng/tools/azure-sdk-tools/azpysdk/main.py b/eng/tools/azure-sdk-tools/azpysdk/main.py index 04a55e0749c6..2d33adb96d49 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/main.py +++ b/eng/tools/azure-sdk-tools/azpysdk/main.py @@ -39,6 +39,25 @@ def build_parser() -> argparse.ArgumentParser: # global flag: allow --isolate to appear before the subcommand as well parser.add_argument("--isolate", action="store_true", default=False, help="If set, run in an isolated virtual environment.") + # logging level info + parser.add_argument( + "--quiet", + action="store_true", + default=False, + help="Enable quiet mode (only shows ERROR logs)" + ) + parser.add_argument( + "--verbose", + action="store_true", + default=False, + help="Enable verbose mode (shows DEBUG logs)" + ) + parser.add_argument( + "--log-level", + default="INFO", + choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], + help="Set the logging level." + ) common = argparse.ArgumentParser(add_help=False) common.add_argument( @@ -104,21 +123,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:# parser = build_parser() args = parser.parse_args(argv) - # parse logging args TODO ? - log_parser = argparse.ArgumentParser() - log_parser.add_argument( - "--quiet", - action="store_true", - default=False, - help="Enable quiet mode (only shows ERROR logs)" - ) - log_parser.add_argument( - "--verbose", - action="store_true", - default=False, - help="Enable verbose mode (shows DEBUG logs)" - ) - + configure_logging(args, args.log_level) if not hasattr(args, "func"): parser.print_help() diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging.py b/eng/tools/azure-sdk-tools/ci_tools/logging.py index d075a6654e30..7cf49f1afd42 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/logging.py +++ b/eng/tools/azure-sdk-tools/ci_tools/logging.py @@ -5,6 +5,7 @@ logger = logging.getLogger("azure-sdk-tools") def configure_logging( + args: argparse.Namespace, level: str = "INFO", fmt: str = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" ) -> None: @@ -14,19 +15,15 @@ def configure_logging( numeric_level = getattr(logging, level.upper(), None) - # parse cli arg, and compare to numeric level? - parser = argparse.ArgumentParser() - parser.add_argument("--quiet", default=False, help="Enable quiet mode (only shows ERROR logs)") - parser.add_argument("--verbose", default=False, help="Enable verbose mode (shows DEBUG logs)") - parser.add_argument("--log-level", default="INFO", help="Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)") - - args = parser.parse_args() - if args.log_level: - numeric_level = getattr(logging, args.log_level.upper(), None) + # parse cli arg + if args.quiet: + numeric_level = logging.ERROR + elif args.verbose: + numeric_level = logging.DEBUG # parse LOG_LEVEL environment variable log_level_env = os.getenv("LOG_LEVEL") - if log_level_env: + if not args.log_level and log_level_env: numeric_level = getattr(logging, log_level_env.upper(), None) if not isinstance(numeric_level, int): From a795ed81f98c8bb1c751b0b012230e1069cbda32 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:02:27 -0700 Subject: [PATCH 03/20] use logger in mypy, move logger to logging/init --- .../azure-sdk-tools/azpysdk/import_all.py | 2 +- eng/tools/azure-sdk-tools/azpysdk/mypy.py | 18 +++++----- eng/tools/azure-sdk-tools/ci_tools/logging.py | 34 ------------------- .../ci_tools/logging/__init__.py | 32 +++++++++++++++++ 4 files changed, 41 insertions(+), 45 deletions(-) delete mode 100644 eng/tools/azure-sdk-tools/ci_tools/logging.py diff --git a/eng/tools/azure-sdk-tools/azpysdk/import_all.py b/eng/tools/azure-sdk-tools/azpysdk/import_all.py index 0dd4ea27cefd..a9b86d07193c 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/import_all.py +++ b/eng/tools/azure-sdk-tools/azpysdk/import_all.py @@ -1,7 +1,6 @@ import argparse import os import sys -import logging import tempfile from typing import Optional,List @@ -11,6 +10,7 @@ from ci_tools.parsing import ParsedSetup from ci_tools.functions import discover_targeted_packages from ci_tools.scenario.generation import create_package_and_install +from ci_tools.logging import logger # keyvault has dependency issue when loading private module _BearerTokenCredentialPolicyBase from azure.core.pipeline.policies # azure.core.tracing.opencensus and azure.eventhub.checkpointstoreblob.aio are skipped due to a known issue in loading azure.core.tracing.opencensus diff --git a/eng/tools/azure-sdk-tools/azpysdk/mypy.py b/eng/tools/azure-sdk-tools/azpysdk/mypy.py index 7d0e0ae4256c..2682ab87c521 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/mypy.py +++ b/eng/tools/azure-sdk-tools/azpysdk/mypy.py @@ -1,7 +1,6 @@ import argparse import os import sys -import logging import tempfile from typing import Optional, List @@ -15,8 +14,7 @@ from ci_tools.environment_exclusions import ( is_check_enabled, is_typing_ignored ) - -logging.getLogger().setLevel(logging.INFO) +from ci_tools.logging import logger PYTHON_VERSION = "3.9" MYPY_VERSION = "1.14.1" @@ -77,11 +75,11 @@ def run(self, args: argparse.Namespace) -> int: print("Failed to install mypy:", e) return e.returncode - logging.info(f"Running mypy against {package_name}") + logger.info(f"Running mypy against {package_name}") if not args.next and in_ci(): if not is_check_enabled(package_dir, "mypy", True) or is_typing_ignored(package_name): - logging.info( + logger.info( f"Package {package_name} opts-out of mypy check. See https://aka.ms/python/typing-guide for information." ) continue @@ -101,17 +99,17 @@ def run(self, args: argparse.Namespace) -> int: src_code_error = None sample_code_error = None try: - logging.info( + logger.info( f"Running mypy commands on src code: {src_code}" ) results.append(check_call(src_code)) - logging.info("Verified mypy, no issues found") + logger.info("Verified mypy, no issues found") except CalledProcessError as src_error: src_code_error = src_error results.append(src_error.returncode) if not args.next and in_ci() and not is_check_enabled(package_dir, "type_check_samples", True): - logging.info( + logger.info( f"Package {package_name} opts-out of mypy check on samples." ) continue @@ -120,7 +118,7 @@ def run(self, args: argparse.Namespace) -> int: samples = os.path.exists(os.path.join(package_dir, "samples")) generated_samples = os.path.exists(os.path.join(package_dir, "generated_samples")) if not samples and not generated_samples: - logging.info( + logger.info( f"Package {package_name} does not have a samples directory." ) else: @@ -131,7 +129,7 @@ def run(self, args: argparse.Namespace) -> int: os.path.join(package_dir, "samples" if samples else "generated_samples"), ] try: - logging.info( + logger.info( f"Running mypy commands on sample code: {sample_code}" ) results.append(check_call(sample_code)) diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging.py b/eng/tools/azure-sdk-tools/ci_tools/logging.py deleted file mode 100644 index 7cf49f1afd42..000000000000 --- a/eng/tools/azure-sdk-tools/ci_tools/logging.py +++ /dev/null @@ -1,34 +0,0 @@ -import logging -import argparse -import os - -logger = logging.getLogger("azure-sdk-tools") - -def configure_logging( - args: argparse.Namespace, - level: str = "INFO", - fmt: str = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" -) -> None: - """ - Configures the shared logger. Should be called **once** at startup. - """ - - numeric_level = getattr(logging, level.upper(), None) - - # parse cli arg - if args.quiet: - numeric_level = logging.ERROR - elif args.verbose: - numeric_level = logging.DEBUG - - # parse LOG_LEVEL environment variable - log_level_env = os.getenv("LOG_LEVEL") - if not args.log_level and log_level_env: - numeric_level = getattr(logging, log_level_env.upper(), None) - - if not isinstance(numeric_level, int): - raise ValueError(f"Invalid log level: {level}") - logger.setLevel(numeric_level) - - # Propagate logger config globally if needed - logging.basicConfig(level=numeric_level, format=fmt) diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py index 27bc68995741..ef7b648041dd 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py +++ b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py @@ -4,9 +4,41 @@ import os import datetime from subprocess import run +import argparse LOGLEVEL = getattr(logging, os.environ.get("LOGLEVEL", "INFO").upper()) +logger = logging.getLogger("azure-sdk-tools") + +def configure_logging( + args: argparse.Namespace, + level: str = "INFO", + fmt: str = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" +) -> None: + """ + Configures the shared logger. Should be called **once** at startup. + """ + + numeric_level = getattr(logging, level.upper(), None) + + # parse cli arg + if args.quiet: + numeric_level = logging.ERROR + elif args.verbose: + numeric_level = logging.DEBUG + + # parse LOG_LEVEL environment variable + log_level_env = os.getenv("LOG_LEVEL") + if not args.log_level and log_level_env: + numeric_level = getattr(logging, log_level_env.upper(), None) + + if not isinstance(numeric_level, int): + raise ValueError(f"Invalid log level: {level}") + logger.setLevel(numeric_level) + + # Propagate logger config globally if needed + logging.basicConfig(level=numeric_level, format=fmt) + def now() -> str: return datetime.datetime.now().strftime("%Y-%m-%dT%H.%M.%S") From ca1420b9395981c0579d25624f3d8bbeaa8e5f4f Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:08:05 -0700 Subject: [PATCH 04/20] use env var --- eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py index ef7b648041dd..c57cad2b2361 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py +++ b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py @@ -27,13 +27,12 @@ def configure_logging( elif args.verbose: numeric_level = logging.DEBUG - # parse LOG_LEVEL environment variable - log_level_env = os.getenv("LOG_LEVEL") - if not args.log_level and log_level_env: - numeric_level = getattr(logging, log_level_env.upper(), None) + # use log level environment variable + if not args.log_level: + numeric_level = getattr(logging, LOGLEVEL.upper(), None) if not isinstance(numeric_level, int): - raise ValueError(f"Invalid log level: {level}") + raise ValueError(f"Invalid log level: {numeric_level}") logger.setLevel(numeric_level) # Propagate logger config globally if needed From cc08c7264588abfc43e6472e6190332f11384005 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:17:54 -0700 Subject: [PATCH 05/20] minor log fix --- eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py index c57cad2b2361..94dd4089ec21 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py +++ b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py @@ -32,7 +32,7 @@ def configure_logging( numeric_level = getattr(logging, LOGLEVEL.upper(), None) if not isinstance(numeric_level, int): - raise ValueError(f"Invalid log level: {numeric_level}") + raise ValueError(f"Invalid log level: {level}") logger.setLevel(numeric_level) # Propagate logger config globally if needed From faf5f4bbef6c2699ab28e64cfd3360a410926280 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:22:59 -0700 Subject: [PATCH 06/20] replace logging with logger --- eng/tools/azure-sdk-tools/azpysdk/import_all.py | 6 +++--- eng/tools/azure-sdk-tools/azpysdk/whl.py | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/eng/tools/azure-sdk-tools/azpysdk/import_all.py b/eng/tools/azure-sdk-tools/azpysdk/import_all.py index a9b86d07193c..ccc688e5c03e 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/import_all.py +++ b/eng/tools/azure-sdk-tools/azpysdk/import_all.py @@ -69,7 +69,7 @@ def run(self, args: argparse.Namespace) -> int: if should_run_import_all(parsed.name): # import all modules from current package - logging.info( + logger.info( "Importing all modules from namespace [{0}] to verify dependency".format( parsed.namespace ) @@ -82,8 +82,8 @@ def run(self, args: argparse.Namespace) -> int: ] outcomes.append(check_call(commands)) - logging.info("Verified module dependency, no issues found") + logger.info("Verified module dependency, no issues found") else: - logging.info("Package {} is excluded from dependency check".format(parsed.name)) + logger.info("Package {} is excluded from dependency check".format(parsed.name)) return max(outcomes) if outcomes else 0 diff --git a/eng/tools/azure-sdk-tools/azpysdk/whl.py b/eng/tools/azure-sdk-tools/azpysdk/whl.py index b6d9bc4f8f93..96aa968435d5 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/whl.py +++ b/eng/tools/azure-sdk-tools/azpysdk/whl.py @@ -1,5 +1,4 @@ import argparse -import logging import tempfile import os from typing import Optional, List, Any @@ -12,7 +11,7 @@ from ci_tools.variables import set_envvar_defaults from ci_tools.parsing import ParsedSetup from ci_tools.scenario.generation import create_package_and_install - +from ci_tools.logging import logger class whl(Check): def __init__(self) -> None: @@ -58,7 +57,7 @@ def run(self, args: argparse.Namespace) -> int: ) # todo, come up with a good pattern for passing all the additional args after -- to pytest - logging.info(f"Invoke pytest for {pkg}") + logger.info(f"Invoke pytest for {pkg}") exit_code = pytest_main( [pkg] @@ -66,9 +65,9 @@ def run(self, args: argparse.Namespace) -> int: if exit_code != 0: if exit_code == 5 and is_error_code_5_allowed(parsed.folder, parsed.name): - logging.info("Exit code 5 is allowed, continuing execution.") + logger.info("Exit code 5 is allowed, continuing execution.") else: - logging.info(f"pytest failed with exit code {exit_code}.") + logger.info(f"pytest failed with exit code {exit_code}.") results.append(exit_code) # final result is the worst case of all the results From 9df96517d2e3a4042a11631bc4ff3f800797cc9f Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:29:44 -0700 Subject: [PATCH 07/20] replace prints with logs --- eng/tools/azure-sdk-tools/azpysdk/Check.py | 11 ++++++----- eng/tools/azure-sdk-tools/azpysdk/import_all.py | 2 +- eng/tools/azure-sdk-tools/azpysdk/main.py | 4 ++-- eng/tools/azure-sdk-tools/azpysdk/mypy.py | 6 +++--- eng/tools/azure-sdk-tools/azpysdk/whl.py | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/eng/tools/azure-sdk-tools/azpysdk/Check.py b/eng/tools/azure-sdk-tools/azpysdk/Check.py index cd18731eed5b..09416eaf4e58 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/Check.py +++ b/eng/tools/azure-sdk-tools/azpysdk/Check.py @@ -5,6 +5,7 @@ from typing import Sequence, Optional, List, Any from ci_tools.parsing import ParsedSetup from ci_tools.functions import discover_targeted_packages +from ci_tools.logging import logger class Check(abc.ABC): """ @@ -45,8 +46,8 @@ def get_targeted_directories(self, args: argparse.Namespace) -> List[ParsedSetup try: targeted.append(ParsedSetup.from_path(targeted_dir)) except Exception as e: - print("Error: Current directory does not appear to be a Python package (no setup.py or setup.cfg found). Remove '.' argument to run on child directories.") - print(f"Exception: {e}") + logger.error("Error: Current directory does not appear to be a Python package (no setup.py or setup.cfg found). Remove '.' argument to run on child directories.") + logger.error(f"Exception: {e}") return [] else: targeted_packages = discover_targeted_packages(args.target, targeted_dir) @@ -54,8 +55,8 @@ def get_targeted_directories(self, args: argparse.Namespace) -> List[ParsedSetup try: targeted.append(ParsedSetup.from_path(pkg)) except Exception as e: - print(f"Unable to parse {pkg} as a Python package. Dumping exception detail and skipping.") - print(f"Exception: {e}") - print(traceback.format_exc()) + logger.error(f"Unable to parse {pkg} as a Python package. Dumping exception detail and skipping.") + logger.error(f"Exception: {e}") + logger.error(traceback.format_exc()) return targeted diff --git a/eng/tools/azure-sdk-tools/azpysdk/import_all.py b/eng/tools/azure-sdk-tools/azpysdk/import_all.py index ccc688e5c03e..8df7f1363ee4 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/import_all.py +++ b/eng/tools/azure-sdk-tools/azpysdk/import_all.py @@ -42,7 +42,7 @@ def register(self, subparsers: "argparse._SubParsersAction", parent_parsers: Opt # todo: figure out venv abstraction mechanism via override def run(self, args: argparse.Namespace) -> int: """Run the import_all check command.""" - print("Running import_all check in isolated venv...") + logger.info("Running import_all check in isolated venv...") targeted = self.get_targeted_directories(args) diff --git a/eng/tools/azure-sdk-tools/azpysdk/main.py b/eng/tools/azure-sdk-tools/azpysdk/main.py index 2d33adb96d49..9b81401c097f 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/main.py +++ b/eng/tools/azure-sdk-tools/azpysdk/main.py @@ -136,10 +136,10 @@ def main(argv: Optional[Sequence[str]] = None) -> int:# result = args.func(args) return int(result or 0) except KeyboardInterrupt: - print("Interrupted by user", file=sys.stderr) + logger.error("Interrupted by user") return 130 except Exception as exc: # pragma: no cover - simple top-level error handling - print(f"Error: {exc}", file=sys.stderr) + logger.error(f"Error: {exc}") return 2 if __name__ == "__main__": diff --git a/eng/tools/azure-sdk-tools/azpysdk/mypy.py b/eng/tools/azure-sdk-tools/azpysdk/mypy.py index 2682ab87c521..850ab3424eaa 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/mypy.py +++ b/eng/tools/azure-sdk-tools/azpysdk/mypy.py @@ -39,7 +39,7 @@ def register(self, subparsers: "argparse._SubParsersAction", parent_parsers: Opt def run(self, args: argparse.Namespace) -> int: """Run the mypy check command.""" - print("Running mypy check in isolated venv...") + logger.info("Running mypy check in isolated venv...") set_envvar_defaults() @@ -50,7 +50,7 @@ def run(self, args: argparse.Namespace) -> int: for parsed in targeted: package_dir = parsed.folder package_name = parsed.name - print(f"Processing {package_name} for mypy check") + logger.info(f"Processing {package_name} for mypy check") staging_area = tempfile.mkdtemp() create_package_and_install( @@ -72,7 +72,7 @@ def run(self, args: argparse.Namespace) -> int: else: check_call([sys.executable, "-m", "pip", "install", f"mypy=={MYPY_VERSION}"]) except CalledProcessError as e: - print("Failed to install mypy:", e) + logger.error("Failed to install mypy:", e) return e.returncode logger.info(f"Running mypy against {package_name}") diff --git a/eng/tools/azure-sdk-tools/azpysdk/whl.py b/eng/tools/azure-sdk-tools/azpysdk/whl.py index 96aa968435d5..e9e6319f72ec 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/whl.py +++ b/eng/tools/azure-sdk-tools/azpysdk/whl.py @@ -28,7 +28,7 @@ def register(self, subparsers: "argparse._SubParsersAction", parent_parsers: Opt def run(self, args: argparse.Namespace) -> int: """Run the whl check command.""" - print("Running whl check...") + logger.info("Running whl check...") set_envvar_defaults() From 071152e20c3cd260759cb62741a167f43452a47b Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:50:41 -0700 Subject: [PATCH 08/20] make log level args mutually exclusive --- eng/tools/azure-sdk-tools/azpysdk/main.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/eng/tools/azure-sdk-tools/azpysdk/main.py b/eng/tools/azure-sdk-tools/azpysdk/main.py index 9b81401c097f..64a57f5c4aec 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/main.py +++ b/eng/tools/azure-sdk-tools/azpysdk/main.py @@ -39,20 +39,22 @@ def build_parser() -> argparse.ArgumentParser: # global flag: allow --isolate to appear before the subcommand as well parser.add_argument("--isolate", action="store_true", default=False, help="If set, run in an isolated virtual environment.") - # logging level info - parser.add_argument( + + # mutually exclusive logging options + log_group = parser.add_mutually_exclusive_group() + log_group.add_argument( "--quiet", action="store_true", default=False, help="Enable quiet mode (only shows ERROR logs)" ) - parser.add_argument( + log_group.add_argument( "--verbose", action="store_true", default=False, help="Enable verbose mode (shows DEBUG logs)" ) - parser.add_argument( + log_group.add_argument( "--log-level", default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], From d07793b52d2a2744d07637a7142724810f53076e Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 16:19:05 -0700 Subject: [PATCH 09/20] fix arg precedence logic --- eng/tools/azure-sdk-tools/azpysdk/main.py | 1 - eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py | 9 +++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/eng/tools/azure-sdk-tools/azpysdk/main.py b/eng/tools/azure-sdk-tools/azpysdk/main.py index 64a57f5c4aec..e157aa621f0a 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/main.py +++ b/eng/tools/azure-sdk-tools/azpysdk/main.py @@ -56,7 +56,6 @@ def build_parser() -> argparse.ArgumentParser: ) log_group.add_argument( "--log-level", - default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], help="Set the logging level." ) diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py index 94dd4089ec21..d618f3298e17 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py +++ b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py @@ -18,18 +18,15 @@ def configure_logging( """ Configures the shared logger. Should be called **once** at startup. """ - + # use cli arg > log level arg > env var numeric_level = getattr(logging, level.upper(), None) - # parse cli arg if args.quiet: numeric_level = logging.ERROR elif args.verbose: numeric_level = logging.DEBUG - - # use log level environment variable - if not args.log_level: - numeric_level = getattr(logging, LOGLEVEL.upper(), None) + elif not args.log_level: + numeric_level = LOGLEVEL if not isinstance(numeric_level, int): raise ValueError(f"Invalid log level: {level}") From e7a9fc494e058ae61e26f1c05f31a1f7e6d2d4c7 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 17:20:40 -0700 Subject: [PATCH 10/20] add unit test --- .../tests/test_logging_config.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 eng/tools/azure-sdk-tools/tests/test_logging_config.py diff --git a/eng/tools/azure-sdk-tools/tests/test_logging_config.py b/eng/tools/azure-sdk-tools/tests/test_logging_config.py new file mode 100644 index 000000000000..7fdddf9f3f13 --- /dev/null +++ b/eng/tools/azure-sdk-tools/tests/test_logging_config.py @@ -0,0 +1,22 @@ + +import logging +from ci_tools.logging import configure_logging, logger +from unittest.mock import patch +import pytest +import argparse +import os + +@pytest.mark.parametrize("cli_args,level,level_env,expected_level", [ + (argparse.Namespace(quiet=True, verbose=False, log_level=None), "INFO", "INFO", logging.ERROR), + (argparse.Namespace(quiet=False, verbose=True, log_level=None), "INFO", "INFO", logging.DEBUG), + (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), "INFO", "WARNING", logging.INFO), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), "INFO", "DEBUG", logging.DEBUG), +]) +@patch("logging.basicConfig") +def test_configure_logging_various_levels(mock_basic_config, cli_args, level, level_env, expected_level, monkeypatch): + monkeypatch.setenv("LOGLEVEL", level_env) + assert os.environ["LOGLEVEL"] == level_env + configure_logging(cli_args, level=level) + assert logger.level == expected_level + mock_basic_config.assert_called_with(level=expected_level, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s") From 4e2299a5fba931feb54b43077aa281e1911a3c78 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 17:33:15 -0700 Subject: [PATCH 11/20] test fix --- eng/tools/azure-sdk-tools/tests/test_logging_config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eng/tools/azure-sdk-tools/tests/test_logging_config.py b/eng/tools/azure-sdk-tools/tests/test_logging_config.py index 7fdddf9f3f13..2a2f49de1022 100644 --- a/eng/tools/azure-sdk-tools/tests/test_logging_config.py +++ b/eng/tools/azure-sdk-tools/tests/test_logging_config.py @@ -10,13 +10,14 @@ (argparse.Namespace(quiet=True, verbose=False, log_level=None), "INFO", "INFO", logging.ERROR), (argparse.Namespace(quiet=False, verbose=True, log_level=None), "INFO", "INFO", logging.DEBUG), (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), "INFO", "WARNING", logging.INFO), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), "INFO", "WARNING", logging.WARNING), (argparse.Namespace(quiet=False, verbose=False, log_level=None), "INFO", "DEBUG", logging.DEBUG), ]) @patch("logging.basicConfig") def test_configure_logging_various_levels(mock_basic_config, cli_args, level, level_env, expected_level, monkeypatch): monkeypatch.setenv("LOGLEVEL", level_env) assert os.environ["LOGLEVEL"] == level_env + print(level_env) configure_logging(cli_args, level=level) assert logger.level == expected_level mock_basic_config.assert_called_with(level=expected_level, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s") From 15122e4be6600e49ab91f736b7830c43fecf94a0 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Thu, 28 Aug 2025 17:37:35 -0700 Subject: [PATCH 12/20] test fix --- eng/tools/azure-sdk-tools/tests/test_logging_config.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/tools/azure-sdk-tools/tests/test_logging_config.py b/eng/tools/azure-sdk-tools/tests/test_logging_config.py index 2a2f49de1022..56d126b130ab 100644 --- a/eng/tools/azure-sdk-tools/tests/test_logging_config.py +++ b/eng/tools/azure-sdk-tools/tests/test_logging_config.py @@ -7,11 +7,11 @@ import os @pytest.mark.parametrize("cli_args,level,level_env,expected_level", [ - (argparse.Namespace(quiet=True, verbose=False, log_level=None), "INFO", "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=True, log_level=None), "INFO", "INFO", logging.DEBUG), + (argparse.Namespace(quiet=True, verbose=False, log_level=None), "NONE", "INFO", logging.ERROR), + (argparse.Namespace(quiet=False, verbose=True, log_level=None), "NONE", "INFO", logging.DEBUG), (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), "INFO", "WARNING", logging.WARNING), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), "INFO", "DEBUG", logging.DEBUG), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), "NONE", "WARNING", logging.WARNING), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), "NONE", "DEBUG", logging.DEBUG), ]) @patch("logging.basicConfig") def test_configure_logging_various_levels(mock_basic_config, cli_args, level, level_env, expected_level, monkeypatch): From 3f61685c6da703e3132a1fc45b3676e4c976bb59 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Fri, 29 Aug 2025 09:18:35 -0700 Subject: [PATCH 13/20] minor fix --- eng/tools/azure-sdk-tools/tests/test_logging_config.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/tools/azure-sdk-tools/tests/test_logging_config.py b/eng/tools/azure-sdk-tools/tests/test_logging_config.py index 56d126b130ab..26ffe0d26fbb 100644 --- a/eng/tools/azure-sdk-tools/tests/test_logging_config.py +++ b/eng/tools/azure-sdk-tools/tests/test_logging_config.py @@ -7,11 +7,11 @@ import os @pytest.mark.parametrize("cli_args,level,level_env,expected_level", [ - (argparse.Namespace(quiet=True, verbose=False, log_level=None), "NONE", "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=True, log_level=None), "NONE", "INFO", logging.DEBUG), + (argparse.Namespace(quiet=True, verbose=False, log_level=None), None, "INFO", logging.ERROR), + (argparse.Namespace(quiet=False, verbose=True, log_level=None), None, "INFO", logging.DEBUG), (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), "NONE", "WARNING", logging.WARNING), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), "NONE", "DEBUG", logging.DEBUG), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "WARNING", logging.WARNING), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "DEBUG", logging.DEBUG), ]) @patch("logging.basicConfig") def test_configure_logging_various_levels(mock_basic_config, cli_args, level, level_env, expected_level, monkeypatch): From f6313bba45ca0d94da000d6c95ee96cd537cb4b9 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Fri, 29 Aug 2025 09:26:26 -0700 Subject: [PATCH 14/20] logic fix --- eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py index d618f3298e17..b75d01534f35 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py +++ b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py @@ -6,9 +6,8 @@ from subprocess import run import argparse -LOGLEVEL = getattr(logging, os.environ.get("LOGLEVEL", "INFO").upper()) - logger = logging.getLogger("azure-sdk-tools") +LOGLEVEL = getattr(logging, os.environ.get("LOGLEVEL", "INFO").upper()) def configure_logging( args: argparse.Namespace, @@ -19,14 +18,15 @@ def configure_logging( Configures the shared logger. Should be called **once** at startup. """ # use cli arg > log level arg > env var - numeric_level = getattr(logging, level.upper(), None) if args.quiet: numeric_level = logging.ERROR elif args.verbose: numeric_level = logging.DEBUG - elif not args.log_level: - numeric_level = LOGLEVEL + elif not level: + numeric_level = getattr(logging, os.environ.get("LOGLEVEL", "INFO").upper()) + else: + numeric_level = getattr(logging, level.upper(), None) if not isinstance(numeric_level, int): raise ValueError(f"Invalid log level: {level}") From 70d8ad3d358d9149af68a2e6cabf7be46ded63b9 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Fri, 29 Aug 2025 09:27:47 -0700 Subject: [PATCH 15/20] formatting fix --- eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py index b75d01534f35..6842fc4e949e 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py +++ b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py @@ -6,9 +6,10 @@ from subprocess import run import argparse -logger = logging.getLogger("azure-sdk-tools") LOGLEVEL = getattr(logging, os.environ.get("LOGLEVEL", "INFO").upper()) +logger = logging.getLogger("azure-sdk-tools") + def configure_logging( args: argparse.Namespace, level: str = "INFO", From e46c0b6cb83467c2a81a6b18b49ab64cf0d52f5b Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Fri, 29 Aug 2025 09:37:43 -0700 Subject: [PATCH 16/20] merge --- eng/tools/azure-sdk-tools/azpysdk/Check.py | 2 +- eng/tools/azure-sdk-tools/azpysdk/main.py | 2 ++ eng/tools/azure-sdk-tools/azpysdk/mypy.py | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/eng/tools/azure-sdk-tools/azpysdk/Check.py b/eng/tools/azure-sdk-tools/azpysdk/Check.py index 8d5e11ba04d4..efdf05ec6ccf 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/Check.py +++ b/eng/tools/azure-sdk-tools/azpysdk/Check.py @@ -11,12 +11,12 @@ from ci_tools.functions import discover_targeted_packages, get_venv_call from ci_tools.variables import discover_repo_root from ci_tools.scenario import install_into_venv, get_venv_python +from ci_tools.logging import logger # right now, we are assuming you HAVE to be in the azure-sdk-tools repo # we assume this because we don't know how a dev has installed this package, and might be # being called from within a site-packages folder. Due to that, we can't trust the location of __file__ REPO_ROOT = discover_repo_root() -from ci_tools.logging import logger class Check(abc.ABC): """ diff --git a/eng/tools/azure-sdk-tools/azpysdk/main.py b/eng/tools/azure-sdk-tools/azpysdk/main.py index db34dd60958b..d11fcd037f29 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/main.py +++ b/eng/tools/azure-sdk-tools/azpysdk/main.py @@ -16,6 +16,8 @@ from .import_all import import_all from .mypy import mypy +from ci_tools.logging import configure_logging, logger + __all__ = ["main", "build_parser"] __version__ = "0.0.0" diff --git a/eng/tools/azure-sdk-tools/azpysdk/mypy.py b/eng/tools/azure-sdk-tools/azpysdk/mypy.py index cf458383bd98..eef2960571ce 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/mypy.py +++ b/eng/tools/azure-sdk-tools/azpysdk/mypy.py @@ -50,8 +50,10 @@ def run(self, args: argparse.Namespace) -> int: for parsed in targeted: package_dir = parsed.folder package_name = parsed.name + executable, staging_directory = self.get_executable(args.isolate, args.command, sys.executable, package_dir) logger.info(f"Processing {package_name} for mypy check") + create_package_and_install( distribution_directory=staging_directory, target_setup=package_dir, From c7549f8bace55af13093d4c2c39502e32b729069 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Fri, 29 Aug 2025 09:42:38 -0700 Subject: [PATCH 17/20] clean test --- eng/tools/azure-sdk-tools/tests/test_logging_config.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/eng/tools/azure-sdk-tools/tests/test_logging_config.py b/eng/tools/azure-sdk-tools/tests/test_logging_config.py index 26ffe0d26fbb..594f5875ee4a 100644 --- a/eng/tools/azure-sdk-tools/tests/test_logging_config.py +++ b/eng/tools/azure-sdk-tools/tests/test_logging_config.py @@ -11,13 +11,11 @@ (argparse.Namespace(quiet=False, verbose=True, log_level=None), None, "INFO", logging.DEBUG), (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "WARNING", logging.WARNING), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "DEBUG", logging.DEBUG), ]) @patch("logging.basicConfig") def test_configure_logging_various_levels(mock_basic_config, cli_args, level, level_env, expected_level, monkeypatch): monkeypatch.setenv("LOGLEVEL", level_env) assert os.environ["LOGLEVEL"] == level_env - print(level_env) configure_logging(cli_args, level=level) assert logger.level == expected_level mock_basic_config.assert_called_with(level=expected_level, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s") From ac83f032ebc9b60b08f96c9981bc2be54a9328cd Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Fri, 29 Aug 2025 10:07:15 -0700 Subject: [PATCH 18/20] standardize log params --- eng/tools/azure-sdk-tools/azpysdk/main.py | 2 +- eng/tools/azure-sdk-tools/tests/test_logging_config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/tools/azure-sdk-tools/azpysdk/main.py b/eng/tools/azure-sdk-tools/azpysdk/main.py index d11fcd037f29..f4fc4aadd828 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/main.py +++ b/eng/tools/azure-sdk-tools/azpysdk/main.py @@ -47,7 +47,7 @@ def build_parser() -> argparse.ArgumentParser: ) log_group.add_argument( "--log-level", - choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], + choices=["DEBUG", "INFO", "WARN", "ERROR", "FATAL"], help="Set the logging level." ) diff --git a/eng/tools/azure-sdk-tools/tests/test_logging_config.py b/eng/tools/azure-sdk-tools/tests/test_logging_config.py index 594f5875ee4a..5ab7025a4071 100644 --- a/eng/tools/azure-sdk-tools/tests/test_logging_config.py +++ b/eng/tools/azure-sdk-tools/tests/test_logging_config.py @@ -10,7 +10,7 @@ (argparse.Namespace(quiet=True, verbose=False, log_level=None), None, "INFO", logging.ERROR), (argparse.Namespace(quiet=False, verbose=True, log_level=None), None, "INFO", logging.DEBUG), (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "WARNING", logging.WARNING), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "WARN", logging.WARNING), ]) @patch("logging.basicConfig") def test_configure_logging_various_levels(mock_basic_config, cli_args, level, level_env, expected_level, monkeypatch): From a952cb1ad6545529685287cbfbddd60231827ce1 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Fri, 29 Aug 2025 10:11:31 -0700 Subject: [PATCH 19/20] copilot formatting fix Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- eng/tools/azure-sdk-tools/tests/test_logging_config.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/tools/azure-sdk-tools/tests/test_logging_config.py b/eng/tools/azure-sdk-tools/tests/test_logging_config.py index 5ab7025a4071..7824d8236e78 100644 --- a/eng/tools/azure-sdk-tools/tests/test_logging_config.py +++ b/eng/tools/azure-sdk-tools/tests/test_logging_config.py @@ -7,10 +7,10 @@ import os @pytest.mark.parametrize("cli_args,level,level_env,expected_level", [ - (argparse.Namespace(quiet=True, verbose=False, log_level=None), None, "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=True, log_level=None), None, "INFO", logging.DEBUG), - (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "WARN", logging.WARNING), + (argparse.Namespace(quiet=True, verbose=False, log_level=None), None, "INFO", logging.ERROR), + (argparse.Namespace(quiet=False, verbose=True, log_level=None), None, "INFO", logging.DEBUG), + (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "WARN", logging.WARNING), ]) @patch("logging.basicConfig") def test_configure_logging_various_levels(mock_basic_config, cli_args, level, level_env, expected_level, monkeypatch): From d538a2c3f6d54a51b7a2c5130a7195cfd5c2e5c3 Mon Sep 17 00:00:00 2001 From: jenny <63012604+JennyPng@users.noreply.github.com> Date: Fri, 29 Aug 2025 10:36:55 -0700 Subject: [PATCH 20/20] remove levels arg --- eng/tools/azure-sdk-tools/azpysdk/main.py | 2 +- .../azure-sdk-tools/ci_tools/logging/__init__.py | 7 +++---- .../azure-sdk-tools/tests/test_logging_config.py | 14 +++++++------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/eng/tools/azure-sdk-tools/azpysdk/main.py b/eng/tools/azure-sdk-tools/azpysdk/main.py index f4fc4aadd828..467f00db0823 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/main.py +++ b/eng/tools/azure-sdk-tools/azpysdk/main.py @@ -87,7 +87,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int: parser = build_parser() args = parser.parse_args(argv) - configure_logging(args, args.log_level) + configure_logging(args) if not hasattr(args, "func"): parser.print_help() diff --git a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py index 6842fc4e949e..a32945c09978 100644 --- a/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py +++ b/eng/tools/azure-sdk-tools/ci_tools/logging/__init__.py @@ -12,7 +12,6 @@ def configure_logging( args: argparse.Namespace, - level: str = "INFO", fmt: str = "%(asctime)s [%(levelname)s] %(name)s: %(message)s" ) -> None: """ @@ -24,13 +23,13 @@ def configure_logging( numeric_level = logging.ERROR elif args.verbose: numeric_level = logging.DEBUG - elif not level: + elif not args.log_level: numeric_level = getattr(logging, os.environ.get("LOGLEVEL", "INFO").upper()) else: - numeric_level = getattr(logging, level.upper(), None) + numeric_level = getattr(logging, args.log_level.upper(), None) if not isinstance(numeric_level, int): - raise ValueError(f"Invalid log level: {level}") + raise ValueError(f"Invalid log level: {numeric_level}") logger.setLevel(numeric_level) # Propagate logger config globally if needed diff --git a/eng/tools/azure-sdk-tools/tests/test_logging_config.py b/eng/tools/azure-sdk-tools/tests/test_logging_config.py index 5ab7025a4071..747723da879e 100644 --- a/eng/tools/azure-sdk-tools/tests/test_logging_config.py +++ b/eng/tools/azure-sdk-tools/tests/test_logging_config.py @@ -6,16 +6,16 @@ import argparse import os -@pytest.mark.parametrize("cli_args,level,level_env,expected_level", [ - (argparse.Namespace(quiet=True, verbose=False, log_level=None), None, "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=True, log_level=None), None, "INFO", logging.DEBUG), - (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "ERROR", "INFO", logging.ERROR), - (argparse.Namespace(quiet=False, verbose=False, log_level=None), None, "WARN", logging.WARNING), +@pytest.mark.parametrize("cli_args,level_env,expected_level", [ + (argparse.Namespace(quiet=True, verbose=False, log_level=None), "INFO", logging.ERROR), + (argparse.Namespace(quiet=False, verbose=True, log_level=None), "INFO", logging.DEBUG), + (argparse.Namespace(quiet=False, verbose=False, log_level="ERROR"), "INFO", logging.ERROR), + (argparse.Namespace(quiet=False, verbose=False, log_level=None), "WARN", logging.WARNING), ]) @patch("logging.basicConfig") -def test_configure_logging_various_levels(mock_basic_config, cli_args, level, level_env, expected_level, monkeypatch): +def test_configure_logging_various_levels(mock_basic_config, cli_args, level_env, expected_level, monkeypatch): monkeypatch.setenv("LOGLEVEL", level_env) assert os.environ["LOGLEVEL"] == level_env - configure_logging(cli_args, level=level) + configure_logging(cli_args) assert logger.level == expected_level mock_basic_config.assert_called_with(level=expected_level, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")