Skip to content

Commit

Permalink
Thrift metrics: omit status codes for exceptions with a non-int code (#…
Browse files Browse the repository at this point in the history
…892)

Co-authored-by: Chris Dary <[email protected]>
  • Loading branch information
umbrae and Chris Dary committed Apr 23, 2024
1 parent 377488c commit a5abb86
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
15 changes: 12 additions & 3 deletions baseplate/clients/thrift.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def _call_thrift_method(self: Any, *args: Any, **kwargs: Any) -> Any:
if exc_info[0] is not None:
thrift_success = "false"
exception_type = exc_info[0].__name__
current_exc = exc_info[1]
current_exc: Any = exc_info[1]
try:
# We want the following code to execute whenever the
# service raises an instance of Baseplate's `Error` class.
Expand All @@ -317,8 +317,17 @@ def _call_thrift_method(self: Any, *args: Any, **kwargs: Any) -> Any:
# we will emit the status code in both cases
# but the status will be blank in the first case, and the baseplate name
# in the second
baseplate_status_code = current_exc.code # type: ignore
baseplate_status = ErrorCode()._VALUES_TO_NAMES.get(current_exc.code, "") # type: ignore
#
# Since this exception could be of any type, we may receive exceptions
# that have a `code` property that is actually not from Baseplate's
# `Error` class. In order to reduce (but not eliminate) the possibility
# of metric explosion, we validate it against the expected type for a
# proper Error code.
if isinstance(current_exc.code, int):
baseplate_status_code = str(current_exc.code)
baseplate_status = ErrorCode()._VALUES_TO_NAMES.get(
current_exc.code, ""
)
except AttributeError:
pass

Expand Down
13 changes: 13 additions & 0 deletions tests/unit/clients/thrift_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ class ExampleClient:
list(thrift._enumerate_service_methods(ExampleClient))


class NonBaseplateExceptionWithCode(Exception):
def __init__(self):
self.code = lambda: "fake method"


class TestPrometheusMetrics:
def setup(self):
REQUEST_LATENCY.clear()
Expand Down Expand Up @@ -127,6 +132,14 @@ def setup(self):
"",
pytest.raises(Exception),
),
# Ensure that we don't poison prom metrics with non-baseplate status codes
(
NonBaseplateExceptionWithCode(),
"NonBaseplateExceptionWithCode",
"",
"",
pytest.raises(NonBaseplateExceptionWithCode),
),
],
)
def test_build_thrift_proxy_method(self, exc, exc_type, status, status_code, expectation):
Expand Down

0 comments on commit a5abb86

Please sign in to comment.