From 01e30b96b2ed52375d58bc40365909b4e9bf9cbb Mon Sep 17 00:00:00 2001 From: dettlaff Date: Sat, 15 Jun 2024 22:17:08 +0400 Subject: [PATCH] feat: add prometheus.py, fix cpu_usage --- selfprivacy_api/graphql/queries/monitoring.py | 64 ++----------------- selfprivacy_api/utils/prometheus.py | 49 ++++++++++++++ 2 files changed, 54 insertions(+), 59 deletions(-) create mode 100644 selfprivacy_api/utils/prometheus.py diff --git a/selfprivacy_api/graphql/queries/monitoring.py b/selfprivacy_api/graphql/queries/monitoring.py index 56b5661..8163f4c 100644 --- a/selfprivacy_api/graphql/queries/monitoring.py +++ b/selfprivacy_api/graphql/queries/monitoring.py @@ -1,70 +1,16 @@ -"""Prometheus monitoring queries.""" - -# pylint: disable=too-few-public-methods -import typing -from typing import Optional - -import strawberry import requests -# TODO: добавить файл в schema.py -PROMETHEUS_URL = "http://localhost:9090" - - -@strawberry.type -class MonitoringInfo: - """ """ - - http_response: int - output: Optional[str] = None - error: Optional[str] = None +from selfprivacy_api.utils.prometheus import PrometheusQueries @strawberry.type class Monitoring: - """GraphQL queries to get prometheus monitoring information.""" - - def _send_request(self, endpoint="/api/v1/query", query=None) -> MonitoringInfo: - try: - if query: - response = requests.get( - f"{PROMETHEUS_URL}{endpoint}", params={"query": query} - ) - else: - response = requests.get(f"{PROMETHEUS_URL}{endpoint}") - - return MonitoringInfo( - http_response=response.status_code, - output=( - json.dumps(response.json()) if response.status_code == 200 else None - ), - ) - except requests.RequestException as error: - return MonitoringInfo( - http_response=500, # копилот предложил использовать тут 500 - error=str(error), - ) @strawberry.field - def status(self) -> MonitoringInfo: - """Get status""" - endpoint = "/api/v1/status/runtimeinfo" - return _send_request(endpoint=endpoint) + def disks_usage(): + return PrometheusQueries.disks_usage() @strawberry.field - def build(self) -> MonitoringInfo: - """Get build information""" - endpoint = "/api/v1/status/buildinfo" - return _send_request(endpoint=endpoint) - - @strawberry.field - def cpu_usage(self) -> MonitoringInfo: - """Get CPU information""" - query = """100 - (avg by (instance) (irate(node_cpu_seconds_total{job="node",mode="idle"}[5m])) * 100)""" - # TODO: не представляю рабочий ли этот запрос вообще - # https://overflow.hostux.net/questions/34923788/prometheus-convert-cpu-user-seconds-to-cpu-usage - # ему бы еще сделать кастомные минуты, чтоб разное время указывать, но так чтоб нельзя было инжектить - return _send_request(query=query) - - def disks_usage(): ... + def disks_usage(): + return PrometheusQueries.disks_usage() diff --git a/selfprivacy_api/utils/prometheus.py b/selfprivacy_api/utils/prometheus.py new file mode 100644 index 0000000..c0b0575 --- /dev/null +++ b/selfprivacy_api/utils/prometheus.py @@ -0,0 +1,49 @@ +"""Prometheus monitoring queries.""" + +# pylint: disable=too-few-public-methods +import time + +import typing +from typing import Optional + +PROMETHEUS_URL = "http://localhost:9090" + + +class PrometheusInfo: + """ """ + + http_response: int + output: Optional[typing.Dict] = None + error: Optional[str] = None + + +class PrometheusQueries: + @staticmethod + def _send_request(endpoint="/api/v1/query_range", params=None) -> PrometheusInfo: + try: + response = requests.get(f"{PROMETHEUS_URL}{endpoint}", params=params) + return PrometheusInfo( + http_response=response.status_code, + output=(response.json() if response.status_code == 200 else None), + ) + except requests.RequestException as error: + return PrometheusInfo( + http_response=500, + error=str(error), + ) + + @staticmethod + def cpu_usage() -> PrometheusInfo: + """Get CPU information""" + start = int((datetime.now() - timedelta(minutes=20)).timestamp()) + end = int(datetime.now().timestamp()) + query = '100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)' + + params = {"query": query, "start": start, "end": end, "step": 60} + + return PrometheusClient._send_request( + endpoint="/api/v1/query_range", params=params + ) + + @staticmethod + def disks_usage(): ...