From ce13a600f12faca50e00eec03021aa1c6f8062c6 Mon Sep 17 00:00:00 2001 From: LeaveMyYard <33721692+LeaveMyYard@users.noreply.github.com> Date: Wed, 5 Jul 2023 14:15:32 +0300 Subject: Update version to 1.3.2 --- pyproject.toml | 2 +- robusta_krr/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index af10fe7..8d269fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "robusta-krr" -version = "1.3.0-dev" +version = "1.3.2-dev" description = "Robusta's Resource Recommendation engine for Kubernetes" authors = ["Pavel Zhukov <33721692+LeaveMyYard@users.noreply.github.com>"] license = "MIT" diff --git a/robusta_krr/__init__.py b/robusta_krr/__init__.py index 70a9032..b3d9e1b 100644 --- a/robusta_krr/__init__.py +++ b/robusta_krr/__init__.py @@ -1,4 +1,4 @@ from .main import run -__version__ = "1.3.0-dev" +__version__ = "1.3.2-dev" __all__ = ["run", "__version__"] -- cgit v1.2.3 From 3cf7883cab3504050214559a561883834434021c Mon Sep 17 00:00:00 2001 From: LeaveMyYard <33721692+LeaveMyYard@users.noreply.github.com> Date: Wed, 5 Jul 2023 15:21:13 +0300 Subject: Prometheus post usage for queries --- .../core/integrations/prometheus/__init__.py | 8 +- .../metrics_service/prometheus_metrics_service.py | 36 +-------- .../integrations/prometheus/prometheus_client.py | 89 ++++++++++++++++++++++ 3 files changed, 94 insertions(+), 39 deletions(-) create mode 100644 robusta_krr/core/integrations/prometheus/prometheus_client.py diff --git a/robusta_krr/core/integrations/prometheus/__init__.py b/robusta_krr/core/integrations/prometheus/__init__.py index 6cec9a6..8f9dbb7 100644 --- a/robusta_krr/core/integrations/prometheus/__init__.py +++ b/robusta_krr/core/integrations/prometheus/__init__.py @@ -1,7 +1,3 @@ from .loader import MetricsLoader -from .metrics_service.prometheus_metrics_service import ( - ClusterNotSpecifiedException, - CustomPrometheusConnect, - PrometheusDiscovery, - PrometheusNotFound, -) +from .metrics_service.prometheus_metrics_service import PrometheusDiscovery, PrometheusNotFound +from .prometheus_client import CustomPrometheusConnect, ClusterNotSpecifiedException diff --git a/robusta_krr/core/integrations/prometheus/metrics_service/prometheus_metrics_service.py b/robusta_krr/core/integrations/prometheus/metrics_service/prometheus_metrics_service.py index 31fe0c0..1572d0c 100644 --- a/robusta_krr/core/integrations/prometheus/metrics_service/prometheus_metrics_service.py +++ b/robusta_krr/core/integrations/prometheus/metrics_service/prometheus_metrics_service.py @@ -1,22 +1,19 @@ import asyncio from concurrent.futures import ThreadPoolExecutor import datetime -from typing import List, Optional, no_type_check, Type +from typing import List, Optional, Type -import requests from kubernetes.client import ApiClient -from prometheus_api_client import PrometheusConnect, Retry -from requests.adapters import HTTPAdapter from requests.exceptions import ConnectionError, HTTPError from robusta_krr.core.abstract.strategies import ResourceHistoryData from robusta_krr.core.models.config import Config from robusta_krr.core.models.objects import K8sObjectData, PodData from robusta_krr.core.models.result import ResourceType -from robusta_krr.utils.configurable import Configurable from robusta_krr.utils.service_discovery import ServiceDiscovery from ..metrics import BaseMetricLoader +from ..prometheus_client import CustomPrometheusConnect from .base_metric_service import MetricsNotFound, MetricsService @@ -51,33 +48,6 @@ class PrometheusNotFound(MetricsNotFound): pass -class ClusterNotSpecifiedException(Exception): - """ - An exception raised when a prometheus requires a cluster label but an invalid one is provided. - """ - - pass - - -class CustomPrometheusConnect(PrometheusConnect): - """ - Custom PrometheusConnect class to handle retries. - """ - - @no_type_check - def __init__( - self, - url: str = "http://127.0.0.1:9090", - headers: dict = None, - disable_ssl: bool = False, - retry: Retry = None, - auth: tuple = None, - ): - super().__init__(url, headers, disable_ssl, retry, auth) - self._session = requests.Session() - self._session.mount(self.url, HTTPAdapter(max_retries=retry, pool_maxsize=10, pool_block=True)) - - class PrometheusMetricsService(MetricsService): """ A class for fetching metrics from Prometheus. @@ -179,7 +149,7 @@ class PrometheusMetricsService(MetricsService): MetricLoaderType = BaseMetricLoader.get_by_resource(resource, self.config.strategy) await self.add_historic_pods(object, period) - + metric_loader = MetricLoaderType(self.config, self.prometheus, self.executor) return await metric_loader.load_data(object, period, step, self.name()) diff --git a/robusta_krr/core/integrations/prometheus/prometheus_client.py b/robusta_krr/core/integrations/prometheus/prometheus_client.py new file mode 100644 index 0000000..16317f3 --- /dev/null +++ b/robusta_krr/core/integrations/prometheus/prometheus_client.py @@ -0,0 +1,89 @@ +from typing import no_type_check + +import requests +from datetime import datetime +from prometheus_api_client import PrometheusConnect, Retry, PrometheusApiClientException +from requests.adapters import HTTPAdapter + + +class ClusterNotSpecifiedException(Exception): + """ + An exception raised when a prometheus requires a cluster label but an invalid one is provided. + """ + + pass + + +class CustomPrometheusConnect(PrometheusConnect): + """ + Custom PrometheusConnect class to handle retries. + """ + + def __init__( + self, + url: str = "http://127.0.0.1:9090", + headers: dict = None, + disable_ssl: bool = False, + retry: Retry = None, + auth: tuple = None, + ): + super().__init__(url, headers, disable_ssl, retry, auth) + self._session = requests.Session() + self._session.mount(self.url, HTTPAdapter(max_retries=retry, pool_maxsize=10, pool_block=True)) + + def custom_query(self, query: str, params: dict = None): + params = params or {} + data = None + query = str(query) + # using the query API to get raw data + response = self._session.post( + "{0}/api/v1/query".format(self.url), + data={"query": query, **params}, + verify=self.ssl_verification, + headers=self.headers, + auth=self.auth, + ) + if response.status_code == 200: + data = response.json()["data"]["result"] + else: + raise PrometheusApiClientException( + "HTTP Status Code {} ({!r})".format(response.status_code, response.content) + ) + + return data + + def custom_query_range( + self, + query: str, + start_time: datetime, + end_time: datetime, + step: str, + params: dict = None, + ): + start = round(start_time.timestamp()) + end = round(end_time.timestamp()) + params = params or {} + data = None + query = str(query) + print(self.headers) + # using the query_range API to get raw data + response = self._session.post( + "{0}/api/v1/query_range".format(self.url), + data={ + "query": query, + "start": start, + "end": end, + "step": step, + **params, + }, + verify=self.ssl_verification, + headers=self.headers, + auth=self.auth, + ) + if response.status_code == 200: + data = response.json()["data"]["result"] + else: + raise PrometheusApiClientException( + "HTTP Status Code {} ({!r})".format(response.status_code, response.content) + ) + return data -- cgit v1.2.3 From 0be0b45e2a440f10ba716f26c4cd462314c9909f Mon Sep 17 00:00:00 2001 From: LeaveMyYard <33721692+LeaveMyYard@users.noreply.github.com> Date: Wed, 5 Jul 2023 15:28:40 +0300 Subject: Remove print --- robusta_krr/core/integrations/prometheus/prometheus_client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/robusta_krr/core/integrations/prometheus/prometheus_client.py b/robusta_krr/core/integrations/prometheus/prometheus_client.py index 16317f3..824cd92 100644 --- a/robusta_krr/core/integrations/prometheus/prometheus_client.py +++ b/robusta_krr/core/integrations/prometheus/prometheus_client.py @@ -65,7 +65,6 @@ class CustomPrometheusConnect(PrometheusConnect): params = params or {} data = None query = str(query) - print(self.headers) # using the query_range API to get raw data response = self._session.post( "{0}/api/v1/query_range".format(self.url), -- cgit v1.2.3 From 9cdc002b9f4a754976dafe5a0452b3ac0242a669 Mon Sep 17 00:00:00 2001 From: Avi-Robusta <97387909+Avi-Robusta@users.noreply.github.com> Date: Wed, 5 Jul 2023 16:24:20 +0300 Subject: missing api in some prometheus versions (#95) * added exception catch for labels api * rebase fix --- .../prometheus/metrics_service/prometheus_metrics_service.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/robusta_krr/core/integrations/prometheus/metrics_service/prometheus_metrics_service.py b/robusta_krr/core/integrations/prometheus/metrics_service/prometheus_metrics_service.py index 1572d0c..c4c280b 100644 --- a/robusta_krr/core/integrations/prometheus/metrics_service/prometheus_metrics_service.py +++ b/robusta_krr/core/integrations/prometheus/metrics_service/prometheus_metrics_service.py @@ -4,6 +4,7 @@ import datetime from typing import List, Optional, Type from kubernetes.client import ApiClient +from prometheus_api_client import PrometheusApiClientException from requests.exceptions import ConnectionError, HTTPError from robusta_krr.core.abstract.strategies import ResourceHistoryData @@ -133,7 +134,11 @@ class PrometheusMetricsService(MetricsService): ) def get_cluster_names(self) -> Optional[List[str]]: - return self.prometheus.get_label_values(label_name=self.config.prometheus_label) + try: + return self.prometheus.get_label_values(label_name=self.config.prometheus_label) + except PrometheusApiClientException: + self.error("Labels api not present on prometheus client") + return [] async def gather_data( self, -- cgit v1.2.3 From e3ddd9256d787062bbdf252f6fb66a361f64fc61 Mon Sep 17 00:00:00 2001 From: Avi-Robusta <97387909+Avi-Robusta@users.noreply.github.com> Date: Fri, 7 Jul 2023 17:45:11 +0300 Subject: remove redundant max (#98) --- robusta_krr/core/integrations/prometheus/metrics/memory_metric.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/robusta_krr/core/integrations/prometheus/metrics/memory_metric.py b/robusta_krr/core/integrations/prometheus/metrics/memory_metric.py index a8a4521..54c6c2d 100644 --- a/robusta_krr/core/integrations/prometheus/metrics/memory_metric.py +++ b/robusta_krr/core/integrations/prometheus/metrics/memory_metric.py @@ -35,13 +35,13 @@ class MemoryMetricLoader(MemoryMetricLoader): cluster_label = self.get_prometheus_cluster_label() resolution_formatted = f"[{resolution}]" if resolution else "" return ( - f"max(max_over_time(container_memory_working_set_bytes{{" + f"max_over_time(container_memory_working_set_bytes{{" f'namespace="{object.namespace}", ' f'pod=~"{pods_selector}", ' f'container="{object.container}"' f"{cluster_label}}}" f"{resolution_formatted}" - f")) by (container, pod, job, id)" + f")" ) def get_query_type(self) -> QueryType: -- cgit v1.2.3