Skip to content

Commit c00e14e

Browse files
authored
Merge pull request #539 from joselsegura/sentry_broker
New monitored broker in order to better handle the exceptions
2 parents 756d461 + 3043093 commit c00e14e

5 files changed

Lines changed: 74 additions & 7 deletions

File tree

ccx_messaging/consumers/idp_kafka_consumer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
import re
66

77
from confluent_kafka import Message
8-
from insights import dr
98

109
from ccx_messaging.consumers.kafka_consumer import KafkaConsumer
1110
from ccx_messaging.error import CCXMessagingError
11+
from ccx_messaging.monitored_broker import SentryMonitoredBroker
1212

1313

1414
# Path example: <org_id>/<cluster_id>/<year><month><day><time>-<id>
@@ -80,7 +80,7 @@ def deserialize(self, msg):
8080
def create_broker(self, input_msg):
8181
"""Create a suitable `Broker` to be pass arguments to the `Engine`."""
8282
path = input_msg.get("path")
83-
broker = dr.Broker()
83+
broker = SentryMonitoredBroker()
8484
broker["original_path"] = path
8585

8686
if "cluster_id" in input_msg:

ccx_messaging/consumers/kafka_consumer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
Producer,
1414
TIMESTAMP_NOT_AVAILABLE,
1515
)
16-
from insights import dr
1716
from insights.core.exceptions import InvalidContentType
1817
from insights_messaging.consumers import Consumer
1918

2019
from ccx_messaging.error import CCXMessagingError
2120
from ccx_messaging.ingress import parse_ingress_message
21+
from ccx_messaging.monitored_broker import SentryMonitoredBroker
2222
from ccx_messaging.utils.kafka_config import kafka_producer_config_cleanup
2323

2424

@@ -249,7 +249,7 @@ def check_last_message_received_time(self):
249249

250250
def create_broker(self, input_msg):
251251
"""Create a suitable `Broker` to be pass arguments to the `Engine`."""
252-
broker = dr.Broker()
252+
broker = SentryMonitoredBroker()
253253

254254
# Some engines expect some data for its own usage, like the following:
255255
# (NOTE: The fields should be always present because of schema validation

ccx_messaging/consumers/rules_results_consumer.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99

1010

1111
from confluent_kafka import KafkaException
12-
from insights import dr
1312
from insights.core.exceptions import InvalidContentType
1413

1514
from ccx_messaging.consumers.kafka_consumer import KafkaConsumer
1615
from ccx_messaging.error import CCXMessagingError
1716
from ccx_messaging.internal_pipeline import parse_rules_results_msg
17+
from ccx_messaging.monitored_broker import SentryMonitoredBroker
1818

1919

2020
LOG = logging.getLogger(__name__)
@@ -89,9 +89,9 @@ def deserialize(self, msg):
8989
LOG.debug("JSON message deserialized (%s): %s", self.log_pattern, deseralized_msg)
9090
return deseralized_msg
9191

92-
def create_broker(self, input_msg: dict[str, Any]) -> dr.Broker:
92+
def create_broker(self, input_msg: dict[str, Any]) -> SentryMonitoredBroker:
9393
"""Create a suitable `Broker`."""
94-
broker = dr.Broker()
94+
broker = SentryMonitoredBroker()
9595
broker["cluster_id"] = input_msg["metadata"]["cluster_id"]
9696
broker["report_path"] = self.create_report_path(input_msg)
9797
return broker

ccx_messaging/monitored_broker.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""Utility broker to improve Ssentry exception handling."""
2+
3+
from insights.core.dr import Broker
4+
from insights.core.dr import MissingRequirements
5+
from insights.core.spec_factory import ContentException
6+
7+
from sentry_sdk import capture_exception
8+
9+
10+
class SentryMonitoredBroker(Broker):
11+
"""Implementation of Broker with custom Sentry capturing logic."""
12+
13+
def add_exception(self, component, ex, tb=None):
14+
"""Check added exception in order to use it with Sentry or not."""
15+
super().add_exception(component, ex, tb)
16+
17+
# prevent MissingRequirements and ContentException from being sent to sentry
18+
if not isinstance(ex, (MissingRequirements, ContentException)):
19+
capture_exception(ex)

test/monitored_broker_test.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""Tests for the utility class SentryMonitoredBroker."""
2+
3+
import time
4+
from uuid import uuid4
5+
from unittest.mock import patch
6+
7+
import pytest
8+
from insights.core.dr import MissingRequirements
9+
from insights.core.spec_factory import ContentException
10+
11+
12+
from ccx_messaging.monitored_broker import SentryMonitoredBroker
13+
14+
15+
def test_usage():
16+
"""Check that normal usage for the broker is kept across inheritance."""
17+
broker = SentryMonitoredBroker()
18+
cluster_id = uuid4()
19+
timestamp = time.time()
20+
21+
broker["cluster_id"] = cluster_id
22+
broker["timestamp"] = timestamp
23+
24+
assert broker["cluster_id"] == cluster_id
25+
assert broker["timestamp"] == timestamp
26+
27+
28+
@patch("ccx_messaging.monitored_broker.capture_exception")
29+
def test_add_exception(sentry_capture_exception_mock):
30+
"""Check add_exception behavior."""
31+
broker = SentryMonitoredBroker()
32+
33+
broker.add_exception(None, KeyboardInterrupt, None)
34+
assert sentry_capture_exception_mock.called
35+
36+
37+
NO_CAPTURE_EXCEPTIONS = [MissingRequirements, ContentException]
38+
39+
40+
@pytest.mark.parametrize("exception", NO_CAPTURE_EXCEPTIONS)
41+
def test_add_exception_no_capture(exception):
42+
"""Check that selected exceptions are not captured by Sentry."""
43+
broker = SentryMonitoredBroker()
44+
45+
with patch("ccx_messaging.monitored_broker.capture_exception") as capture_exception_mock:
46+
# Adding an argument to constructor because it is required by some of the exceptions
47+
broker.add_exception(None, exception("some message"), None)
48+
assert not capture_exception_mock.called

0 commit comments

Comments
 (0)