Skip to content

Commit

Permalink
Improving logging patching and new testcase
Browse files Browse the repository at this point in the history
  • Loading branch information
casabre committed Jun 15, 2023
1 parent 2d539d6 commit 7340227
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 22 deletions.
16 changes: 12 additions & 4 deletions src/pytest_fluent/content_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ def get_tag_and_label(
stage_info = self._user_settings.get(stage_name, {})
return stage_info["tag"], stage_info["label"]

def patch(self, content: dict, stage_name: typing.Optional[str] = None) -> dict:
def patch(
self,
content: dict,
stage_name: typing.Optional[str] = None,
ignore_entries: typing.List[str] = [],
) -> dict:
"""Patch the content with the provided settings for each stage.
Args:
Expand All @@ -99,17 +104,20 @@ def patch(self, content: dict, stage_name: typing.Optional[str] = None) -> dict:
stage_name = inspect.stack()[1][3]

stage_info = self._user_settings.get(stage_name, {})
stage_info = {k: v for k, v in stage_info.items() if k not in ignore_entries}
if not stage_info:
return content
return self._patch_stage_content(content, stage_info)

@staticmethod
def _patch_stage_content(stage_content: dict, user_settings: dict) -> dict:
stage_content_patched = stage_content.copy()
stage_content_patched["tag"] = user_settings["tag"]
stage_content_patched["label"] = user_settings["label"]
if "tag" in user_settings:
stage_content_patched["tag"] = user_settings["tag"]
if "label" in user_settings:
stage_content_patched["label"] = user_settings["label"]
if "replace" in user_settings:
for key, value in user_settings["replace"].items():
for key, value in user_settings.get("replace", {}).items():
if key in stage_content_patched:
tmp = stage_content_patched[key]
stage_content_patched[value] = tmp
Expand Down
54 changes: 37 additions & 17 deletions src/pytest_fluent/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,27 @@ def __init__(self, config):
tags, self._host, self._port, buffer_overflow_handler=overflow_handler
)
self._log_reporter = LogReport(self.config)
self._patch_logging(
f"{self._content_patcher.user_settings['logging']['tag']}."
f"{self._content_patcher.user_settings['logging']['label']}"
self._patch_logging()

def _patch_logging(self):
if not self._extend_logging:
return
tag = self._content_patcher.user_settings.get("logging", {}).get("tag")
if not tag:
raise ValueError(
"Tag for logging was not set. Please set either specific tag value for \
key 'logging' or use the 'all' object in stage settings file."
)
label = self._content_patcher.user_settings.get("logging", {}).get("label")
if label:
tag = f"{tag}.{label}"
extend_loggers(
self._host,
self._port,
tag,
self._content_patcher,
)

def _patch_logging(self, tag: str):
if self._extend_logging:
extend_loggers(self._host, self._port, tag)

def _set_session_uid(
self, id: typing.Optional[typing.Union[str, uuid.UUID]] = None
) -> None:
Expand Down Expand Up @@ -330,14 +342,14 @@ def get_logger(request):
port = config.getoption("--fluentd-port")
tag = config.getoption("--fluentd-tag")

def get_logger(name=None):
def get_logger_wrapper(name=None):
logger = logging.getLogger(name)
if name is None:
return logger
add_handler(host, port, tag, logger)
return logger

return get_logger
return get_logger_wrapper


@pytest.fixture
Expand All @@ -363,9 +375,10 @@ def test_uid() -> typing.Optional[str]:
class RecordFormatter(FluentRecordFormatter):
"""Extension of FluentRecordFormatter in order to add unique ID's"""

def __init__(self, *args, **kwargs):
def __init__(self, patcher: typing.Optional[ContentPatcher], *args, **kwargs):
"""Specific initilization."""
super(RecordFormatter, self).__init__(*args, **kwargs)
self.content_patcher = patcher

def format(self, record):
"""Extend formatting for Fluentd handler."""
Expand All @@ -375,34 +388,41 @@ def format(self, record):
data["sessionId"] = get_session_uid()
data["testId"] = get_test_uid()
data["stage"] = get_stage()
if self.content_patcher:
data = self.content_patcher.patch(data, "logging", ["tag", "label"])
return data


def extend_loggers(host, port, tag) -> None:
def extend_loggers(host, port, tag, patcher: ContentPatcher) -> None:
"""Extend Python logging with a Fluentd handler."""
modify_logger(host, port, tag, None)
modify_logger(host, port, tag, "fluent")
modify_logger(host, port, tag, None, patcher)
modify_logger(host, port, tag, "fluent", patcher)


def modify_logger(host, port, tag, name=None) -> None:
def modify_logger(
host, port, tag, name=None, patcher: typing.Optional[ContentPatcher] = None
) -> None:
"""Extend Python logging with a Fluentd handler."""
logger = logging.getLogger(name)
add_handler(host, port, tag, logger)
add_handler(host, port, tag, logger, patcher)


def add_handler(host, port, tag, logger):
def add_handler(
host, port, tag, logger, patcher: typing.Optional[ContentPatcher] = None
):
"""Add handler to a specific logger."""
handler = FluentHandler(
tag, host=host, port=port, buffer_overflow_handler=overflow_handler
)
formatter = RecordFormatter(
patcher,
{
"type": "logging",
"host": "%(hostname)s",
"where": "%(module)s.%(funcName)s",
"level": "%(levelname)s",
"stack_trace": "%(exc_text)s",
}
},
)
handler.setFormatter(formatter)
logger.addHandler(handler)
Expand Down
58 changes: 57 additions & 1 deletion tests/test_content_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def user_settings() -> dict:
"label": "testcase",
"add": {"stop_info": "Testcase finished"},
},
"logging": {
"replace": {"message": "msg", "sessionId": "id"},
},
}


Expand Down Expand Up @@ -107,7 +110,7 @@ def user_settings_patched() -> dict:
"logging": {
"tag": "run",
"label": "pytest",
"replace": {"status": "state", "sessionId": "id"},
"replace": {"message": "msg", "sessionId": "id"},
},
}

Expand Down Expand Up @@ -252,6 +255,59 @@ def test_patch_content(to_patch, expected, stage, user_settings_patched):
assert patched == expected


@pytest.mark.parametrize(
"to_patch,expected,stage,ignore",
[
(
{
"status": "start",
"stage": "session",
"sessionId": UNIQUE_IDENTIFIER,
},
{
"tag": "run",
"label": "test",
"state": "start",
"stage": "session",
"id": UNIQUE_IDENTIFIER,
"start_info": "Pytest started",
},
"pytest_sessionstart",
[],
),
(
{
"type": "logging",
"stage": "testcase",
"message": "Logged from test_base",
"sessionId": UNIQUE_IDENTIFIER,
},
{
"type": "logging",
"stage": "testcase",
"id": UNIQUE_IDENTIFIER,
"msg": "Logged from test_base",
},
"logging",
["tag", "label"],
),
],
)
def test_patch(
to_patch,
expected,
stage,
ignore,
user_settings,
namespace,
stage_names,
):
patched = ContentPatcher(user_settings, namespace, stage_names).patch(
to_patch, stage, ignore
)
assert patched == expected


def test_get_tag_and_label(
user_settings, namespace, stage_names, user_settings_patched
):
Expand Down

0 comments on commit 7340227

Please sign in to comment.