Module mbed_tools_lib.logging
Helpers for logging errors according to severity of the exception.
Expand source code
#
# Copyright (C) 2020 Arm Mbed. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
"""Helpers for logging errors according to severity of the exception."""
from typing import Type, Optional, cast
from types import TracebackType
import logging
from mbed_tools_lib.exceptions import ToolsError
LOGGING_FORMAT = "%(levelname)s: %(message)s"
VERBOSITY_HELP = {
logging.CRITICAL: "-v",
logging.ERROR: "-v",
logging.WARNING: "-vv",
logging.INFO: "-vvv",
logging.DEBUG: "--traceback",
}
def _exception_message(err: BaseException, log_level: int, traceback: bool) -> str:
"""Generate a user facing message with help on how to get more information from the logs."""
error_msg = str(err)
if log_level != logging.DEBUG or not traceback:
cli_option = VERBOSITY_HELP.get(log_level, "-v")
error_msg += f"\n\nMore information may be available by using the command line option '{cli_option}'."
return error_msg
class MbedToolsHandler:
"""Context Manager to catch Mbed Tools exceptions and generate a helpful user facing message."""
def __init__(self, logger: logging.Logger, traceback: bool = False):
"""Keep track of the logger to use and whether or not a traceback should be generated."""
self._logger = logger
self._traceback = traceback
def __enter__(self) -> "MbedToolsHandler":
"""Return the Context Manager."""
return self
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_value: Optional[BaseException],
exc_traceback: Optional[TracebackType],
) -> bool:
"""Handle any raised exceptions, suppressing Tools errors and generating an error message instead."""
if exc_type and issubclass(exc_type, ToolsError):
error_msg = _exception_message(cast(BaseException, exc_value), logging.root.level, self._traceback)
self._logger.error(error_msg, exc_info=self._traceback)
# Do not propagate exceptions derived from ToolsError
return True
# Propagate all other exceptions
return False
def log_exception(logger: logging.Logger, exception: Exception, show_traceback: bool = False) -> None:
"""Logs an exception in both normal and verbose forms.
Args:
logger: logger
exception: exception to log
show_traceback: show the full traceback.
"""
logger.error(exception, exc_info=show_traceback)
def set_log_level(verbose_count: int) -> None:
"""Sets the log level.
Args:
verbose_count: number of `-v` flags used
"""
if verbose_count > 2:
log_level = logging.DEBUG
elif verbose_count == 2:
log_level = logging.INFO
elif verbose_count == 1:
log_level = logging.WARNING
else:
log_level = logging.ERROR
logging.basicConfig(level=log_level, format=LOGGING_FORMAT)
Functions
def log_exception(logger: logging.Logger, exception: Exception, show_traceback: bool = False) -> NoneType
-
Logs an exception in both normal and verbose forms.
Args
logger
- logger
exception
- exception to log
show_traceback
- show the full traceback.
Expand source code
def log_exception(logger: logging.Logger, exception: Exception, show_traceback: bool = False) -> None: """Logs an exception in both normal and verbose forms. Args: logger: logger exception: exception to log show_traceback: show the full traceback. """ logger.error(exception, exc_info=show_traceback)
def set_log_level(verbose_count: int) -> NoneType
-
Sets the log level.
Args
verbose_count
- number of
-v
flags used
Expand source code
def set_log_level(verbose_count: int) -> None: """Sets the log level. Args: verbose_count: number of `-v` flags used """ if verbose_count > 2: log_level = logging.DEBUG elif verbose_count == 2: log_level = logging.INFO elif verbose_count == 1: log_level = logging.WARNING else: log_level = logging.ERROR logging.basicConfig(level=log_level, format=LOGGING_FORMAT)
Classes
class MbedToolsHandler (logger: logging.Logger, traceback: bool = False)
-
Context Manager to catch Mbed Tools exceptions and generate a helpful user facing message.
Keep track of the logger to use and whether or not a traceback should be generated.
Expand source code
class MbedToolsHandler: """Context Manager to catch Mbed Tools exceptions and generate a helpful user facing message.""" def __init__(self, logger: logging.Logger, traceback: bool = False): """Keep track of the logger to use and whether or not a traceback should be generated.""" self._logger = logger self._traceback = traceback def __enter__(self) -> "MbedToolsHandler": """Return the Context Manager.""" return self def __exit__( self, exc_type: Optional[Type[BaseException]], exc_value: Optional[BaseException], exc_traceback: Optional[TracebackType], ) -> bool: """Handle any raised exceptions, suppressing Tools errors and generating an error message instead.""" if exc_type and issubclass(exc_type, ToolsError): error_msg = _exception_message(cast(BaseException, exc_value), logging.root.level, self._traceback) self._logger.error(error_msg, exc_info=self._traceback) # Do not propagate exceptions derived from ToolsError return True # Propagate all other exceptions return False