Skip to content

Commit

Permalink
Added integration with Sentry
Browse files Browse the repository at this point in the history
  • Loading branch information
egor-voynov-aiven committed Aug 1, 2024
1 parent 6f077c1 commit afd261f
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 1 deletion.
1 change: 1 addition & 0 deletions pghoard/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
"statsd": ("pghoard.monitoring.statsd", "StatsClient"),
"pushgateway": ("pghoard.monitoring.pushgateway", "PushgatewayClient"),
"prometheus": ("pghoard.monitoring.prometheus", "PrometheusClient"),
"sentry": ("pghoard.monitoring.sentry", "SentryClient"),
}
43 changes: 43 additions & 0 deletions pghoard/monitoring/sentry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import logging

LOG = logging.getLogger(__name__)


class SentryClient:
def __init__(self, config):
self.sentry = None
if config is None:
LOG.info("Sentry configuration not found, skipping setup")
return
dsn = config.get("dsn")
if dsn is None:
LOG.info("Sentry DSN not found, skipping setup")
return
try:
from sentry_sdk.integrations.logging import LoggingIntegration
import sentry_sdk
except ImportError:
LOG.info("Sentry SDK not found, skipping setup")
return
self.sentry = sentry_sdk
sentry_logging = LoggingIntegration(
level=logging.INFO,
event_level=logging.CRITICAL,
)
sentry_sdk.init(dsn=dsn, integrations=[sentry_logging])
for key, value in config.get("tags", {}).items():
sentry_sdk.set_tag(key, value)

def gauge(self, metric, value, tags=None):
pass

def increase(self, metric, inc_value=1, tags=None):
pass

def unexpected_exception(self, ex, where, tags=None):
if not self.sentry:
return

with self.sentry.push_scope() as scope:
scope.set_tag("where", where)
self.sentry.capture_exception(ex)
3 changes: 2 additions & 1 deletion pghoard/pghoard.py
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,8 @@ def load_config(self, _signal=None, _frame=None): # pylint: disable=unused-argu
self.metrics = metrics.Metrics(
statsd=self.config.get("statsd", None),
pushgateway=self.config.get("pushgateway", None),
prometheus=self.config.get("prometheus", None)
prometheus=self.config.get("prometheus", None),
sentry=self.config.get("sentry", None)
)

# need to refresh the web server config too
Expand Down
50 changes: 50 additions & 0 deletions test/monitoring/test_sentry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import contextlib
import logging

import sentry_sdk

from pghoard.monitoring.sentry import SentryClient


@contextlib.contextmanager
def patch_sentry_init(events):
original_init = sentry_sdk.init

def patched_init(*args, **kwargs):
kwargs["transport"] = events.append
kwargs.pop("dsn", None)
return original_init(*args, **kwargs)

sentry_sdk.init = patched_init
try:
yield
finally:
sentry_sdk.init = original_init


def test_missing_config():
client = SentryClient(config=None)
client.unexpected_exception(ValueError("hello !"), where="tests")
client.gauge("something", 123.456)
client.increase("something")


def test_exception_send():
events = []
with patch_sentry_init(events):
client = SentryClient(config={"dsn": "http://localhost:9000", "tags": {"foo": "bar"}}, transport=events.append)
client.unexpected_exception(ValueError("hello !"), where="tests")
assert len(events) == 1


def test_logging_integration():
events = []
with patch_sentry_init(events):
client = SentryClient(config={"dsn": "http://localhost:9000", "tags": {"foo": "bar"}}, transport=events.append)

logging.warning("Info")
assert len(events) == 0
logging.error("Error")
assert len(events) == 0
logging.critical("Critical")
assert len(events) == 1

0 comments on commit afd261f

Please sign in to comment.