Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]
)