Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions prometheus_api_client/prometheus_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,42 @@ def all_metrics(self, params: dict = None):
self._all_metrics = self.get_label_values(label_name="__name__", params=params)
return self._all_metrics


def get_series(self, start: datetime, end: datetime, params: dict = None):
"""
Get a list series happening between start and end times.

:param start: (int) Start time unix ts
:param end: (int) End time unix ts
:param params: (dict) Optional dictionary containing GET parameters to be
sent along with the API request, such as "start", "end" or "match[]".
:returns: (list) A list of labels from the specified prometheus host
:raises:
(RequestException) Raises an exception in case of a connection error
(PrometheusApiClientException) Raises in case of non 200 response status code
"""
params = params or {}
params["start"] = start.timestamp()
params["end"] = end.timestamp()
response = self._session.get(
"{0}/api/v1/series".format(self.url),
verify=self._session.verify,
headers=self.headers,
params=params,
auth=self.auth,
cert=self._session.cert,
timeout=self._timeout,
)

if response.status_code == 200:
labels = response.json()["data"]
else:
raise PrometheusApiClientException(
"HTTP Status Code {} ({!r})".format(response.status_code, response.content)
)
return labels


def get_label_names(self, params: dict = None):
"""
Get a list of all labels.
Expand Down
34 changes: 34 additions & 0 deletions tests/test_prometheus_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ def test_get_label_names_method(self): # noqa D102
self.assertEqual(len(labels), 3)
self.assertEqual(labels, ["__name__", "instance", "job"])

def test_get_series(self): # noqa D102
start_time = datetime.now() - timedelta(hours=1)
end_time = datetime.now()
series = self.pc.get_series(start=start_time, end=end_time, params={"match[]": "up"})
self.assertIsInstance(series, list)
self.assertTrue(len(series) > 0, "no series data received from prometheus")
# Verify that each series entry is a dict with labels
for series_entry in series:
self.assertIsInstance(series_entry, dict)
self.assertIn("__name__", series_entry)

def test_get_scrape_pools(self): # noqa D102
scrape_pools = self.pc.get_scrape_pools()
self.assertIsInstance(scrape_pools, list)
Expand Down Expand Up @@ -251,6 +262,10 @@ def test_broken_responses(self): # noqa D102
self.pc.get_label_values("label_name")
self.assertEqual("HTTP Status Code 403 (b'BOOM!')", str(exc.exception))

with self.assertRaises(PrometheusApiClientException) as exc:
self.pc.get_series(start=datetime.now() - timedelta(hours=1), end=datetime.now())
self.assertEqual("HTTP Status Code 403 (b'BOOM!')", str(exc.exception))

with self.assertRaises(PrometheusApiClientException) as exc:
self.pc.get_current_metric_value("metric")
self.assertEqual("HTTP Status Code 403 (b'BOOM!')", str(exc.exception))
Expand Down Expand Up @@ -284,6 +299,25 @@ def test_all_metrics_method(self): # noqa D102
request = handler.requests[0]
self.assertEqual(request.path_url, "/api/v1/label/__name__/values")


def test_get_series_method(self): # noqa D102
series_payload = {"status": "success", "data": [
{"__name__": "up", "job": "prometheus", "instance": "localhost:9090"},
{"__name__": "up", "job": "node", "instance": "localhost:9100"}
]}

with self.mock_response(series_payload) as handler:
start_time = datetime.now() - timedelta(hours=1)
end_time = datetime.now()
result = self.pc.get_series(start=start_time, end=end_time)
self.assertTrue(len(result) > 0)
self.assertEqual(handler.call_count, 1)
request = handler.requests[0]
self.assertTrue(request.path_url.startswith("/api/v1/series"))
# Verify that start and end parameters are included
self.assertIn("start", request.url)
self.assertIn("end", request.url)

def test_get_label_names_method(self): # noqa D102
all_metrics_payload = {"status": "success", "data": ["value1", "value2"]}

Expand Down