mirror of
https://github.com/sprockets/sprockets.http.git
synced 2024-11-14 19:29:28 +00:00
Merge pull request #43 from nvllsvm/sentry
Add optional sentry integration
This commit is contained in:
commit
5b38192836
4 changed files with 95 additions and 23 deletions
|
@ -1,4 +1,4 @@
|
||||||
-e .
|
-e '.[sentry]'
|
||||||
-r testing.txt
|
-r testing.txt
|
||||||
-r docs.txt
|
-r docs.txt
|
||||||
flake8==3.7.8
|
flake8==3.7.8
|
||||||
|
|
3
setup.py
3
setup.py
|
@ -34,6 +34,9 @@ setuptools.setup(
|
||||||
entry_points={
|
entry_points={
|
||||||
'distutils.commands': ['httprun=sprockets.http.runner:RunCommand'],
|
'distutils.commands': ['httprun=sprockets.http.runner:RunCommand'],
|
||||||
},
|
},
|
||||||
|
extras_require={
|
||||||
|
'sentry': ['sentry-sdk>=1.5.4,<2'],
|
||||||
|
},
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 5 - Production/Stable',
|
'Development Status :: 5 - Production/Stable',
|
||||||
'Environment :: No Input/Output (Daemon)',
|
'Environment :: No Input/Output (Daemon)',
|
||||||
|
|
|
@ -1,8 +1,22 @@
|
||||||
import logging
|
import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
try:
|
||||||
|
import sentry_sdk
|
||||||
|
import sentry_sdk.integrations.logging
|
||||||
|
import sentry_sdk.integrations.tornado
|
||||||
|
|
||||||
|
_sentry_integrations = [
|
||||||
|
sentry_sdk.integrations.logging.LoggingIntegration(
|
||||||
|
event_level=logging.CRITICAL),
|
||||||
|
sentry_sdk.integrations.tornado.TornadoIntegration(),
|
||||||
|
]
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
version_info = (2, 2, 0)
|
version_info = (2, 2, 0)
|
||||||
__version__ = '.'.join(str(v) for v in version_info)
|
__version__ = '.'.join(str(v) for v in version_info)
|
||||||
|
@ -77,8 +91,18 @@ def run(create_application, settings=None, log_config=_unspecified):
|
||||||
|
|
||||||
port_number = int(app_settings.pop('port', os.environ.get('PORT', 8000)))
|
port_number = int(app_settings.pop('port', os.environ.get('PORT', 8000)))
|
||||||
num_procs = int(app_settings.pop('number_of_procs', '0'))
|
num_procs = int(app_settings.pop('number_of_procs', '0'))
|
||||||
server = runner.Runner(create_application(**app_settings))
|
app = create_application(**app_settings)
|
||||||
|
|
||||||
|
if 'sentry_sdk' in sys.modules:
|
||||||
|
kwargs = {
|
||||||
|
'integrations': _sentry_integrations,
|
||||||
|
'release': app.settings.get('version'),
|
||||||
|
'environment': app.settings.get('environment'),
|
||||||
|
}
|
||||||
|
kwargs.update(app.settings.get('sentry_sdk_init') or {})
|
||||||
|
sentry_sdk.init(**kwargs)
|
||||||
|
|
||||||
|
server = runner.Runner(app)
|
||||||
server.run(port_number, num_procs)
|
server.run(port_number, num_procs)
|
||||||
|
|
||||||
|
|
||||||
|
|
87
tests.py
87
tests.py
|
@ -234,76 +234,121 @@ class RunTests(MockHelper, unittest.TestCase):
|
||||||
self.logging_dict_config = self.start_mock(
|
self.logging_dict_config = self.start_mock(
|
||||||
'sprockets.http.logging.config').dictConfig
|
'sprockets.http.logging.config').dictConfig
|
||||||
|
|
||||||
|
self.app = mock.Mock()
|
||||||
|
self.app.settings = {}
|
||||||
|
self.create_app = mock.Mock(return_value=self.app)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def runner_instance(self):
|
def runner_instance(self):
|
||||||
return self.runner_cls.return_value
|
return self.runner_cls.return_value
|
||||||
|
|
||||||
def test_that_runner_run_called_with_created_application(self):
|
def test_that_runner_run_called_with_created_application(self):
|
||||||
create_app = mock.Mock()
|
sprockets.http.run(self.create_app)
|
||||||
sprockets.http.run(create_app)
|
self.assertEqual(self.create_app.call_count, 1)
|
||||||
self.assertEqual(create_app.call_count, 1)
|
self.runner_cls.assert_called_once_with(self.create_app.return_value)
|
||||||
self.runner_cls.assert_called_once_with(create_app.return_value)
|
|
||||||
|
|
||||||
def test_that_debug_envvar_enables_debug_flag(self):
|
def test_that_debug_envvar_enables_debug_flag(self):
|
||||||
create_app = mock.Mock()
|
|
||||||
with override_environment_variable(DEBUG='1'):
|
with override_environment_variable(DEBUG='1'):
|
||||||
sprockets.http.run(create_app)
|
sprockets.http.run(self.create_app)
|
||||||
create_app.assert_called_once_with(debug=True)
|
self.create_app.assert_called_once_with(debug=True)
|
||||||
self.get_logging_config.assert_called_once_with(True)
|
self.get_logging_config.assert_called_once_with(True)
|
||||||
|
|
||||||
def test_that_false_debug_envvar_disables_debug_flag(self):
|
def test_that_false_debug_envvar_disables_debug_flag(self):
|
||||||
create_app = mock.Mock()
|
|
||||||
with override_environment_variable(DEBUG='0'):
|
with override_environment_variable(DEBUG='0'):
|
||||||
sprockets.http.run(create_app)
|
sprockets.http.run(self.create_app)
|
||||||
create_app.assert_called_once_with(debug=False)
|
self.create_app.assert_called_once_with(debug=False)
|
||||||
self.get_logging_config.assert_called_once_with(False)
|
self.get_logging_config.assert_called_once_with(False)
|
||||||
|
|
||||||
def test_that_unset_debug_envvar_disables_debug_flag(self):
|
def test_that_unset_debug_envvar_disables_debug_flag(self):
|
||||||
create_app = mock.Mock()
|
|
||||||
with override_environment_variable(DEBUG=None):
|
with override_environment_variable(DEBUG=None):
|
||||||
sprockets.http.run(create_app)
|
sprockets.http.run(self.create_app)
|
||||||
create_app.assert_called_once_with(debug=False)
|
self.create_app.assert_called_once_with(debug=False)
|
||||||
self.get_logging_config.assert_called_once_with(False)
|
self.get_logging_config.assert_called_once_with(False)
|
||||||
|
|
||||||
def test_that_port_defaults_to_8000(self):
|
def test_that_port_defaults_to_8000(self):
|
||||||
sprockets.http.run(mock.Mock())
|
sprockets.http.run(self.create_app)
|
||||||
self.runner_instance.run.assert_called_once_with(8000, mock.ANY)
|
self.runner_instance.run.assert_called_once_with(8000, mock.ANY)
|
||||||
|
|
||||||
def test_that_port_envvar_sets_port_number(self):
|
def test_that_port_envvar_sets_port_number(self):
|
||||||
with override_environment_variable(PORT='8888'):
|
with override_environment_variable(PORT='8888'):
|
||||||
sprockets.http.run(mock.Mock())
|
sprockets.http.run(self.create_app)
|
||||||
self.runner_instance.run.assert_called_once_with(8888, mock.ANY)
|
self.runner_instance.run.assert_called_once_with(8888, mock.ANY)
|
||||||
|
|
||||||
def test_that_port_kwarg_sets_port_number(self):
|
def test_that_port_kwarg_sets_port_number(self):
|
||||||
sprockets.http.run(mock.Mock(), settings={'port': 8888})
|
sprockets.http.run(self.create_app, settings={'port': 8888})
|
||||||
self.runner_instance.run.assert_called_once_with(8888, mock.ANY)
|
self.runner_instance.run.assert_called_once_with(8888, mock.ANY)
|
||||||
|
|
||||||
def test_that_number_of_procs_defaults_to_zero(self):
|
def test_that_number_of_procs_defaults_to_zero(self):
|
||||||
sprockets.http.run(mock.Mock())
|
sprockets.http.run(self.create_app)
|
||||||
self.runner_instance.run.assert_called_once_with(mock.ANY, 0)
|
self.runner_instance.run.assert_called_once_with(mock.ANY, 0)
|
||||||
|
|
||||||
def test_that_number_of_process_kwarg_sets_number_of_procs(self):
|
def test_that_number_of_process_kwarg_sets_number_of_procs(self):
|
||||||
sprockets.http.run(mock.Mock(), settings={'number_of_procs': 1})
|
sprockets.http.run(self.create_app, settings={'number_of_procs': 1})
|
||||||
self.runner_instance.run.assert_called_once_with(mock.ANY, 1)
|
self.runner_instance.run.assert_called_once_with(mock.ANY, 1)
|
||||||
|
|
||||||
def test_that_logging_dict_config_is_called_appropriately(self):
|
def test_that_logging_dict_config_is_called_appropriately(self):
|
||||||
sprockets.http.run(mock.Mock())
|
sprockets.http.run(self.create_app)
|
||||||
self.logging_dict_config.assert_called_once_with(
|
self.logging_dict_config.assert_called_once_with(
|
||||||
self.get_logging_config.return_value)
|
self.get_logging_config.return_value)
|
||||||
|
|
||||||
def test_that_logconfig_override_is_used(self):
|
def test_that_logconfig_override_is_used(self):
|
||||||
sprockets.http.run(mock.Mock(), log_config=mock.sentinel.config)
|
sprockets.http.run(self.create_app, log_config=mock.sentinel.config)
|
||||||
self.logging_dict_config.assert_called_once_with(
|
self.logging_dict_config.assert_called_once_with(
|
||||||
mock.sentinel.config)
|
mock.sentinel.config)
|
||||||
|
|
||||||
def test_that_not_specifying_logging_config_is_deprecated(self):
|
def test_that_not_specifying_logging_config_is_deprecated(self):
|
||||||
with warnings.catch_warnings(record=True) as captured:
|
with warnings.catch_warnings(record=True) as captured:
|
||||||
warnings.simplefilter('always')
|
warnings.simplefilter('always')
|
||||||
sprockets.http.run(mock.Mock())
|
sprockets.http.run(self.create_app)
|
||||||
|
|
||||||
self.assertEqual(len(captured), 1)
|
self.assertEqual(len(captured), 1)
|
||||||
self.assertTrue(issubclass(captured[0].category, DeprecationWarning))
|
self.assertTrue(issubclass(captured[0].category, DeprecationWarning))
|
||||||
|
|
||||||
|
@mock.patch('sentry_sdk.init')
|
||||||
|
def test_that_sentry_is_initialized_with_implied_overrides(
|
||||||
|
self, mock_sentry_init):
|
||||||
|
self.app.settings = {
|
||||||
|
'environment': 'whatever',
|
||||||
|
'version': 'a.b.c',
|
||||||
|
}
|
||||||
|
sprockets.http.run(self.create_app)
|
||||||
|
mock_sentry_init.assert_called_once_with(
|
||||||
|
integrations=sprockets.http._sentry_integrations,
|
||||||
|
release='a.b.c',
|
||||||
|
environment='whatever',
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch('sentry_sdk.init')
|
||||||
|
def test_that_sentry_is_initialized_with_explicit_overrides(
|
||||||
|
self, mock_sentry_init):
|
||||||
|
self.app.settings = {
|
||||||
|
'sentry_sdk_init': {
|
||||||
|
'before_send': mock.sentinel.before_send,
|
||||||
|
'integrations': mock.sentinel.integrations,
|
||||||
|
'environment': mock.sentinel.environment,
|
||||||
|
'release': mock.sentinel.release,
|
||||||
|
},
|
||||||
|
'environment': 'whatever',
|
||||||
|
'version': 'a.b.c',
|
||||||
|
}
|
||||||
|
sprockets.http.run(self.create_app)
|
||||||
|
mock_sentry_init.assert_called_once_with(
|
||||||
|
integrations=mock.sentinel.integrations,
|
||||||
|
before_send=mock.sentinel.before_send,
|
||||||
|
release=mock.sentinel.release,
|
||||||
|
environment=mock.sentinel.environment,
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch('sentry_sdk.init')
|
||||||
|
def test_that_sentry_is_initialized_with_defaults(self, mock_sentry_init):
|
||||||
|
self.app.settings = {}
|
||||||
|
sprockets.http.run(self.create_app)
|
||||||
|
mock_sentry_init.assert_called_once_with(
|
||||||
|
integrations=sprockets.http._sentry_integrations,
|
||||||
|
release=None,
|
||||||
|
environment=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CallbackTests(MockHelper, unittest.TestCase):
|
class CallbackTests(MockHelper, unittest.TestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue