Source code for masci_tools.util.logging_util

###############################################################################
# Copyright (c), 2018 Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany.    #
#                All rights reserved.                                         #
# This file is part of the Masci-tools package.                               #
# (Material science tools)                                                    #
#                                                                             #
# The code is hosted on GitHub at https://github.com/judftteam/masci-tools    #
# For further information on the license, see the LICENSE.txt file            #
#                                                                             #
###############################################################################
"""
This module defines useful utility for logging related functionality
"""
from __future__ import annotations

from logging import Handler, LoggerAdapter, LogRecord
from typing import Any, cast


[docs]class DictHandler(Handler): """ Custom Handler for the logging module inserting logging messages into a given dictionary. Messages are grouped into list under the names of the error categories. Keyword arguments can be used to modify the keys for the different levels """ def __init__(self, log_dict: dict[str, list[str]], ignore_unknown_levels: bool = False, **kwargs: int | str): from logging import _levelToName import copy self.log_dict = log_dict levels = copy.copy(list(_levelToName.values())) levels.remove('NOTSET') self.level_names: dict[str, str] = {name: cast(str, kwargs[name]) for name in levels if name in kwargs} if not ignore_unknown_levels: for name in levels: if name not in self.level_names: self.level_names[name] = name for name in self.level_names.values(): self.log_dict[name] = [] super().__init__()
[docs] def emit(self, record: LogRecord) -> None: """ Emit a record. """ try: msg = self.format(record) entry_name = self.level_names.get(record.levelname, 'NOTSET') if entry_name not in self.log_dict: self.log_dict[entry_name] = [] self.log_dict[entry_name].append(msg) except Exception: #pylint: disable=broad-except self.handleError(record)
def __repr__(self) -> str: from logging import getLevelName level = getLevelName(self.level) return f'<{self.__class__.__name__} ({level})>'
[docs]class OutParserLogAdapter(LoggerAdapter): """ This adapter expects the passed in dict-like object to have a 'iteration' key, whose value is prepended as [Iteration i] to the message """
[docs] def process(self, msg: str, kwargs: Any) -> tuple[str, dict[str, Any]]: return f"[Iteration {self.extra['iteration']}] {msg}", kwargs