From 8339bf17dc2d768d98a033814aaf77a9d67c47af Mon Sep 17 00:00:00 2001 From: Anton Joubert <ajoubert@ska.ac.za> Date: Mon, 13 Jan 2020 09:05:58 +0200 Subject: [PATCH] SAR-55 Add option to use static tag string This is useful for the Tango SKABaseDevice, where the only tag is the device name. --- ska_logging/__init__.py | 14 ++++++++++++-- ska_logging/configuration.py | 34 ++++++++++++++++++++++++++++++---- tests/test_configuration.py | 21 +++++++++++++++++---- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/ska_logging/__init__.py b/ska_logging/__init__.py index 47c2feb..1dcf20a 100644 --- a/ska_logging/__init__.py +++ b/ska_logging/__init__.py @@ -2,12 +2,22 @@ """Module init code.""" -__all__ = ("configure_logging", "get_default_formatter") +__all__ = ( + "configure_logging", + "get_default_formatter", + "SkaLoggingError", + "SkaLoggingTagsFormatError", +) __author__ = "Anton Joubert" __email__ = "ajoubert+ska@ska.ac.za" -from .configuration import configure_logging, get_default_formatter +from .configuration import ( + configure_logging, + get_default_formatter, + SkaLoggingError, + SkaLoggingTagsFormatError, +) # BEGIN VERSION CHECK diff --git a/ska_logging/configuration.py b/ska_logging/configuration.py index efa85e5..11135f3 100644 --- a/ska_logging/configuration.py +++ b/ska_logging/configuration.py @@ -7,6 +7,14 @@ import logging.config import time +class SkaLoggingError(Exception): + """Base class for all SKA Logger exceptions.""" + + +class SkaLoggingTagsFormatError(SkaLoggingError): + """Invalid format for the 'tags' field string.""" + + class _UTCFormatter(logging.Formatter): converter = time.gmtime @@ -38,6 +46,8 @@ _FORMAT_STR_WITH_TAGS = ( "%(message)s" ) +_INVALID_TAG_CHARS = ("|", "%") + _LOGGING_CONFIG = { "version": 1, "disable_existing_loggers": False, @@ -113,17 +123,33 @@ def get_default_formatter(tags=False): Parameters ---------- - tags : bool, optional - If true, then include the "tags" field in the format string. This requires - a tags filter to be linked to the corresponding handler. + tags : bool or str, optional + If boolean, then treated as a toggle: + - True: include the "tags" field in the format string. This requires + a tags filter to be linked to the corresponding handler. + - False: exclude the "tags" field from the format string. + If string, then it is a static tag. Instead of using a logging filter, the + formatter will just use this static string for the "tags" field directly. Returns ------- logging.Formatter A new default formatter. + Raises + ------ + SkaLoggingTagsFormatError: + If the static tags string has an invalid format. + """ - if tags: + if isinstance(tags, str): + invalid_chars = [c for c in _INVALID_TAG_CHARS if c in tags] + if invalid_chars: + raise SkaLoggingTagsFormatError( + "Invalid char(s) {} in tags: {!r}".format(invalid_chars, tags) + ) + format_str = _FORMAT_STR_WITH_TAGS.replace("%(tags)s", tags) + elif tags: format_str = _FORMAT_STR_WITH_TAGS else: format_str = _FORMAT_STR_NO_TAGS diff --git a/tests/test_configuration.py b/tests/test_configuration.py index a386d41..3e72a36 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -9,7 +9,7 @@ import pytest import ska_logging.configuration -from ska_logging import configure_logging, get_default_formatter +from ska_logging import configure_logging, get_default_formatter, SkaLoggingTagsFormatError @pytest.fixture @@ -165,7 +165,7 @@ class TestConfigureLogging: assert get_named_handler(logger, "test") -class TestGetFormatter: +class TestGetDefaultFormatter: """Tests for :func:`~ska_logging.configuration.get_default_formatter`.""" def test_default_no_tags(self): @@ -173,16 +173,29 @@ class TestGetFormatter: assert isinstance(formatter, ska_logging.configuration._UTCFormatter) assert formatter._fmt == ska_logging.configuration._FORMAT_STR_NO_TAGS - def test_get_without_tags(self): + def test_get_tags_disabled(self): formatter = get_default_formatter(tags=False) assert isinstance(formatter, ska_logging.configuration._UTCFormatter) assert formatter._fmt == ska_logging.configuration._FORMAT_STR_NO_TAGS - def test_get_with_tags(self): + def test_get_tags_enabled(self): formatter = get_default_formatter(tags=True) assert isinstance(formatter, ska_logging.configuration._UTCFormatter) assert formatter._fmt == ska_logging.configuration._FORMAT_STR_WITH_TAGS + def test_get_tags_static_string(self): + formatter = get_default_formatter(tags="test-key:test-value") + assert isinstance(formatter, ska_logging.configuration._UTCFormatter) + tags_format = ska_logging.configuration._FORMAT_STR_WITH_TAGS + expected_format = tags_format.replace("%(tags)s", "test-key:test-value") + assert formatter._fmt == expected_format + + def test_get_tags_invalid_static_string(self): + with pytest.raises(SkaLoggingTagsFormatError): + get_default_formatter(tags="no|pipes|allowed") + with pytest.raises(SkaLoggingTagsFormatError): + get_default_formatter(tags="no%percentage%symbols%allowed") + class TestOverride: """Tests for :func:`~ska_logging.configuration._override`. -- GitLab