Skip to content

Commit ae911b2

Browse files
authored
Typecast status_code as int before emitting to statsd (#1311)
1 parent 0bc7461 commit ae911b2

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

src/marqo/core/monitoring/statsd_middleware.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ async def dispatch(self, request: Request, call_next):
4040
tags = {
4141
"path": path_tag,
4242
"method": request.method,
43-
"status_code": str(response.status_code),
43+
"status_code": str(int(response.status_code)),
4444
}
4545

4646
# latency

src/marqo/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "2.24.3"
1+
__version__ = "2.24.4"
22

33
def get_version() -> str:
44
return f"{__version__}"

tests/unit_tests/marqo/core/monitoring/test_statsd_middleware.py

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
from typing import Dict, List, Optional, Tuple
2-
import unittest
1+
from http import HTTPStatus
32

3+
import unittest
44
from fastapi import FastAPI, HTTPException
55
from starlette.responses import JSONResponse
66
from starlette.testclient import TestClient
7+
from typing import Dict, List, Optional, Tuple
78

89
from marqo.core.monitoring import statsd_middleware as sm
910

@@ -193,4 +194,41 @@ def test_sanitize_path(self):
193194
self.assertEqual(
194195
sanitize("/indexes/foo/documents/get-batch"),
195196
"/indexes/foo/documents/get-batch",
196-
)
197+
)
198+
199+
def test_status_code_tag_is_string_integer(self):
200+
"""Ensure status_code tag is always a plain integer string, not an Enum representation."""
201+
# Create a mock response with an IntEnum-like status_code
202+
# This simulates cases where status_code could be an IntEnum subclass
203+
# Create a new stub and middleware for this test
204+
test_cass = [
205+
(HTTPStatus.OK, "200"),
206+
(HTTPStatus.BAD_REQUEST, "400"),
207+
(HTTPStatus.INTERNAL_SERVER_ERROR, "500")
208+
]
209+
for return_enum, expected_str in test_cass:
210+
with self.subTest(msg=f"status_code tag for {return_enum}"):
211+
stub = _StubStatsD()
212+
app = FastAPI()
213+
app.add_middleware(sm.StatsDMiddleware, statsd_client=stub)
214+
215+
@app.get("/test")
216+
async def test_endpoint():
217+
# Create a response with IntEnum status_code
218+
response = JSONResponse({"message": "test"})
219+
response.status_code = return_enum
220+
return response
221+
222+
with TestClient(app) as client:
223+
client.get("/test")
224+
225+
timings = _extract(stub, "timing", "request.duration_ms")
226+
self.assertTrue(any(f"status_code:{expected_str}" in m for m in timings),
227+
f"Expected 'status_code:{expected_str}' in metrics, got: {timings}")
228+
# Ensure it doesn't contain enum representation
229+
for timing in timings:
230+
if "status_code:" in timing:
231+
status_part = [part for part in timing.split("|#")[1].split(",") if "status_code:" in part][0]
232+
status_value = status_part.split(":")[1]
233+
self.assertEqual(status_value, expected_str,
234+
f"Status code should be '{expected_str}', got '{status_value}'")

0 commit comments

Comments
 (0)