From ca3d9eb01204652ebf9b9e6abd6265201b600edb Mon Sep 17 00:00:00 2001 From: kkedziak Date: Thu, 22 Feb 2024 13:05:43 +0100 Subject: [PATCH 1/8] Add exception logging in Script --- splunklib/modularinput/event_writer.py | 21 ++++++++++++++++ splunklib/modularinput/script.py | 7 +++--- tests/modularinput/test_event.py | 28 +++++++++++++++++++++ tests/modularinput/test_script.py | 35 ++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 4 deletions(-) diff --git a/splunklib/modularinput/event_writer.py b/splunklib/modularinput/event_writer.py index 38a110c12..07347725d 100644 --- a/splunklib/modularinput/event_writer.py +++ b/splunklib/modularinput/event_writer.py @@ -14,6 +14,7 @@ from __future__ import absolute_import import sys +import traceback from splunklib.six import ensure_str from .event import ET @@ -23,6 +24,7 @@ except ImportError: from splunklib.six import StringIO + class EventWriter(object): """``EventWriter`` writes events and error messages to Splunk from a modular input. Its two important methods are ``writeEvent``, which takes an ``Event`` object, @@ -71,6 +73,25 @@ def log(self, severity, message): self._err.write("%s %s\n" % (severity, message)) self._err.flush() + def log_exception(self, message, exception=None, severity=None): + """Logs messages about the exception thrown by this modular input to Splunk. + These messages will show up in Splunk's internal logs. + + :param message: ``string``, message to log. + :param exception: ``Exception``, exception thrown by this modular input; if none, sys.exc_info() is used + :param severity: ``string``, severity of message, see severities defined as class constants. Default: ERROR + """ + if exception is not None: + tb_str = traceback.format_exception(type(exception), exception, exception.__traceback__) + else: + tb_str = traceback.format_exc() + + if severity is None: + severity = EventWriter.ERROR + + self._err.write(("%s %s - %s" % (severity, message, tb_str)).replace("\n", " ")) + self._err.flush() + def write_xml_document(self, document): """Writes a string representation of an ``ElementTree`` object to the output stream. diff --git a/splunklib/modularinput/script.py b/splunklib/modularinput/script.py index 8595dc4bd..fe9ebbe7f 100644 --- a/splunklib/modularinput/script.py +++ b/splunklib/modularinput/script.py @@ -99,13 +99,12 @@ def run_script(self, args, event_writer, input_stream): return 1 else: - err_string = "ERROR Invalid arguments to modular input script:" + ' '.join( - args) - event_writer._err.write(err_string) + event_writer.log(EventWriter.ERROR, "Invalid arguments to modular input script:" + ' '.join( + args)) return 1 except Exception as e: - event_writer.log(EventWriter.ERROR, str(e)) + event_writer.log_exception(str(e)) return 1 @property diff --git a/tests/modularinput/test_event.py b/tests/modularinput/test_event.py index 865656031..03bf2de94 100644 --- a/tests/modularinput/test_event.py +++ b/tests/modularinput/test_event.py @@ -16,7 +16,9 @@ from __future__ import absolute_import +import re import sys +from io import StringIO import pytest @@ -151,3 +153,29 @@ def test_write_xml_is_sane(capsys): found_xml = ET.fromstring(captured.out) assert xml_compare(expected_xml, found_xml) + + +def test_log_exception(): + out, err = StringIO(), StringIO() + ew = EventWriter(out, err) + + exc = Exception("Something happened!") + + try: + raise exc + except: + ew.log_exception("ex1") + + assert out.getvalue() == "" + + # Remove paths and line + err = re.sub(r'File "[^"]+', 'File "...', err.getvalue()) + err = re.sub(r'line \d+', 'line 123', err) + + # One line + assert err == ( + 'ERROR ex1 - Traceback (most recent call last): ' + ' File "...", line 123, in test_log_exception ' + ' raise exc ' + 'Exception: Something happened! ' + ) diff --git a/tests/modularinput/test_script.py b/tests/modularinput/test_script.py index b15885dc7..9bdcb562f 100644 --- a/tests/modularinput/test_script.py +++ b/tests/modularinput/test_script.py @@ -3,6 +3,7 @@ from splunklib.client import Service from splunklib.modularinput import Script, EventWriter, Scheme, Argument, Event import io +import re from splunklib.modularinput.utils import xml_compare from tests.modularinput.modularinput_testlib import data_open @@ -231,3 +232,37 @@ def stream_events(self, inputs, ew): assert output.err == "" assert isinstance(script.service, Service) assert script.service.authority == script.authority_uri + + +def test_log_script_exception(monkeypatch): + out, err = io.StringIO(), io.StringIO() + + # Override abstract methods + class NewScript(Script): + def get_scheme(self): + return None + + def stream_events(self, inputs, ew): + raise RuntimeError("Some error") + + script = NewScript() + input_configuration = data_open("data/conf_with_2_inputs.xml") + + ew = EventWriter(out, err) + + assert script.run_script([TEST_SCRIPT_PATH], ew, input_configuration) == 1 + + # Remove paths and line numbers + err = re.sub(r'File "[^"]+', 'File "...', err.getvalue()) + err = re.sub(r'line \d+', 'line 123', err) + + assert out.getvalue() == "" + assert err == ( + 'ERROR Some error - ' + 'Traceback (most recent call last): ' + ' File "...", line 123, in run_script ' + ' self.stream_events(self._input_definition, event_writer) ' + ' File "...", line 123, in stream_events ' + ' raise RuntimeError("Some error") ' + 'RuntimeError: Some error ' + ) From 06a97b66fe3c4a041e3f959d202c2075c69c8ff4 Mon Sep 17 00:00:00 2001 From: maszyk99 Date: Tue, 26 Mar 2024 11:29:03 +0100 Subject: [PATCH 2/8] Add next release number --- README.md | 2 +- splunklib/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2bbae4de9..0969bbc2b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # The Splunk Enterprise Software Development Kit for Python -#### Version 2.0.0 +#### Version 2.0.1 The Splunk Enterprise Software Development Kit (SDK) for Python contains library code designed to enable developers to build applications using the Splunk platform. diff --git a/splunklib/__init__.py b/splunklib/__init__.py index 2613d2849..c86dfdb8a 100644 --- a/splunklib/__init__.py +++ b/splunklib/__init__.py @@ -30,5 +30,5 @@ def setup_logging(level, log_format=DEFAULT_LOG_FORMAT, date_format=DEFAULT_DATE datefmt=date_format) -__version_info__ = (2, 0, 0) +__version_info__ = (2, 0, 1) __version__ = ".".join(map(str, __version_info__)) From 91f2bec08d59ec79b1efe3e79d1114c217f55687 Mon Sep 17 00:00:00 2001 From: maszyk99 Date: Tue, 26 Mar 2024 11:37:20 +0100 Subject: [PATCH 3/8] Mention bugfix in changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e423e67d..87d27a229 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Splunk Enterprise SDK for Python Changelog +## Version 2.0.1 + +### Bug fixes +* [#567](https://github.com/splunk/splunk-sdk-python/issues/567) Moved "deprecation" dependency + + ## Version 2.0.0 ### Feature updates From 2869237ec343d0cf0fe5a1cec6ee03f61bb7ac38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20K=C4=99dziak?= Date: Fri, 5 Apr 2024 14:38:45 +0200 Subject: [PATCH 4/8] Revert CHANGELOG.md --- CHANGELOG.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87d27a229..0e423e67d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,5 @@ # Splunk Enterprise SDK for Python Changelog -## Version 2.0.1 - -### Bug fixes -* [#567](https://github.com/splunk/splunk-sdk-python/issues/567) Moved "deprecation" dependency - - ## Version 2.0.0 ### Feature updates From e5f7af0f64afe582c5893726e6cb77e78e5356a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20K=C4=99dziak?= Date: Fri, 5 Apr 2024 14:39:15 +0200 Subject: [PATCH 5/8] Revert README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0969bbc2b..2bbae4de9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # The Splunk Enterprise Software Development Kit for Python -#### Version 2.0.1 +#### Version 2.0.0 The Splunk Enterprise Software Development Kit (SDK) for Python contains library code designed to enable developers to build applications using the Splunk platform. From 3dab0b528bb429f5b8c795f86294f0f4a6853f16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20K=C4=99dziak?= Date: Fri, 5 Apr 2024 14:39:36 +0200 Subject: [PATCH 6/8] Update __init__.py --- splunklib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splunklib/__init__.py b/splunklib/__init__.py index c86dfdb8a..2613d2849 100644 --- a/splunklib/__init__.py +++ b/splunklib/__init__.py @@ -30,5 +30,5 @@ def setup_logging(level, log_format=DEFAULT_LOG_FORMAT, date_format=DEFAULT_DATE datefmt=date_format) -__version_info__ = (2, 0, 1) +__version_info__ = (2, 0, 0) __version__ = ".".join(map(str, __version_info__)) From be7dfe04ead6d1f6e5912afa646ecb78abae4856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20K=C4=99dziak?= Date: Wed, 8 May 2024 12:33:38 +0000 Subject: [PATCH 7/8] Refactor comment --- splunklib/modularinput/event_writer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splunklib/modularinput/event_writer.py b/splunklib/modularinput/event_writer.py index cdf694ee9..7be3845ab 100644 --- a/splunklib/modularinput/event_writer.py +++ b/splunklib/modularinput/event_writer.py @@ -73,7 +73,7 @@ def log_exception(self, message, exception=None, severity=None): :param message: ``string``, message to log. :param exception: ``Exception``, exception thrown by this modular input; if none, sys.exc_info() is used - :param severity: ``string``, severity of message, see severities defined as class constants. Default: ERROR + :param severity: ``string``, severity of message, see severities defined as class constants. Default severity: ERROR """ if exception is not None: tb_str = traceback.format_exception(type(exception), exception, exception.__traceback__) From 3ef0519242ebf7733aae41c965801242427bd7b6 Mon Sep 17 00:00:00 2001 From: kkedziak Date: Tue, 21 May 2024 15:01:24 +0200 Subject: [PATCH 8/8] Change --- tests/modularinput/test_event.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modularinput/test_event.py b/tests/modularinput/test_event.py index 3180feb62..35e9c09cd 100644 --- a/tests/modularinput/test_event.py +++ b/tests/modularinput/test_event.py @@ -162,7 +162,7 @@ def test_log_exception(): try: raise exc - except: + except Exception: ew.log_exception("ex1") assert out.getvalue() == ""