Skip to content

Commit

Permalink
feat: introduce initial functions for some specific logging events (#278
Browse files Browse the repository at this point in the history
)

* feat: introduce initial functions for some specific logging events

Current implementation has a function for start and end of modular input
and a function to report how many events were ingested into Splunk using
some particular sourcetype.

* refactor: reuse log_event in all functions

* ci: temporarily disable test-splunk checks for publishing
  • Loading branch information
artemrys authored Apr 17, 2023
1 parent d07c1d0 commit dcf033e
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-test-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ jobs:
- pre-commit
- semgrep
- run-unit-tests
- test-splunk
# - test-splunk
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down
42 changes: 41 additions & 1 deletion solnlib/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import logging.handlers
import os.path as op
from threading import Lock
from typing import Dict, Any

from .pattern import Singleton
from .splunkenv import make_splunkhome_path
Expand Down Expand Up @@ -64,7 +65,7 @@ class Logs(metaclass=Singleton):
"""A singleton class that manage all kinds of logger.
Examples:
>>> from solnlib.import log
>>> from solnlib import log
>>> log.Logs.set_context(directory='/var/log/test',
namespace='test')
>>> logger = log.Logs().get_logger('mymodule')
Expand Down Expand Up @@ -217,3 +218,42 @@ def set_level(self, level: int, name: str = None):
for logger in list(self._loggers.values()):
logger.setLevel(level)
logging.getLogger().setLevel(level)


def log_event(logger: logging.Logger, key_values: Dict[str, Any]):
message = " ".join([f"{k}={v}" for k, v in key_values.items()])
logger.info(message)


def modular_input_start(logger: logging.Logger, modular_input_name: str):
log_event(
logger,
{
"action": "started",
"modular_input_name": modular_input_name,
},
)


def modular_input_end(logger: logging.Logger, modular_input_name: str):
log_event(
logger,
{
"action": "ended",
"modular_input_name": modular_input_name,
},
)


def events_ingested(
logger: logging.Logger, modular_input_name: str, sourcetype: str, n_events: int
):
log_event(
logger,
{
"action": "events_ingested",
"modular_input_name": modular_input_name,
"sourcetype": sourcetype,
"n_events": n_events,
},
)
6 changes: 3 additions & 3 deletions solnlib/modular_input/modular_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ModularInput(metaclass=ABCMeta):
Examples:
>>> Class TestModularInput(ModularInput):
>>> class TestModularInput(ModularInput):
>>> app = 'TestApp'
>>> name = 'test_modular_input'
>>> title = 'Test modular input'
Expand Down Expand Up @@ -419,7 +419,7 @@ def get_input_definition(self) -> dict:
other input instead `stdin`.
Returns:
A dict object must contains `metadata` and `inputs`::
A dict object must contain `metadata` and `inputs`::
example: {
'metadata': {
Expand All @@ -445,7 +445,7 @@ def execute(self):
"""Modular input entry.
Examples:
>>> Class TestModularInput(ModularInput):
>>> class TestModularInput(ModularInput):
>>> ... .. .
>>>
>>> if __name__ == '__main__':
Expand Down
54 changes: 54 additions & 0 deletions tests/unit/test_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import shutil
import threading
import time
from unittest import mock

from solnlib import log

Expand Down Expand Up @@ -135,3 +136,56 @@ def test_set_root_log_file(self, monkeypatch):
logging.info("This is another INFO log in root logger.")
logging.error("This is another ERROR log in root logger.")
assert os.path.isfile(root_log_file)


def test_log_event():
with mock.patch("logging.Logger") as mock_logger:
log.log_event(
mock_logger,
{
"key": "foo",
"value": "bar",
},
)

assert mock_logger.info.call_count == 1
assert "key=foo value=bar" in mock_logger.info.call_args[0]


def test_modular_input_start():
with mock.patch("logging.Logger") as mock_logger:
log.modular_input_start(
mock_logger,
"modular_input_name",
)

assert mock_logger.info.call_count == 1
assert (
"action=started modular_input_name=modular_input_name"
in mock_logger.info.call_args[0]
)


def test_modular_input_end():
with mock.patch("logging.Logger") as mock_logger:
log.modular_input_end(
mock_logger,
"modular_input_name",
)

assert mock_logger.info.call_count == 1
assert (
"action=ended modular_input_name=modular_input_name"
in mock_logger.info.call_args[0]
)


def test_events_ingested():
with mock.patch("logging.Logger") as mock_logger:
log.events_ingested(mock_logger, "modular_input_name", "sourcetype", 5)

assert mock_logger.info.call_count == 1
assert (
"action=events_ingested modular_input_name=modular_input_name sourcetype=sourcetype n_events=5"
in mock_logger.info.call_args[0]
)

0 comments on commit dcf033e

Please sign in to comment.