def test_transaction_with_error( sentry_init, crashing_app, capture_events, DictionaryContaining # noqa:N803 ): def dogpark(environ, start_response): raise Exception("Fetch aborted. The ball was not returned.") sentry_init(send_default_pii=True, traces_sample_rate=1.0) app = SentryWsgiMiddleware(dogpark) client = Client(app) events = capture_events() with pytest.raises(Exception): client.get("http://dogs.are.great/sit/stay/rollover/") error_event, envelope = events assert error_event["transaction"] == "generic WSGI request" assert error_event["contexts"]["trace"]["op"] == "http.server" assert error_event["exception"]["values"][0]["type"] == "Exception" assert (error_event["exception"]["values"][0]["value"] == "Fetch aborted. The ball was not returned.") assert envelope["type"] == "transaction" # event trace context is a subset of envelope trace context assert envelope["contexts"]["trace"] == DictionaryContaining( error_event["contexts"]["trace"]) assert envelope["contexts"]["trace"]["status"] == "internal_error" assert envelope["transaction"] == error_event["transaction"] assert envelope["request"] == error_event["request"]
def test_transaction_no_error( sentry_init, capture_events, DictionaryContaining # noqa:N803 ): def dogpark(environ, start_response): start_response("200 OK", []) return ["Go get the ball! Good dog!"] sentry_init(send_default_pii=True, traces_sample_rate=1.0) app = SentryWsgiMiddleware(dogpark) client = Client(app) events = capture_events() client.get("/dogs/are/great/") envelope = events[0] assert envelope["type"] == "transaction" assert envelope["transaction"] == "generic WSGI request" assert envelope["contexts"]["trace"]["op"] == "http.server" assert envelope["request"] == DictionaryContaining({ "method": "GET", "url": "http://localhost/dogs/are/great/" })
def make_middleware(self, app, config): # we get this called twice, once for Flask and once for Pylons if isinstance(app, PylonsApp): return SentryWsgiMiddleware(app) else: sentry_sdk.init(integrations=[FlaskIntegration()]) return app
def sentry_patched_wsgi_app(self, environ, start_response): if Hub.current.get_integration(FlaskIntegration) is None: return old_app(self, environ, start_response) return SentryWsgiMiddleware( lambda *a, **kw: old_app(self, *a, **kw))(environ, start_response)
def test_session_mode_defaults_to_request_mode_in_wsgi_handler( capture_envelopes, sentry_init): """ Test that ensures that even though the default `session_mode` for auto_session_tracking is `application`, that flips to `request` when we are in the WSGI handler """ def app(environ, start_response): start_response("200 OK", []) return ["Go get the ball! Good dog!"] traces_sampler = mock.Mock(return_value=True) sentry_init(send_default_pii=True, traces_sampler=traces_sampler) app = SentryWsgiMiddleware(app) envelopes = capture_envelopes() client = Client(app) client.get("/dogs/are/great/") sentry_sdk.flush() sess = envelopes[1] assert len(sess.items) == 1 sess_event = sess.items[0].payload.json aggregates = sess_event["aggregates"] assert len(aggregates) == 1 assert aggregates[0]["exited"] == 1
def test_traces_sampler_gets_correct_values_in_sampling_context( sentry_init, DictionaryContaining, ObjectDescribedBy # noqa:N803 ): def app(environ, start_response): start_response("200 OK", []) return ["Go get the ball! Good dog!"] traces_sampler = mock.Mock(return_value=True) sentry_init(send_default_pii=True, traces_sampler=traces_sampler) app = SentryWsgiMiddleware(app) client = Client(app) client.get("/dogs/are/great/") traces_sampler.assert_any_call( DictionaryContaining({ "wsgi_environ": DictionaryContaining( { "PATH_INFO": "/dogs/are/great/", "REQUEST_METHOD": "GET", }, ), }))
def test_basic(sentry_init, crashing_app, capture_events): sentry_init(send_default_pii=True) app = SentryWsgiMiddleware(crashing_app) client = Client(app) events = capture_events() with pytest.raises(ZeroDivisionError): client.get("/") event, = events assert event["request"] == { "env": { "SERVER_NAME": "localhost", "SERVER_PORT": "80" }, "headers": { "Content-Length": "0", "Content-Type": "", "Host": "localhost" }, "method": "GET", "query_string": "", "url": "http://localhost/", }
def sentry_patched_wsgi_handler(self, environ, start_response): # type: (Any, Dict[str, str], Callable[..., Any]) -> _ScopedResponse if Hub.current.get_integration(DjangoIntegration) is None: return old_app(self, environ, start_response) bound_old_app = old_app.__get__(self, WSGIHandler) return SentryWsgiMiddleware(bound_old_app)(environ, start_response)
def sentry_patched_wsgi_app(self, environ, start_response): # type: (Any, Dict[str, str], Callable[..., Any]) -> _ScopedResponse if Hub.current.get_integration(FlaskIntegration) is None: return old_app(self, environ, start_response) return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))( environ, start_response )
def sentry_patched_wsgi_call(self, environ, start_response): hub = Hub.current integration = hub.get_integration(PyramidIntegration) if integration is None: return old_wsgi_call(self, environ, start_response) return SentryWsgiMiddleware( lambda *a, **kw: old_wsgi_call(self, *a, **kw))(environ, start_response)
def sentry_patched_wsgi_app(self, env, start_response): hub = Hub.current integration = hub.get_integration(FalconIntegration) if integration is None: return original_wsgi_app(self, env, start_response) sentry_wrapped = SentryWsgiMiddleware( lambda envi, start_resp: original_wsgi_app(self, envi, start_resp)) return sentry_wrapped(env, start_response)
def sentry_patched_wsgi_call(self, environ, start_response): # type: (Any, Dict[str, str], Callable) -> _ScopedResponse hub = Hub.current integration = hub.get_integration(PyramidIntegration) if integration is None: return old_wsgi_call(self, environ, start_response) return SentryWsgiMiddleware(lambda *a, **kw: old_wsgi_call(self, *a, **kw))( environ, start_response )
def test_env_modifing_app(sentry_init, crashing_env_modifing_app, capture_events): sentry_init(send_default_pii=True) app = SentryWsgiMiddleware(crashing_env_modifing_app) client = Client(app) events = capture_events() with pytest.raises(ZeroDivisionError): client.get("/") assert len(events) == 1 # only one exception is raised
def test_systemexit_zero_is_ignored(sentry_init, capture_events, request): zero_code = request.param sentry_init(send_default_pii=True) iterable = ExitingIterable(lambda: SystemExit(zero_code)) app = SentryWsgiMiddleware(IterableApp(iterable)) client = Client(app) events = capture_events() with pytest.raises(SystemExit): client.get("/") assert len(events) == 0
def filter_wsgi_app(application: Callable[..., Any]) -> Callable[..., Any]: """If sentry is configured, add a Sentry filter around the application.""" if _client_setup: try: LOG.info("Enable WSGI filter for Sentry") return SentryWsgiMiddleware(application) except Exception: # pylint: disable=broad-except LOG.error("Failed enabling sentry. Continuing without it.", exc_info=True) return application else: return application
def initialize_sentry(config): """ Setup an instance of :class:`sentry_sdk.Client`. :param config: Sentry configuration :param client: class used to instantiate the sentry_sdk client. """ enabled = config.get("sentry_enabled", False) if not (HAS_SENTRY_SDK and enabled): return _logger.info("Initializing sentry...") if config.get("sentry_odoo_dir") and config.get("sentry_release"): _logger.debug("Both sentry_odoo_dir and \ sentry_release defined, choosing sentry_release") options = { "release": config.get("sentry_release", get_odoo_commit(config.get("sentry_odoo_dir"))), } for option in const.get_sentry_options(): value = config.get('sentry_%s' % option.key, option.default) if isinstance(option.converter, collections.Callable): value = option.converter(value) options[option.key] = value exclude_loggers = const.split_multiple( config.get("sentry_exclude_loggers", const.DEFAULT_EXCLUDE_LOGGERS) ) # Change name `ignore_exceptions` (with raven) # to `ignore_errors' (sentry_sdk) options["ignore_errors"] = options["ignore_exceptions"] del options["ignore_exceptions"] options["before_send"] = before_send options["integrations"] = [options["logging_level"], ThreadingIntegration(propagate_hub=True)] # Remove logging_level, since in sentry_sdk is include in 'integrations' del options["logging_level"] client = sentry_sdk.init(**options) sentry_sdk.set_tag("include_context", config.get("sentry_include_context", True)) if exclude_loggers: for item in exclude_loggers: ignore_logger(item) wsgi_server.application = SentryWsgiMiddleware(wsgi_server.application) with sentry_sdk.push_scope() as scope: scope.set_extra("debug", False) sentry_sdk.capture_message("Starting Odoo Server", "info") return client
def make_application(config_path): """Construct a WSGI application for the AcoustID server :param config_path: path to the server configuration file """ server = Server(config_path) server.setup_sentry() app = GzipRequestMiddleware(server) app = ProxyFix(app) app = SentryWsgiMiddleware(app) app = replace_double_slashes(app) app = add_cors_headers(app) return server, app
def make_app_from_environ(): from werkzeug.middleware.proxy_fix import ProxyFix from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware app = App( dataset=os.environ.get("BIGQUERY_DATASET", "reload"), table=os.environ.get("BIGQUERY_TABLE", "page"), pubsub_project=os.environ.get("PUBSUB_PROJECT", "internal-sentry"), pubsub_topic=os.environ.get("PUBSUB_TOPIC", "analytics-events"), datadog_prefix=os.environ.get("DATADOG_PREFIX", ""), datadog_host=os.environ.get("DATADOG_HOST", "127.0.0.1"), datadog_port=int(os.environ.get("DATADOG_PORT", 8125)), ) return ProxyFix(SentryWsgiMiddleware(app))
def sentry_patched_wsgi_handler(self, environ, start_response): # type: (Any, Dict[str, str], Callable[..., Any]) -> _ScopedResponse if Hub.current.get_integration(DjangoIntegration) is None: return old_app(self, environ, start_response) bound_old_app = old_app.__get__(self, WSGIHandler) from django.conf import settings use_x_forwarded_for = settings.USE_X_FORWARDED_HOST return SentryWsgiMiddleware(bound_old_app, use_x_forwarded_for)(environ, start_response)
def make_error_log_middleware(self, app, config): for option in CONFIG_FROM_ENV_VARS: from_env = os.environ.get(CONFIG_FROM_ENV_VARS[option], None) if from_env: config[option] = from_env if not config.get('sentry.dsn') and os.environ.get('SENTRY_DSN'): config['sentry.dsn'] = os.environ['SENTRY_DSN'] if plugins.toolkit.asbool(config.get('sentry.configure_logging')): self._configure_logging(config) log.debug('Adding Sentry middleware...') sentry_sdk.init(dsn=config.get('sentry.dsn')) sentry = SentryWsgiMiddleware(app) return app
def make_application(config_path=None): # type: (Optional[str]) -> Server """Construct a WSGI application for the AcoustID server :param config_path: path to the server configuration file """ if config_path is None: config_path = os.environ.get('ACOUSTID_CONFIG', '') assert config_path is not None server = Server(config_path) server.setup_sentry() server.wsgi_app = GzipRequestMiddleware(server.wsgi_app) # type: ignore server.wsgi_app = SentryWsgiMiddleware(server.wsgi_app) # type: ignore server.wsgi_app = replace_double_slashes(server.wsgi_app) # type: ignore server.wsgi_app = add_cors_headers(server.wsgi_app) # type: ignore server.wsgi_app = ProxyFix(server.wsgi_app) # type: ignore return server
def test_keyboard_interrupt_is_captured(sentry_init, capture_events): sentry_init(send_default_pii=True) iterable = ExitingIterable(lambda: KeyboardInterrupt()) app = SentryWsgiMiddleware(IterableApp(iterable)) client = Client(app) events = capture_events() with pytest.raises(KeyboardInterrupt): client.get("/") event, = events assert "exception" in event exc = event["exception"]["values"][-1] assert exc["type"] == "KeyboardInterrupt" assert exc["value"] == "" assert event["level"] == "error"
def sentry_patched_wsgi_call(self, environ, start_response): # type: (Any, Dict[str, str], Callable) -> _ScopedResponse hub = Hub.current integration = hub.get_integration(PyramidIntegration) if integration is None: return old_wsgi_call(self, environ, start_response) def sentry_patched_inner_wsgi_call(environ, start_response): try: return old_wsgi_call(self, environ, start_response) except Exception: einfo = sys.exc_info() _capture_exception(einfo) reraise(*einfo) return SentryWsgiMiddleware(sentry_patched_inner_wsgi_call)( environ, start_response)
def test_systemexit_nonzero_is_captured(sentry_init, capture_events, request): nonzero_code = request.param sentry_init(send_default_pii=True) iterable = ExitingIterable(lambda: SystemExit(nonzero_code)) app = SentryWsgiMiddleware(IterableApp(iterable)) client = Client(app) events = capture_events() with pytest.raises(SystemExit): client.get("/") event, = events assert "exception" in event exc = event["exception"]["values"][-1] assert exc["type"] == "SystemExit" assert exc["value"] == nonzero_code assert event["level"] == "error"
def make_error_log_middleware(self, app, config): for option in CONFIG_FROM_ENV_VARS: from_env = os.environ.get(CONFIG_FROM_ENV_VARS[option], None) if from_env: config[option] = from_env if not config.get('sentry.dsn') and os.environ.get('SENTRY_DSN'): config['sentry.dsn'] = os.environ['SENTRY_DSN'] log.debug('Adding Sentry middleware...') sentry_sdk.init(dsn=config.get('sentry.dsn')) sentry_log_level = config.get('sentry.log_level', logging.INFO) set_level(sentry_log_level) log.debug( 'Setting up Sentry logger with level {0}'.format(sentry_log_level)) sentry = SentryWsgiMiddleware(app) return app
def enable_sentry(): logger = logging.getLogger('runbot_merge') dsn = environ.get('SENTRY_DSN') if not dsn: logger.info("No DSN found, skipping sentry...") return try: sentry_sdk.init( dsn, integrations=[ # note: if the colorformatter is enabled, sentry gets lost # and classifies everything as errors because it fails to # properly classify levels as the colorformatter injects # the ANSI color codes right into LogRecord.levelname LoggingIntegration(level=logging.INFO, event_level=logging.WARNING), ]) http.root = SentryWsgiMiddleware(http.root) except Exception: logger.exception("DSN found, failed to enable sentry...") else: logger.info("DSN found, sentry enabled...")
import json import sentry_sdk from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware from svr import app with open('data.json') as f: dat = json.load(f) sentry_sdk.init(dsn=dat["sentry_dsn"]) wsgi_app = SentryWsgiMiddleware(app.run) # if __name__ == "__main__": # app.run() # wsgi_app = SentryWsgiMiddleware(app) # this is just an entrypoint to allow WDGI to access the flask part of the server.
import bottle from bot import web # noqa from bot.config import SENTRY_SDK_KEY, VERSION if __name__ == '__main__': bottle.run(host='localhost', port=9000, debug=True) else: import sentry_sdk from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware sentry_sdk.init(SENTRY_SDK_KEY, release=VERSION) app = bottle.default_app() app.catchall = False application = SentryWsgiMiddleware(app)
def init_sentry(app): if settings.SENTRY_DSN: sentry_sdk.init(dsn=settings.SENTRY_DSN) return SentryWsgiMiddleware(app) return app
""" WSGI config for committee_admissions project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ """ import os from django.core.wsgi import get_wsgi_application from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware os.environ.setdefault("DJANGO_SETTINGS_MODULE", "committee_admissions.settings") application = SentryWsgiMiddleware(get_wsgi_application())