fix: refactor utils/prometheus.py

This commit is contained in:
nhnn 2024-07-08 18:00:49 +03:00
parent 3de0952c3f
commit c34551014f
2 changed files with 61 additions and 49 deletions

View file

@ -2,42 +2,52 @@
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
import requests import requests
from typing import Optional, Dict import strawberry
from dataclasses import dataclass
from typing import Optional
from strawberry.scalars import JSON
from datetime import datetime, timedelta from datetime import datetime, timedelta
PROMETHEUS_URL = "http://localhost:9001" PROMETHEUS_URL = "http://localhost:9001"
class PrometheusInfo: @strawberry.type
""" """ @dataclass
class PrometheusQueryResult:
http_response: int result_type: str
output: Optional[Dict] = None result: JSON
error: Optional[str] = None
class PrometheusQueries: class PrometheusQueries:
@staticmethod @staticmethod
def _send_request(endpoint="/api/v1/query", params=None) -> PrometheusInfo: def _send_query(query: str, start: int, end: int, step: int):
try: try:
response = requests.get(f"{PROMETHEUS_URL}{endpoint}", params=params) response = requests.get(
return PrometheusInfo( f"{PROMETHEUS_URL}/api/v1/query",
http_response=response.status_code, params={
output=(response.json() if response.status_code == 200 else None), "query": query,
"start": start,
"end": end,
"step": step,
},
) )
except requests.RequestException as error: if response.status_code != 200:
return PrometheusInfo( raise Exception("Prometheus returned unexpected HTTP status code")
http_response=500, json = response.json()
error=str(error), return PrometheusQueryResult(
result_type=json.result_type, result=json.result
) )
except Exception as error:
raise Exception("Prometheus request failed! " + str(error))
@staticmethod @staticmethod
def cpu_usage( def cpu_usage(
start: Optional[int] = None, start: Optional[int] = None,
end: Optional[int] = None, end: Optional[int] = None,
step: int = 60, # seconds step: int = 60, # seconds
) -> PrometheusInfo: ) -> PrometheusQueryResult:
"""Get CPU information,. """
Get CPU information.
Args: Args:
start (int, optional): Unix timestamp indicating the start time. start (int, optional): Unix timestamp indicating the start time.
@ -55,16 +65,14 @@ class PrometheusQueries:
query = '100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)' query = '100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)'
params = {"query": query, "start": start, "end": end, "step": step} return PrometheusQueries._send_query(query, start, end, step)
return PrometheusQueries._send_request(params=params)
@staticmethod @staticmethod
def disk_usage( def disk_usage(
start: Optional[int] = None, start: Optional[int] = None,
end: Optional[int] = None, end: Optional[int] = None,
step: int = 60, # seconds step: int = 60, # seconds
) -> PrometheusInfo: ) -> PrometheusQueryResult:
""" """
Get disk usage information. Get disk usage information.
@ -84,6 +92,4 @@ class PrometheusQueries:
query = '100 - (100 * ((node_filesystem_avail_bytes{mountpoint="/",fstype!="rootfs"} ) / (node_filesystem_size_bytes{mountpoint="/",fstype!="rootfs"}) ))' query = '100 - (100 * ((node_filesystem_avail_bytes{mountpoint="/",fstype!="rootfs"} ) / (node_filesystem_size_bytes{mountpoint="/",fstype!="rootfs"}) ))'
params = {"query": query, "start": start, "end": end, "step": step} return PrometheusQueries._send_query(query, start, end, step)
return PrometheusQueries._send_request(params=params)

View file

@ -3,14 +3,10 @@
# pylint: disable=missing-function-docstring # pylint: disable=missing-function-docstring
import pytest import pytest
from datetime import datetime, timezone
from tests.test_graphql.common import ( from tests.test_graphql.common import (
assert_empty, assert_empty,
get_data, get_data,
assert_ok, assert_ok,
assert_errorcode,
assert_original,
) )
@ -53,14 +49,6 @@ MOCK_CPU_USAGE_RESPONSE = {
} }
@pytest.fixture
def mock_post():
with patch(
"path.to.authorized_client.post", return_value=mock_response
) as mock_method:
yield mock_method
MOCK_DISKS_USAGE_RESPONSE = { MOCK_DISKS_USAGE_RESPONSE = {
"data": { "data": {
"monitoring": { "monitoring": {
@ -148,37 +136,54 @@ MOCK_MEMORY_USAGE_RESPONSE = {
DISKS_USAGE = """ DISKS_USAGE = """
query DefShouldSleepEnough { query TestDisksUsage {
monitoring { monitoring {
disks_usage { disks_usage
<ты не сделал как я просил вывод данных из Prometheus, по этому тут будет ошибка>
}
} }
} }
""" """
DISKS_USAGE_WITH_OPTIONS = """ DISKS_USAGE_WITH_OPTIONS = """
query DefShouldSleepEnough($start: int, $end: int, $step: int) { query TestDisksUsageWithOptions($start: int, $end: int, $step: int) {
monitoring { monitoring {
disks_usage(start: $start, end: $end, step: $step) { disks_usage(start: $start, end: $end, step: $step)
<ты не сделал как я просил вывод данных из Prometheus, по этому тут будет ошибка>
}
} }
} }
""" """
def test_graphql_get_disks_usage(client, authorized_client): @pytest.fixture
def mock_cpu_usage(mocker):
mock = mocker.patch(
"selfprivacy_api.utils.PrometheusQueries._sent_query",
return_value=MOCK_CPU_USAGE_RESPONSE["data"]["monitoring"]["cpu_usage"],
)
return mock
@pytest.fixture
def mock_disk_usage(mocker):
mock = mocker.patch(
"selfprivacy_api.utils.PrometheusQueries._sent_query",
return_value=MOCK_DISKS_USAGE_RESPONSE["data"]["monitoring"]["disk_usage"],
)
return mock
def test_graphql_get_disks_usage(client, authorized_client, mock_disk_usage):
response = authorized_client.post( response = authorized_client.post(
"/graphql", "/graphql",
json={"query": DISKS_USAGE}, json={"query": DISKS_USAGE},
) )
data = get_data(response)["monitoring"]["disks_usage"] data = get_data(response)
assert_ok(data) assert_ok(data)
assert data["data"] == MOCK_DISKS_USAGE_RESPONSE["data"]
def test_graphql_get_disks_usage_with_options(client, authorized_client): def test_graphql_get_disks_usage_with_options(
client, authorized_client, mock_disk_usage
):
response = authorized_client.post( response = authorized_client.post(
"/graphql", "/graphql",
json={ json={
@ -191,8 +196,9 @@ def test_graphql_get_disks_usage_with_options(client, authorized_client):
}, },
) )
data = get_data(response)["monitoring"]["disks_usage"] data = get_data(response)
assert_ok(data) assert_ok(data)
assert data["data"] == MOCK_DISKS_USAGE_RESPONSE["data"]
def test_graphql_get_disks_usage_unauthorized(client): def test_graphql_get_disks_usage_unauthorized(client):