From e0c32852c1fec234668b5266333e3fbe2ba8ed39 Mon Sep 17 00:00:00 2001 From: David Erb Date: Tue, 14 Feb 2023 13:49:35 +0000 Subject: [PATCH] adds filter markers --- src/dls_mainiac_lib/mainiac.py | 37 ++++++++++ tests/test_08_logging_markers.py | 117 +++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 tests/test_08_logging_markers.py diff --git a/src/dls_mainiac_lib/mainiac.py b/src/dls_mainiac_lib/mainiac.py index 5542185..5fceda3 100644 --- a/src/dls_mainiac_lib/mainiac.py +++ b/src/dls_mainiac_lib/mainiac.py @@ -62,6 +62,28 @@ class Namespace: pass +class Filterer: + """ + Python logging filter which excludes messages from output. + + Filters is a dict, for only only containing a markers list. + + A marker is a string of the form [SOMETHING] and occur anywhere in the message. + """ + + def __init__(self, filters): + if filters is not None: + self.__markers = filters.get("markers", []) + else: + self.__markers = [] + + def filter(self, record): + for marker in self.__markers: + if marker in record.msg: + return 0 + return 1 + + class Mainiac: """ Base class. Handles details like logging. @@ -157,6 +179,8 @@ def __synonym_of_failed(self): "goes belly up", "kicks the bucket", "croaks", + "bites the dust", + "rolls over", "pleads for help", "is lost", "displays frowny face", @@ -392,6 +416,11 @@ def configure_logging(self, settings=None): console_handler.setFormatter(formatter) # Log level for the console, not verbose. console_handler.setLevel(logging.INFO) + + # Possibly filter out messages. + console_filterer = Filterer(console_settings.get("filters")) + console_handler.addFilter(console_filterer) + else: console_handler = None @@ -405,6 +434,10 @@ def configure_logging(self, settings=None): logfile_directory, logfile_settings ) logfile_handler.setLevel(logging.DEBUG) + + # Possibly filter out messages. + logfile_filterer = Filterer(logfile_settings.get("filters")) + logfile_handler.addFilter(logfile_filterer) else: logfile_handler = None @@ -447,6 +480,10 @@ def configure_logging(self, settings=None): graypy_handler.setLevel(logging.DEBUG) logging.getLogger().addHandler(graypy_handler) + # Possibly filter out messages. + graypy_filterer = Filterer(graypy_settings.get("filters")) + graypy_handler.addFilter(graypy_filterer) + logger.debug( f"graypy logging handler enabled to {host}:{port} {protocol}" ) diff --git a/tests/test_08_logging_markers.py b/tests/test_08_logging_markers.py new file mode 100644 index 0000000..916ed74 --- /dev/null +++ b/tests/test_08_logging_markers.py @@ -0,0 +1,117 @@ +import argparse +import logging +import os +import shutil + +import pytest + +# Class under test. +from dls_mainiac_lib.mainiac import Mainiac + +logger = logging.getLogger(__name__) + + +class Test_08_logging_markers: + + # ---------------------------------------------------------------------------------------- + def test( + self, + constants, + logging_setup, + output_directory, + capsys, + ): + """ + Test mainiac base class. + """ + + failure_message = None + try: + + # Instantiate the app class. + app = _App(output_directory) + + # Configure the app from empty command line arguments. + app.parse_args_and_configure_logging([]) + + # Run the gui wrapped in a try/catch. + app.try_run_catch() + + except Exception as exception: + logger.exception("unexpected exception during the test", exc_info=exception) + failure_message = str(exception) + + if failure_message is not None: + pytest.fail(failure_message) + + +# --------------------------------------------------------------------------------- +class _App(Mainiac): + """ + App class. + """ + + def __init__( + self, + output_directory, + ): + + program_name = "test_08_logging_markers" + + self.__logfile_directory = f"/tmp/logs/{program_name}" + + if os.path.isdir(self.__logfile_directory): + shutil.rmtree(self.__logfile_directory) + + Mainiac.__init__(self, program_name) + + # ---------------------------------------------------------- + def run(self): + logger.debug("[MARKER1] this is marker1") + logger.debug("[MARKER2] this is marker2, should not appear in logfile") + logger.debug("[MARKER3] this is marker3, should not appear in logfile") + + filename = "logform.log" + filename = f"{self.__logfile_directory}/{filename}" + + # Check the logfile got written. + assert os.path.exists(filename) + + # Check there is the right number of output lines. + with open(filename, "r") as stream: + lines = stream.readlines() + assert len(lines) == 1 + assert "marker1" in lines[0] + + # -------------------------------------------------------------------------- + def configure_logging(self, settings=None): + """ + Configure runtime logging, override base class. + Presume that self._args is already set. + """ + + settings = { + "logfile": { + "enabled": True, + "filters": {"markers": ["[MARKER2]", "[MARKER3]"]}, + } + } + # Call the base method which has the extra kwarg. + Mainiac.configure_logging(self, settings) + + # ---------------------------------------------------------- + def version(self): + return "x.y.z" + + # ---------------------------------------------------------- + def about(self): + return {"url": "/some/good/url", "description": "A good description"} + + # ---------------------------------------------------------- + def build_parser(self, arglist=None): + + # Make a parser. + parser = argparse.ArgumentParser() + + # Return a structure describing the default subcommand. + return parser