Pull count of detection events by label into prometheus metrics (#20119)

* pull count of detection events by label into prometheus metrics

* format changes with ruff

* remove unneeded f-string

* fix imports format

---------

Co-authored-by: iesad <iesad>
This commit is contained in:
iesad
2025-09-19 06:27:20 -06:00
committed by GitHub
co-authored by iesad <iesad>
parent 1408abb050
commit dc96940eb9
4 changed files with 136 additions and 46 deletions
+107
View File
@@ -8,7 +8,9 @@ from playhouse.shortcuts import model_to_dict
from frigate.api.auth import get_allowed_cameras_for_filter, get_current_user
from frigate.comms.event_metadata_updater import EventMetadataPublisher
from frigate.models import Event, Recordings, ReviewSegment, Timeline
from frigate.stats.emitter import StatsEmitter
from frigate.test.http_api.base_http_test import BaseTestHttp
from frigate.test.test_storage import _insert_mock_event
class TestHttpApp(BaseTestHttp):
@@ -293,3 +295,108 @@ class TestHttpApp(BaseTestHttp):
sub_labels = client.get("/sub_labels").json()
assert sub_labels
assert sub_labels == [sub_label]
####################################################################################################################
################################### GET /metrics Endpoint #########################################################
####################################################################################################################
def test_get_metrics(self):
"""ensure correct prometheus metrics api response"""
with TestClient(self.app) as client:
ts_start = datetime.now().timestamp()
ts_end = ts_start + 30
_insert_mock_event(
id="abcde.random", start=ts_start, end=ts_end, retain=True
)
_insert_mock_event(
id="01234.random", start=ts_start, end=ts_end, retain=True
)
_insert_mock_event(
id="56789.random", start=ts_start, end=ts_end, retain=True
)
_insert_mock_event(
id="101112.random",
label="outside",
start=ts_start,
end=ts_end,
retain=True,
)
_insert_mock_event(
id="131415.random",
label="outside",
start=ts_start,
end=ts_end,
retain=True,
)
_insert_mock_event(
id="161718.random",
camera="porch",
start=ts_start,
end=ts_end,
retain=True,
)
_insert_mock_event(
id="192021.random",
camera="porch",
start=ts_start,
end=ts_end,
retain=True,
)
_insert_mock_event(
id="222324.random",
camera="porch",
label="inside",
start=ts_start,
end=ts_end,
retain=True,
)
_insert_mock_event(
id="252627.random",
camera="porch",
label="inside",
start=ts_start,
end=ts_end,
retain=True,
)
_insert_mock_event(
id="282930.random",
label="inside",
start=ts_start,
end=ts_end,
retain=True,
)
_insert_mock_event(
id="313233.random",
label="inside",
start=ts_start,
end=ts_end,
retain=True,
)
stats_emitter = Mock(spec=StatsEmitter)
stats_emitter.get_latest_stats.return_value = self.test_stats
self.app.stats_emitter = stats_emitter
event = client.get("/metrics")
assert "# TYPE frigate_detection_total_fps gauge" in event.text
assert "frigate_detection_total_fps 13.7" in event.text
assert (
"# HELP frigate_camera_events_total Count of camera events since exporter started"
in event.text
)
assert "# TYPE frigate_camera_events_total counter" in event.text
assert (
'frigate_camera_events_total{camera="front_door",label="Mock"} 3.0'
in event.text
)
assert (
'frigate_camera_events_total{camera="front_door",label="inside"} 2.0'
in event.text
)
assert (
'frigate_camera_events_total{camera="front_door",label="outside"} 2.0'
in event.text
)
assert (
'frigate_camera_events_total{camera="porch",label="Mock"} 2.0' in event.text
)
assert 'frigate_camera_events_total{camera="porch",label="inside"} 2.0'
+10 -3
View File
@@ -261,12 +261,19 @@ class TestHttp(unittest.TestCase):
assert Recordings.get(Recordings.id == rec_k3_id)
def _insert_mock_event(id: str, start: int, end: int, retain: bool) -> Event:
def _insert_mock_event(
id: str,
start: int,
end: int,
retain: bool,
camera: str = "front_door",
label: str = "Mock",
) -> Event:
"""Inserts a basic event model with a given id."""
return Event.insert(
id=id,
label="Mock",
camera="front_door",
label=label,
camera=camera,
start_time=start,
end_time=end,
top_score=100,