2020-08-05 00:52:06 +00:00
|
|
|
import functools
|
2019-11-25 17:21:18 +00:00
|
|
|
import logging
|
|
|
|
import sys
|
|
|
|
import traceback
|
|
|
|
from typing import *
|
2020-08-05 00:52:06 +00:00
|
|
|
|
2020-07-31 14:44:17 +00:00
|
|
|
import royalnet
|
2019-11-25 17:21:18 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
import sentry_sdk
|
|
|
|
from sentry_sdk.integrations.aiohttp import AioHttpIntegration
|
|
|
|
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
|
|
|
from sentry_sdk.integrations.logging import LoggingIntegration
|
|
|
|
except ImportError:
|
|
|
|
sentry_sdk = None
|
|
|
|
AioHttpIntegration = None
|
|
|
|
SqlalchemyIntegration = None
|
|
|
|
LoggingIntegration = None
|
|
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
def init_sentry(sentry_cfg: Dict[str, Any]):
|
|
|
|
if sentry_sdk is None:
|
|
|
|
raise ImportError("`sentry` extra is not installed")
|
|
|
|
log.debug("Initializing Sentry...")
|
2020-07-31 14:44:17 +00:00
|
|
|
release = f"royalnet@{royalnet.__version__}"
|
2019-11-25 17:21:18 +00:00
|
|
|
sentry_sdk.init(sentry_cfg["dsn"],
|
|
|
|
integrations=[AioHttpIntegration(),
|
|
|
|
SqlalchemyIntegration(),
|
|
|
|
LoggingIntegration(event_level=None)],
|
|
|
|
release=release)
|
|
|
|
log.info(f"Sentry: {release}")
|
|
|
|
|
|
|
|
|
|
|
|
# noinspection PyUnreachableCode
|
|
|
|
def sentry_exc(exc: Exception,
|
|
|
|
level: str = "ERROR"):
|
|
|
|
if sentry_sdk is not None:
|
|
|
|
with sentry_sdk.configure_scope() as scope:
|
|
|
|
scope.set_level(level.lower())
|
|
|
|
sentry_sdk.capture_exception(exc)
|
2020-08-05 01:02:50 +00:00
|
|
|
# noinspection PyUnresolvedReferences,PyProtectedMember
|
2019-11-25 17:21:18 +00:00
|
|
|
level_int: int = logging._nameToLevel[level.upper()]
|
|
|
|
log.log(level_int, f"Captured {level.capitalize()}: {exc}")
|
|
|
|
# If started in debug mode (without -O), raise the exception, allowing you to see its source
|
|
|
|
if __debug__:
|
|
|
|
exc_type, exc_value, exc_traceback = sys.exc_info()
|
|
|
|
traceback.print_exception(exc_type, exc_value, exc_traceback)
|
2020-04-10 22:41:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
def sentry_wrap(level: str = "ERROR"):
|
|
|
|
def decorator(func: Callable):
|
|
|
|
@functools.wraps(func)
|
|
|
|
def new_func(*args, **kwargs):
|
|
|
|
try:
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
except Exception as exc:
|
|
|
|
sentry_exc(exc=exc, level=level)
|
|
|
|
raise
|
2020-08-05 00:52:06 +00:00
|
|
|
|
2020-04-10 22:41:39 +00:00
|
|
|
return new_func
|
2020-08-05 00:52:06 +00:00
|
|
|
|
2020-04-10 22:41:39 +00:00
|
|
|
return decorator
|
2020-04-10 22:56:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
def sentry_async_wrap(level: str = "ERROR"):
|
|
|
|
def decorator(func: Callable):
|
|
|
|
@functools.wraps(func)
|
|
|
|
async def new_func(*args, **kwargs):
|
|
|
|
try:
|
|
|
|
return await func(*args, **kwargs)
|
|
|
|
except Exception as exc:
|
|
|
|
sentry_exc(exc=exc, level=level)
|
|
|
|
raise
|
2020-08-05 00:52:06 +00:00
|
|
|
|
2020-04-10 22:56:05 +00:00
|
|
|
return new_func
|
2020-08-05 00:52:06 +00:00
|
|
|
|
2020-04-10 22:56:05 +00:00
|
|
|
return decorator
|