From 4befc6fa7be7db0215f0f2cb8eaf680923fa52f8 Mon Sep 17 00:00:00 2001 From: NeonKirill Date: Sat, 6 Apr 2024 17:48:02 +0200 Subject: [PATCH 1/6] Added support for initializing Sentry along with general support for log aggregators integration --- neon_utils/log_aggregators/__init__.py | 51 ++++++++++++++++++++++++++ neon_utils/log_aggregators/sentry.py | 33 +++++++++++++++++ neon_utils/logger.py | 3 ++ requirements/sentry.txt | 1 + setup.py | 3 +- 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 neon_utils/log_aggregators/__init__.py create mode 100644 neon_utils/log_aggregators/sentry.py create mode 100644 requirements/sentry.txt diff --git a/neon_utils/log_aggregators/__init__.py b/neon_utils/log_aggregators/__init__.py new file mode 100644 index 00000000..7da3cefc --- /dev/null +++ b/neon_utils/log_aggregators/__init__.py @@ -0,0 +1,51 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework +# All trademark and other rights reserved by their respective owners +# Copyright 2008-2022 Neongecko.com Inc. +# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds, +# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo +# BSD-3 License +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import importlib + +_service_name_to_handler = { + 'sentry': 'init_sentry' +} + + +def init_log_aggregators(): + from ovos_config.config import Configuration + config = Configuration() + for service_name, handler in _service_name_to_handler.items(): + service_config = _get_log_aggregator_config(config=config, name=service_name) + if not bool(service_config.get('enabled')): + service_module = importlib.import_module('.', service_name) + getattr(service_module, handler)(config=service_config) + + +def _get_log_aggregator_config(config: dict, name: str): + return config.get('logs', {}).get('aggregators', {}).get(name, {}) + + +if __name__ == '__main__': + init_log_aggregators() diff --git a/neon_utils/log_aggregators/sentry.py b/neon_utils/log_aggregators/sentry.py new file mode 100644 index 00000000..29e59220 --- /dev/null +++ b/neon_utils/log_aggregators/sentry.py @@ -0,0 +1,33 @@ +# NEON AI (TM) SOFTWARE, Software Development Kit & Application Framework +# All trademark and other rights reserved by their respective owners +# Copyright 2008-2022 Neongecko.com Inc. +# Contributors: Daniel McKnight, Guy Daniels, Elon Gasper, Richard Leeds, +# Regina Bloomstine, Casimiro Ferreira, Andrii Pernatii, Kirill Hrymailo +# BSD-3 License +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import sentry_sdk + + +def init_sentry(config: dict): + return sentry_sdk.init(**config) diff --git a/neon_utils/logger.py b/neon_utils/logger.py index 9cc1d1db..85a8681c 100644 --- a/neon_utils/logger.py +++ b/neon_utils/logger.py @@ -27,7 +27,10 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from ovos_utils.log import LOG +from neon_utils.log_aggregators import init_log_aggregators if LOG.name == 'OVOS': LOG.name = 'neon-utils' # TODO: Deprecate this backwards-compat import in 2.0.0 + +init_log_aggregators() diff --git a/requirements/sentry.txt b/requirements/sentry.txt new file mode 100644 index 00000000..4b614c79 --- /dev/null +++ b/requirements/sentry.txt @@ -0,0 +1 @@ +sentry-sdk \ No newline at end of file diff --git a/setup.py b/setup.py index d3fe875c..93e6697f 100644 --- a/setup.py +++ b/setup.py @@ -85,7 +85,8 @@ def get_requirements(requirements_filename: str): "test": get_requirements("test_requirements.txt"), "audio": get_requirements("audio.txt"), "network": get_requirements("network.txt"), - "configuration": get_requirements("configuration.txt") + "configuration": get_requirements("configuration.txt"), + "sentry": get_requirements("sentry.txt") }, entry_points={ 'console_scripts': [ From e17e25f1547766c08b908bf40e30ebc4432c75c4 Mon Sep 17 00:00:00 2001 From: NeonKirill Date: Sat, 6 Apr 2024 17:49:22 +0200 Subject: [PATCH 2/6] small fix --- neon_utils/log_aggregators/__init__.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/neon_utils/log_aggregators/__init__.py b/neon_utils/log_aggregators/__init__.py index 7da3cefc..828bcf71 100644 --- a/neon_utils/log_aggregators/__init__.py +++ b/neon_utils/log_aggregators/__init__.py @@ -38,14 +38,10 @@ def init_log_aggregators(): config = Configuration() for service_name, handler in _service_name_to_handler.items(): service_config = _get_log_aggregator_config(config=config, name=service_name) - if not bool(service_config.get('enabled')): + if bool(service_config.get('enabled')): service_module = importlib.import_module('.', service_name) getattr(service_module, handler)(config=service_config) def _get_log_aggregator_config(config: dict, name: str): return config.get('logs', {}).get('aggregators', {}).get(name, {}) - - -if __name__ == '__main__': - init_log_aggregators() From 13e2e0ed6f19e89ded946f6a6b606a00a9499979 Mon Sep 17 00:00:00 2001 From: NeonKirill Date: Mon, 13 May 2024 01:11:55 +0200 Subject: [PATCH 3/6] Added optional config param for init_log_aggregators --- neon_utils/log_aggregators/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neon_utils/log_aggregators/__init__.py b/neon_utils/log_aggregators/__init__.py index 828bcf71..7c0367f6 100644 --- a/neon_utils/log_aggregators/__init__.py +++ b/neon_utils/log_aggregators/__init__.py @@ -33,9 +33,9 @@ } -def init_log_aggregators(): +def init_log_aggregators(config: dict = None): from ovos_config.config import Configuration - config = Configuration() + config = config or Configuration() for service_name, handler in _service_name_to_handler.items(): service_config = _get_log_aggregator_config(config=config, name=service_name) if bool(service_config.get('enabled')): From f68b7a7a76b3dad3511e17ebccfd8e932131dfca Mon Sep 17 00:00:00 2001 From: NeonKirill Date: Mon, 13 May 2024 01:27:06 +0200 Subject: [PATCH 4/6] fixed relative import --- neon_utils/log_aggregators/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neon_utils/log_aggregators/__init__.py b/neon_utils/log_aggregators/__init__.py index 7c0367f6..5223933e 100644 --- a/neon_utils/log_aggregators/__init__.py +++ b/neon_utils/log_aggregators/__init__.py @@ -39,7 +39,7 @@ def init_log_aggregators(config: dict = None): for service_name, handler in _service_name_to_handler.items(): service_config = _get_log_aggregator_config(config=config, name=service_name) if bool(service_config.get('enabled')): - service_module = importlib.import_module('.', service_name) + service_module = importlib.import_module(f'.{service_name}', __name__) getattr(service_module, handler)(config=service_config) From b1acfee63edb7363ca7f3fb47ba53046b43d902f Mon Sep 17 00:00:00 2001 From: NeonKirill Date: Mon, 13 May 2024 01:28:44 +0200 Subject: [PATCH 5/6] preventing "enabled" to be populated to Sentry --- neon_utils/log_aggregators/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neon_utils/log_aggregators/__init__.py b/neon_utils/log_aggregators/__init__.py index 5223933e..10d80db5 100644 --- a/neon_utils/log_aggregators/__init__.py +++ b/neon_utils/log_aggregators/__init__.py @@ -38,7 +38,7 @@ def init_log_aggregators(config: dict = None): config = config or Configuration() for service_name, handler in _service_name_to_handler.items(): service_config = _get_log_aggregator_config(config=config, name=service_name) - if bool(service_config.get('enabled')): + if bool(service_config.pop('enabled', False)): service_module = importlib.import_module(f'.{service_name}', __name__) getattr(service_module, handler)(config=service_config) From 7c7e405579b0687ed4d3dd278b17d7ca5ad63ad0 Mon Sep 17 00:00:00 2001 From: kgrim Date: Thu, 3 Oct 2024 13:55:20 +0200 Subject: [PATCH 6/6] Added validation on required configuration keys in Sentry SDK --- neon_utils/log_aggregators/sentry.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/neon_utils/log_aggregators/sentry.py b/neon_utils/log_aggregators/sentry.py index 29e59220..29fecb74 100644 --- a/neon_utils/log_aggregators/sentry.py +++ b/neon_utils/log_aggregators/sentry.py @@ -28,6 +28,11 @@ import sentry_sdk +SENTRY_SDK_REQUIRED_KEYS = {'dsn'} + def init_sentry(config: dict): + missing_required_keys = SENTRY_SDK_REQUIRED_KEYS.difference(config.keys()) + if missing_required_keys: + raise KeyError(f'Sentry SDK configuration missing required keys: {missing_required_keys}') return sentry_sdk.init(**config)