From 1e62a1a8407ebd05d42a3bf8270d79a8062d5ab0 Mon Sep 17 00:00:00 2001 From: Chandrakala Subramanyam Date: Thu, 27 Jun 2024 17:29:10 +0530 Subject: [PATCH 01/77] Test plan and results for Kruize rel 0.0.23_mvp Signed-off-by: Chandrakala Subramanyam --- tests/test_plans/test_plan_rel_0.0.23.md | 144 +++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 tests/test_plans/test_plan_rel_0.0.23.md diff --git a/tests/test_plans/test_plan_rel_0.0.23.md b/tests/test_plans/test_plan_rel_0.0.23.md new file mode 100644 index 000000000..83a610a54 --- /dev/null +++ b/tests/test_plans/test_plan_rel_0.0.23.md @@ -0,0 +1,144 @@ +# KRUIZE TEST PLAN RELEASE 0.0.23 + +- [INTRODUCTION](#introduction) +- [FEATURES TO BE TESTED](#features-to-be-tested) +- [BUG FIXES TO BE TESTED](#bug-fixes-to-be-tested) +- [TEST ENVIRONMENT](#test-environment) +- [TEST DELIVERABLES](#test-deliverables) + - [New Test Cases Developed](#new-test-cases-developed) + - [Regression Testing](#regresion-testing) +- [SCALABILITY TESTING](#scalability-testing) +- [RELEASE TESTING](#release-testing) +- [TEST METRICS](#test-metrics) +- [RISKS AND CONTINGENCIES](#risks-and-contingencies) +- [APPROVALS](#approvals) + +----- + +## INTRODUCTION + +This document describes the test plan for Kruize remote monitoring release 0.0.23 + +---- + +## FEATURES TO BE TESTED + +* Support for ‘kind’ instead of minikube to run kruize local demo +* Add metrics logging for Kruize recommendation notifications +* Update the scalability test to print the metrics summary + +Kruize Local: + +* Update the kruize-demos to include different workload conditions +* Included tests for list datasource metadata and multiple import metadata +* Support for ‘kind’ instead of minikube to run kruize local monitoring demo + + +------ + +## BUG FIXES TO BE TESTED + +* Kruize pod fails if postgres doesn't comeup +* Analyze updateRecommendation failures in production +* Box plots - long_term : duration_in_hours - Limit to 2 decimal places similar to Short _term and mid_term +* Cleaned up recommendation engine code to remove redundant constants +* Security Vulnerability fixes + +--- + +## TEST ENVIRONMENT + +* Minikube Cluster +* Openshift Cluster + +--- + +## TEST DELIVERABLES + +### New Test Cases Developed + +| # | ISSUE (NEW FEATURE) | TEST DESCRIPTION | TEST DELIVERABLES | RESULTS | COMMENTS | +| --- |-----------------------------------------------------------------------| ---------------- | ----------------- | ----- | --- | +| 1 | [Add metrics logging for Kruize recommendation notifications] (https://github.com/kruize/autotune/pull/1206) | Updated scalability test to capture the notifications metrics | | PASSED | | +| 2 | [Support multiple invocations of import metadata] (https://github.com/kruize/autotune/pull/1178) | [Included new tests](https://github.com/kruize/autotune/blob/master/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md) | Tests added - [1211](https://github.com/kruize/autotune/pull/1211) | PASSED | | +| 3 | [Test list datasource metadata] (https://github.com/kruize/autotune/issues/) | [Included new tests](https://github.com/kruize/autotune/blob/master/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md) | Tests added - [1199](https://github.com/kruize/autotune/pull/1199) | PASSED | | +| 4 | [Update the kruize-demos to include different workload conditions] | Different load conditions idle/over utilized/under utilized were simulated | [79](https://github.com/kruize/kruize-demos/pull/79) | PASSED | | +| 5 | [Support for ‘kind’ instead of minikube to run kruize local demo] | local monitoring demo has been updated to use kind | [81](https://github.com/kruize/kruize-demos/pull/81) | CPU recommendations are not generated | | +| 6 | [Update the scalability test to print the metrics summary] | Existing Scale test has been updated to print the summary | [81](https://github.com/kruize/autotune/pull/81) | PASSED | | + +### Regression Testing + +| # | ISSUE (BUG/NEW FEATURE) | TEST CASE | RESULTS | COMMENTS | +| --- |--------------------------------| ---------- |---------| --- | +| 1 | Kruize pod fails if postgres doesn't comeup | Kruize remote monitoring tests | PASSED | | +| 2 | Box plots - long_term : duration_in_hours - Limit to 2 decimal places similar to Short _term and mid_term | Updated existing tests | PASSED | | + +--- + +## SCALABILITY TESTING + +Evaluate Kruize Scalability on OCP, with 5k experiments by uploading resource usage data for 15 days and update recommendations. +Changes do not have scalability implications. Short scalability test will be run as part of the release testing + +Short Scalability run +- 5K exps / 15 days of results / 2 containers per exp +- Kruize replicas - 10 +- OCP - Scalelab cluster + +Kruize Release | Exps / Results / Recos | Execution time | Latency (Max/ Avg) in seconds | | | | Postgres DB size(MB) | Kruize Max CPU | Kruize Max Memory (GB) +-- |------------------|------------------|--------------|--------------|-------------|-----------|----------------| -- | + | | | UpdateRecommendations | UpdateResults | LoadResultsByExpName | GeneratePlots| | | +0.0.22_mvp | 5K / 72L / 3L | 3h 51 mins | 0.62 / 0.39 | 0.24 / 0.17 | 0.34 / 0.25 | 0.0008 / 0.0007 | 21756.32 | 7.12 | 33.64 +0.0.23_mvp | 5K / 72L / 3L | 3h 51 mins | 0.63 / 0.39 | 0.24 / 0.17 | 0.35 / 0.25 | 0.0 / 0.0 | 21760 | 4.52 | 32.59 + +---- +## RELEASE TESTING + +As part of the release testing, following tests will be executed: +- [Kruize Remote monitoring Functional tests](/tests/scripts/remote_monitoring_tests/Remote_monitoring_tests.md) +- [Fault tolerant test](/tests/scripts/remote_monitoring_tests/fault_tolerant_tests.md) +- [Stress test](/tests/scripts/remote_monitoring_tests/README.md) +- [DB Migration test](/tests/scripts/remote_monitoring_tests/db_migration_test.md) +- [Stress test](/tests/scripts/remote_monitoring_tests/README.md) +- [Scalability test (On openshift)](/tests/scripts/remote_monitoring_tests/scalability_test.md) - scalability test with 5000 exps / 15 days usage data +- [Kruize remote monitoring demo (On minikube)](https://github.com/kruize/kruize-demos/blob/main/monitoring/remote_monitoring_demo/README.md) +- [Kruize local monitoring demo (On openshift)](https://github.com/kruize/kruize-demos/blob/main/monitoring/local_monitoring_demo) + + +| # | TEST SUITE | EXPECTED RESULTS | ACTUAL RESULTS | COMMENTS | +| --- | ---------- |------------------|------------|--------------| +| 1 | Kruize Remote monitoring Functional testsuite | TOTAL - 357, PASSED - 314 / FAILED - 43 | TOTAL - 357, PASSED - 314/ FAILED - 43 | No new regressions seen, existing issues - [559](https://github.com/kruize/autotune/issues/559), [610](https://github.com/kruize/autotune/issues/610) | +| 2 | Fault tolerant test | PASSED | PASSED | | +| 3 | Stress test | PASSED | PASSED | | +| 4 | Scalability test (short run)| PASSED | PASSED | Exps - 5000, Results - 72000, execution time - 3 hours 51 mins | +| 5 | DB Migration test | PASSED | PASSED | Tested on Openshift | +| 6 | Recommendation and box plot values validations | PASSED | PASSED | | +| 7 | Kruize remote monitoring demo | PASSED | PASSED | Tested manually | +| 8 | Kruize Local monitoring demo | PASSED | PASSED | | +| 9 | Kruize Local Functional tests | TOTAL - 35, PASSED - 35 / FAILED - 0 | TOTAL - 35, PASSED - 33 / FAILED - 2 | [Issue 1217](https://github.com/kruize/autotune/issues/1217) | + +--- + +## TEST METRICS + +### Test Completion Criteria + +* All must_fix defects identified for the release are fixed +* New features work as expected and tests have been added to validate these +* No new regressions in the functional tests +* All non-functional tests work as expected without major issues +* Documentation updates have been completed + +---- + +## RISKS AND CONTINGENCIES + +* None + +---- +## APPROVALS + +Sign-off + +---- + From 85724d63ead714b93223331acb213f445a9d5e81 Mon Sep 17 00:00:00 2001 From: Chandrakala Subramanyam Date: Thu, 27 Jun 2024 17:44:35 +0530 Subject: [PATCH 02/77] Fixed formatting issues Signed-off-by: Chandrakala Subramanyam --- tests/test_plans/test_plan_rel_0.0.23.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/test_plans/test_plan_rel_0.0.23.md b/tests/test_plans/test_plan_rel_0.0.23.md index 83a610a54..5a426b116 100644 --- a/tests/test_plans/test_plan_rel_0.0.23.md +++ b/tests/test_plans/test_plan_rel_0.0.23.md @@ -59,12 +59,12 @@ Kruize Local: | # | ISSUE (NEW FEATURE) | TEST DESCRIPTION | TEST DELIVERABLES | RESULTS | COMMENTS | | --- |-----------------------------------------------------------------------| ---------------- | ----------------- | ----- | --- | -| 1 | [Add metrics logging for Kruize recommendation notifications] (https://github.com/kruize/autotune/pull/1206) | Updated scalability test to capture the notifications metrics | | PASSED | | -| 2 | [Support multiple invocations of import metadata] (https://github.com/kruize/autotune/pull/1178) | [Included new tests](https://github.com/kruize/autotune/blob/master/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md) | Tests added - [1211](https://github.com/kruize/autotune/pull/1211) | PASSED | | -| 3 | [Test list datasource metadata] (https://github.com/kruize/autotune/issues/) | [Included new tests](https://github.com/kruize/autotune/blob/master/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md) | Tests added - [1199](https://github.com/kruize/autotune/pull/1199) | PASSED | | -| 4 | [Update the kruize-demos to include different workload conditions] | Different load conditions idle/over utilized/under utilized were simulated | [79](https://github.com/kruize/kruize-demos/pull/79) | PASSED | | -| 5 | [Support for ‘kind’ instead of minikube to run kruize local demo] | local monitoring demo has been updated to use kind | [81](https://github.com/kruize/kruize-demos/pull/81) | CPU recommendations are not generated | | -| 6 | [Update the scalability test to print the metrics summary] | Existing Scale test has been updated to print the summary | [81](https://github.com/kruize/autotune/pull/81) | PASSED | | +| 1 | [Add metrics logging for Kruize recommendation notifications](https://github.com/kruize/autotune/pull/1206) | Updated scalability test to capture the notifications metrics | | PASSED | | +| 2 | [Support multiple invocations of import metadata](https://github.com/kruize/autotune/pull/1178) | [Included new tests](https://github.com/kruize/autotune/blob/master/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md) | Tests added - [1211](https://github.com/kruize/autotune/pull/1211) | PASSED | | +| 3 | Tests for list datasource metadata | [Included new tests](https://github.com/kruize/autotune/blob/master/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md) | Tests added - [1199](https://github.com/kruize/autotune/pull/1199) | PASSED | | +| 4 | [Update the kruize-demos to include different workload conditions](https://github.com/kruize/kruize-demos/pull/79) | Different load conditions idle/over utilized/under utilized were simulated | | PASSED | | +| 5 | [Support for ‘kind’ instead of minikube to run kruize local demo](https://github.com/kruize/kruize-demos/pull/81) | local monitoring demo has been updated to use kind | | CPU recommendations are not generated, being investigated | | +| 6 | Update the scalability test to print the metrics summary | Existing Scale test has been updated to print the summary | [81](https://github.com/kruize/autotune/pull/81) | PASSED | | ### Regression Testing @@ -85,11 +85,11 @@ Short Scalability run - Kruize replicas - 10 - OCP - Scalelab cluster -Kruize Release | Exps / Results / Recos | Execution time | Latency (Max/ Avg) in seconds | | | | Postgres DB size(MB) | Kruize Max CPU | Kruize Max Memory (GB) --- |------------------|------------------|--------------|--------------|-------------|-----------|----------------| -- | - | | | UpdateRecommendations | UpdateResults | LoadResultsByExpName | GeneratePlots| | | -0.0.22_mvp | 5K / 72L / 3L | 3h 51 mins | 0.62 / 0.39 | 0.24 / 0.17 | 0.34 / 0.25 | 0.0008 / 0.0007 | 21756.32 | 7.12 | 33.64 -0.0.23_mvp | 5K / 72L / 3L | 3h 51 mins | 0.63 / 0.39 | 0.24 / 0.17 | 0.35 / 0.25 | 0.0 / 0.0 | 21760 | 4.52 | 32.59 +Kruize Release | Exps / Results / Recos | Execution time | Latency (Max/ Avg) in seconds | | | Postgres DB size(MB) | Kruize Max CPU | Kruize Max Memory (GB) +-- |------------------------|-----------------------|-------------------------------|----------------------|--------------|----------------------|----------------| -- + | | | | UpdateRecommendations | UpdateResults | LoadResultsByExpName | | | +0.0.22_mvp | 5K / 72L / 3L | 3h 51 mins | 0.62 / 0.39 | 0.24 / 0.17 | 0.34 / 0.25 | 21756.32 | 7.12 | 33.64 +0.0.23_mvp | 5K / 72L / 3L | 3h 51 mins | 0.63 / 0.39 | 0.24 / 0.17 | 0.35 / 0.25 | 21760 | 4.52 | 32.59 ---- ## RELEASE TESTING From fd9a9f3b323bd1f3159a30b0c8c46f0eabca0fd3 Mon Sep 17 00:00:00 2001 From: Chandrakala Subramanyam Date: Fri, 28 Jun 2024 10:56:27 +0530 Subject: [PATCH 03/77] Made a few updates to release tests executed Signed-off-by: Chandrakala Subramanyam --- tests/test_plans/test_plan_rel_0.0.23.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_plans/test_plan_rel_0.0.23.md b/tests/test_plans/test_plan_rel_0.0.23.md index 5a426b116..4e267d2c0 100644 --- a/tests/test_plans/test_plan_rel_0.0.23.md +++ b/tests/test_plans/test_plan_rel_0.0.23.md @@ -23,7 +23,6 @@ This document describes the test plan for Kruize remote monitoring release 0.0.2 ## FEATURES TO BE TESTED -* Support for ‘kind’ instead of minikube to run kruize local demo * Add metrics logging for Kruize recommendation notifications * Update the scalability test to print the metrics summary @@ -99,10 +98,11 @@ As part of the release testing, following tests will be executed: - [Fault tolerant test](/tests/scripts/remote_monitoring_tests/fault_tolerant_tests.md) - [Stress test](/tests/scripts/remote_monitoring_tests/README.md) - [DB Migration test](/tests/scripts/remote_monitoring_tests/db_migration_test.md) -- [Stress test](/tests/scripts/remote_monitoring_tests/README.md) +- [Recommendation and box plot values validation test](https://github.com/kruize/kruize-demos/blob/main/monitoring/remote_monitoring_demo/recommendations_infra_demo/README.md) - [Scalability test (On openshift)](/tests/scripts/remote_monitoring_tests/scalability_test.md) - scalability test with 5000 exps / 15 days usage data - [Kruize remote monitoring demo (On minikube)](https://github.com/kruize/kruize-demos/blob/main/monitoring/remote_monitoring_demo/README.md) - [Kruize local monitoring demo (On openshift)](https://github.com/kruize/kruize-demos/blob/main/monitoring/local_monitoring_demo) +- [Kruize local monitoring Functional tests](/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md) | # | TEST SUITE | EXPECTED RESULTS | ACTUAL RESULTS | COMMENTS | From 2cc9a221d1fed0146ef7d75298629e6bf256f03a Mon Sep 17 00:00:00 2001 From: Chandrakala Subramanyam Date: Fri, 28 Jun 2024 19:37:10 +0530 Subject: [PATCH 04/77] Updated the scalability results with the latest 0.0.23_mvp build Signed-off-by: Chandrakala Subramanyam --- tests/test_plans/test_plan_rel_0.0.23.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_plans/test_plan_rel_0.0.23.md b/tests/test_plans/test_plan_rel_0.0.23.md index 4e267d2c0..d9d1a0572 100644 --- a/tests/test_plans/test_plan_rel_0.0.23.md +++ b/tests/test_plans/test_plan_rel_0.0.23.md @@ -88,7 +88,7 @@ Kruize Release | Exps / Results / Recos | Execution time | Latency (Max/ -- |------------------------|-----------------------|-------------------------------|----------------------|--------------|----------------------|----------------| -- | | | | UpdateRecommendations | UpdateResults | LoadResultsByExpName | | | 0.0.22_mvp | 5K / 72L / 3L | 3h 51 mins | 0.62 / 0.39 | 0.24 / 0.17 | 0.34 / 0.25 | 21756.32 | 7.12 | 33.64 -0.0.23_mvp | 5K / 72L / 3L | 3h 51 mins | 0.63 / 0.39 | 0.24 / 0.17 | 0.35 / 0.25 | 21760 | 4.52 | 32.59 +0.0.23_mvp | 5K / 72L / 3L | 3h 30 mins | 0.66 / 0.41 | 0.14 / 0.12 | 0.22 / 0.18 | 21767 | 6.96 | 36.35 ---- ## RELEASE TESTING From eb2aa3fa4efb618bff11c311793c10bfe545e82b Mon Sep 17 00:00:00 2001 From: Saad Khan Date: Tue, 11 Jun 2024 10:22:17 +0530 Subject: [PATCH 05/77] add new script to install prometheus on Kind Signed-off-by: Saad Khan --- scripts/prometheus_on_kind.sh | 154 ++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100755 scripts/prometheus_on_kind.sh diff --git a/scripts/prometheus_on_kind.sh b/scripts/prometheus_on_kind.sh new file mode 100755 index 000000000..e4056e8f0 --- /dev/null +++ b/scripts/prometheus_on_kind.sh @@ -0,0 +1,154 @@ +#!/bin/bash +# +# Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# include the common_utils.sh script to access methods +current_dir="$(dirname "$0")" +source ${current_dir}/common_utils.sh +non_interactive=0 +# Call setup by default (and not terminate) +setup=1 + +# Prometheus release default +tag="v0.8.0" + +function install_prometheus() { + echo + echo "Info: Checking pre requisites for prometheus..." + check_kustomize + + prometheus_ns="monitoring" + kubectl_cmd="kubectl -n ${prometheus_ns}" + prometheus_pod_running=$(${kubectl_cmd} get pods | grep "prometheus-k8s-1") + + if [ "${prometheus_pod_running}" != "" ]; then + echo "Prometheus is already installed and running." + return; + fi + + if [ "${non_interactive}" == 0 ]; then + echo "Info: Prometheus needs cadvisor/grafana" + echo -n "Download and install these software to KIND(y/n)? " + read inst + linst=$(echo ${inst} | tr A-Z a-z) + if [ "${linst}" == "n" ]; then + echo "Info: prometheus not installed" + exit 0 + fi + fi + + mkdir kind_downloads 2>/dev/null + pushd kind_downloads >/dev/null + echo "Info: Downloading cadvisor git" + git clone https://github.com/google/cadvisor.git 2>/dev/null + pushd cadvisor/deploy/kubernetes/base >/dev/null + echo + echo "Info: Installing cadvisor" + kubectl kustomize . | kubectl apply -f- + check_err "Error: Unable to install cadvisor" + popd >/dev/null + echo + echo "Info: Downloading prometheus git release - ${tag}" + # Commenting the below lines as the latest prometheus requires more than 2 CPUs and the PR checks fail on github hosted runners + # as they have only 2 CPUs on the host. Hence switching back to prometheus release 0.8.0 (Apr 2021) + # git clone https://github.com/coreos/kube-prometheus.git 2>/dev/null + git clone -b ${tag} https://github.com/coreos/kube-prometheus.git 2>/dev/null + pushd kube-prometheus/manifests >/dev/null + echo + echo "Info: Installing prometheus" + kubectl apply -f setup --server-side + check_err "Error: Unable to setup prometheus" + kubectl apply -f . --server-side + check_err "Error: Unable to install prometheus" + popd >/dev/null + popd >/dev/null + + echo -n "Info: Waiting for all Prometheus Pods to get spawned..." + while true; + do + # Wait for prometheus docker images to get downloaded and spawn the main pod + pod_started=$(${kubectl_cmd} get pods | grep "prometheus-k8s-1") + if [ "${pod_started}" == "" ]; then + # prometheus-k8s-1 not yet spawned + echo -n "." + sleep 5 + else + echo "done" + break; + fi + done + check_running prometheus-k8s-1 ${prometheus_ns} + sleep 2 +} + +function delete_prometheus() { + echo -n "### Removing cadvisor and prometheus" + pushd kind_downloads > /dev/null + echo + echo "Removing cadvisor" + pushd cadvisor/deploy/kubernetes/base > /dev/null + kubectl kustomize . | kubectl delete -f- + popd > /dev/null + + echo + echo "Removing prometheus" + pushd kube-prometheus/manifests > /dev/null + kubectl delete -f . 2>/dev/null + kubectl delete -f setup 2>/dev/null + popd > /dev/null + popd > /dev/null + rm -rf kind_downloads +} + +# Input from user to install/delete prometheus +function usage() { + echo >&2 "usage: $0 [-r Date: Fri, 14 Jun 2024 11:37:42 +0530 Subject: [PATCH 06/77] update copyright year in prometheus_on_kind file Signed-off-by: Saad Khan --- scripts/prometheus_on_kind.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/prometheus_on_kind.sh b/scripts/prometheus_on_kind.sh index e4056e8f0..aaadb6f6d 100755 --- a/scripts/prometheus_on_kind.sh +++ b/scripts/prometheus_on_kind.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. +# Copyright (c) 2024 Red Hat, IBM Corporation and others. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 46eb206c3242d24e5da7f667841ec9b66ac47a67 Mon Sep 17 00:00:00 2001 From: Saad Khan Date: Mon, 1 Jul 2024 15:24:59 +0530 Subject: [PATCH 07/77] update prometheus version to latest Signed-off-by: Saad Khan --- scripts/prometheus_on_kind.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/prometheus_on_kind.sh b/scripts/prometheus_on_kind.sh index aaadb6f6d..464113eb3 100755 --- a/scripts/prometheus_on_kind.sh +++ b/scripts/prometheus_on_kind.sh @@ -23,7 +23,7 @@ non_interactive=0 setup=1 # Prometheus release default -tag="v0.8.0" +tag="v0.13.0" function install_prometheus() { echo From 73e22c705ff218668d095fd9cf5374a632ff3065 Mon Sep 17 00:00:00 2001 From: Krishna Harsha Voora Date: Tue, 2 Jul 2024 22:48:03 +0530 Subject: [PATCH 08/77] Adds support for AKS --- deploy.sh | 10 +- manifests/autotune/configmaps/aks-config.yaml | 28 ++ .../aks/kruize-crc-aks.yaml | 375 ++++++++++++++++++ scripts/aks-helpers.sh | 212 ++++++++++ scripts/prometheus_on_aks.sh | 103 +++++ 5 files changed, 724 insertions(+), 4 deletions(-) create mode 100644 manifests/autotune/configmaps/aks-config.yaml create mode 100644 manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml create mode 100755 scripts/aks-helpers.sh create mode 100755 scripts/prometheus_on_aks.sh diff --git a/deploy.sh b/deploy.sh index 1b34abae0..9597ae177 100755 --- a/deploy.sh +++ b/deploy.sh @@ -43,9 +43,10 @@ AUTOTUNE_QUERY_VARIABLES_MANIFEST_TEMPLATE="${AUTOTUNE_DIR}/autotune-query-varia AUTOTUNE_QUERY_VARIABLES_MANIFEST="${AUTOTUNE_DIR}/autotune-query-variables/query-variable.yaml" KRUIZE_CRC_DEPLOY_MANIFEST_OPENSHIFT="${CRC_DIR}/openshift/kruize-crc-openshift.yaml" KRUIZE_CRC_DEPLOY_MANIFEST_MINIKUBE="${CRC_DIR}/minikube/kruize-crc-minikube.yaml" +KRUIZE_CRC_DEPLOY_MANIFEST_AKS="${CRC_DIR}/aks/kruize-crc-aks.yaml" AUTOTUNE_PORT="8080" -AUTOTUNE_DOCKER_REPO="docker.io/kruize/autotune_operator" +AUTOTUNE_DOCKER_REPO="quay.io/kruize/autotune_operator" #Fetch autotune version from the pom.xml file. AUTOTUNE_VERSION="$(grep -A 1 "autotune" "${ROOT_DIR}"/pom.xml | grep version | awk -F '>' '{ split($2, a, "<"); print a[1] }')" @@ -63,6 +64,7 @@ HPO_DOCKER_IMAGE=${HPO_DOCKER_REPO}:${HPO_VERSION} # source all the helpers scripts . "${SCRIPTS_DIR}"/minikube-helpers.sh +. "${SCRIPTS_DIR}"/aks-helpers.sh . "${SCRIPTS_DIR}"/openshift-helpers.sh . "${SCRIPTS_DIR}"/common_utils.sh @@ -96,7 +98,7 @@ trap "ctrlc_handler" 1 2 3 function usage() { echo - echo "Usage: $0 [-a] [-k url] [-c [docker|minikube|openshift]] [-i autotune docker image] [-o hpo docker image] [-n namespace] [-d configmaps-dir ] [--timeout=x, x in seconds, for docker only]" + echo "Usage: $0 [-a] [-k url] [-c [docker|minikube|openshift|aks]] [-i autotune docker image] [-o hpo docker image] [-n namespace] [-d configmaps-dir ] [--timeout=x, x in seconds, for docker only]" echo " -s = start(default), -t = terminate" echo " -s: Deploy autotune [Default]" echo " -t: Terminate autotune deployment" @@ -113,7 +115,7 @@ function usage() { # Check if the cluster_type is one of icp or openshift function check_cluster_type() { case "${cluster_type}" in - docker | minikube | openshift) ;; + docker | minikube | openshift | aks) ;; *) echo "Error: unsupported cluster type: ${cluster_type}" @@ -187,7 +189,7 @@ done # Call the proper setup function based on the cluster_type if [ ${setup} == 1 ]; then if [ ${target} == "crc" ]; then - if [ ${cluster_type} == "minikube" ] || [ ${cluster_type} == "openshift" ]; then + if [ ${cluster_type} == "minikube" ] || [ ${cluster_type} == "openshift" ] || [ ${cluster_type} == "aks" ]; then ${cluster_type}_crc_start else echo "Unsupported cluster!" diff --git a/manifests/autotune/configmaps/aks-config.yaml b/manifests/autotune/configmaps/aks-config.yaml new file mode 100644 index 000000000..615293cbc --- /dev/null +++ b/manifests/autotune/configmaps/aks-config.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: autotune-config +data: + cluster_type: "kubernetes" + k8s_type: "aks" + auth_type: "" + auth_token: "" + monitoring_agent: "prometheus" + monitoring_service: "prometheus-k8s" + monitoring_agent_endpoint: "" + root_logging_level: "error" + logging_level: "info" + kruizeconfigjson: | + { + "datasource": [ + { + "name": "prometheus-1", + "provider": "prometheus", + "serviceName": "prometheus-k8s", + "namespace": "monitoring", + "url": "" + } + ] + } + + diff --git a/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml b/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml new file mode 100644 index 000000000..532d94e55 --- /dev/null +++ b/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml @@ -0,0 +1,375 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: postgres-pvc + namespace: monitoring +spec: + accessModes: + - ReadWriteOnce + storageClassName: managed + resources: + requests: + storage: 1Gi +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: postgres-deployment + namespace: monitoring + labels: + app: postgres +spec: + replicas: 1 + selector: + matchLabels: + app: postgres + template: + metadata: + labels: + app: postgres + spec: + #securityContext: #todo + # runAsNonRoot: true + # runAsUser: 1000 + containers: + - name: postgres + image: quay.io/kruizehub/postgres:15.2 + imagePullPolicy: IfNotPresent + env: + - name: POSTGRES_PASSWORD + value: admin + - name: POSTGRES_USER + value: admin + - name: POSTGRES_DB + value: kruizeDB + ports: + - containerPort: 5432 + volumeMounts: + - name: postgres-storage + mountPath: /var/lib/postgresql/data + volumes: + - name: postgres-storage + persistentVolumeClaim: + claimName: postgres-pvc +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres-service + namespace: monitoring + labels: + app: postgres +spec: + type: ClusterIP + ports: + - name: postgres-port + port: 5432 + targetPort: 5432 + selector: + app: postgres +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: kruizeconfig + namespace: monitoring +data: + dbconfigjson: | + { + "database": { + "adminPassword": "admin", + "adminUsername": "admin", + "hostname": "postgres-service", + "name": "kruizeDB", + "password": "admin", + "port": 5432, + "sslMode": "require", + "username": "admin" + } + } + kruizeconfigjson: | + { + "clustertype": "kubernetes", + "k8stype": "minikube", + "authtype": "", + "monitoringagent": "prometheus", + "monitoringservice": "prometheus-k8s", + "monitoringendpoint": "prometheus-k8s", + "savetodb": "true", + "dbdriver": "jdbc:postgresql://", + "plots": "true", + "local": "false", + "logAllHttpReqAndResp": "true", + "hibernate": { + "dialect": "org.hibernate.dialect.PostgreSQLDialect", + "driver": "org.postgresql.Driver", + "c3p0minsize": 2, + "c3p0maxsize": 5, + "c3p0timeout": 300, + "c3p0maxstatements": 50, + "hbm2ddlauto": "none", + "showsql": "false", + "timezone": "UTC" + }, + "logging" : { + "cloudwatch": { + "accessKeyId": "", + "logGroup": "kruize-logs", + "logStream": "kruize-stream", + "region": "", + "secretAccessKey": "", + "logLevel": "INFO" + } + }, + "datasource": [ + { + "name": "prometheus-1", + "provider": "prometheus", + "serviceName": "prometheus-k8s", + "namespace": "monitoring", + "url": "" + } + ] + } +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kruize + labels: + app: kruize + namespace: monitoring +spec: + replicas: 1 + selector: + matchLabels: + name: kruize + template: + metadata: + labels: + app: kruize + name: kruize + spec: + containers: + - name: kruize + image: quay.io/kruize/autotune_operator:0.0.22_rm + imagePullPolicy: Always + volumeMounts: + - name: config-volume + mountPath: /etc/config + env: + - name: LOGGING_LEVEL + value: "info" + - name: ROOT_LOGGING_LEVEL + value: "error" + - name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + - name: JAVA_TOOL_OPTIONS + value: "-XX:MaxRAMPercentage=80" + ports: + - name: kruize-port + containerPort: 8080 + # livenessProbe: + # exec: + # command: + # - sh + # - -c + # - chmod +x /home/autotune/app/target/bin/TestDBConnection && /home/autotune/app/target/bin/TestDBConnection + # initialDelaySeconds: 10 + # periodSeconds: 5 + # timeoutSeconds: 20 + volumes: + - name: config-volume + configMap: + name: kruizeconfig +--- +apiVersion: v1 +kind: Service +metadata: + name: kruize + namespace: monitoring + annotations: + prometheus.io/scrape: 'true' + prometheus.io/path: '/metrics' + labels: + app: kruize +spec: + type: NodePort + selector: + app: kruize + ports: + - name: kruize-port + port: 8080 + targetPort: 8080 +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: create-partition-cronjob + namespace: monitoring +spec: + schedule: "0 0 25 * *" # Run on 25th of every month at midnight + jobTemplate: + spec: + template: + spec: + containers: + - name: kruizecronjob + image: quay.io/kruize/autotune_operator:0.0.22_rm + imagePullPolicy: Always + volumeMounts: + - name: config-volume + mountPath: /etc/config + command: + - sh + - -c + - | + /home/autotune/app/target/bin/CreatePartition + args: [ "" ] + env: + - name: START_AUTOTUNE + value: "false" + - name: LOGGING_LEVEL + value: "info" + - name: ROOT_LOGGING_LEVEL + value: "error" + - name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + volumes: + - name: config-volume + configMap: + name: kruizeconfig + restartPolicy: OnFailure +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: kruize-service-monitor + namespace: monitoring + labels: + app: kruize +spec: + selector: + matchLabels: + app: kruize + endpoints: + - port: kruize-port + interval: 30s + path: /metrics +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-config + namespace: monitoring +data: + nginx.conf: | + events {} + http { + upstream kruize-api { + server kruize:8080; + } + + server { + listen 8080; + server_name localhost; + + root /usr/share/nginx/html; + + location ^~ /api/ { + rewrite ^/api(.*)$ $1 break; + proxy_pass http://kruize-api; + } + + location / { + index index.html; + error_page 404 =200 /index.html; + } + } + } +--- +apiVersion: v1 +kind: Service +metadata: + name: kruize-ui-nginx-service + namespace: monitoring +spec: + type: NodePort + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: kruize-ui-nginx +--- +apiVersion: v1 +kind: Pod +metadata: + name: kruize-ui-nginx-pod + namespace: monitoring + labels: + app: kruize-ui-nginx +spec: + containers: + - name: kruize-ui-nginx-container + image: quay.io/kruize/kruize-ui:0.0.3 + imagePullPolicy: Always + env: + - name: KRUIZE_UI_ENV + value: "production" + volumeMounts: + - name: nginx-config-volume + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + volumes: + - name: nginx-config-volume + configMap: + name: nginx-config +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: kruize-delete-partition-cronjob + namespace: monitoring +spec: + schedule: "0 0 25 * *" # Run on 25th of every month at midnight + jobTemplate: + spec: + template: + spec: + containers: + - name: kruizedeletejob + image: quay.io/kruize/autotune_operator:0.0.22_rm + imagePullPolicy: Always + volumeMounts: + - name: config-volume + mountPath: /etc/config + command: + - sh + - -c + - | + /home/autotune/app/target/bin/RetentionPartition + args: [ "" ] + env: + - name: START_AUTOTUNE + value: "false" + - name: LOGGING_LEVEL + value: "info" + - name: ROOT_LOGGING_LEVEL + value: "error" + - name: DB_CONFIG_FILE + value: "/etc/config/dbconfigjson" + - name: KRUIZE_CONFIG_FILE + value: "/etc/config/kruizeconfigjson" + - name: deletepartitionsthreshold + value: "15" + volumes: + - name: config-volume + configMap: + name: kruizeconfig + restartPolicy: OnFailure +--- diff --git a/scripts/aks-helpers.sh b/scripts/aks-helpers.sh new file mode 100755 index 000000000..e04850f3b --- /dev/null +++ b/scripts/aks-helpers.sh @@ -0,0 +1,212 @@ +#!/bin/bash +# +# Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################### v AKS v ################################# + +function aks_first() { + #Create a namespace + echo "Create autotune namespace ${autotune_ns}" + kubectl create namespace ${autotune_ns} + + kubectl_cmd="kubectl -n ${autotune_ns}" + echo "Info: One time setup - Create a service account to deploy autotune" + + ${kubectl_cmd} apply -f ${AUTOTUNE_SA_MANIFEST} + check_err "Error: Failed to create service account and RBAC" + + ${kubectl_cmd} apply -f ${AUTOTUNE_OPERATOR_CRD} + check_err "Error: Failed to create autotune CRD" + + ${kubectl_cmd} apply -f ${AUTOTUNE_CONFIG_CRD} + check_err "Error: Failed to create autotuneconfig CRD" + + ${kubectl_cmd} apply -f ${AUTOTUNE_QUERY_VARIABLE_CRD} + check_err "Error: Failed to create autotunequeryvariable CRD" + + ${kubectl_cmd} apply -f ${AUTOTUNE_PERF_PROFILE_CRD} + check_err "Error: Failed to create autotunePerformanceProfile CRD" + + ${kubectl_cmd} apply -f ${AUTOTUNE_ROLE_MANIFEST} + check_err "Error: Failed to create role" + + sed -e "s|{{ AUTOTUNE_NAMESPACE }}|${autotune_ns}|" ${AUTOTUNE_RB_MANIFEST_TEMPLATE} > ${AUTOTUNE_RB_MANIFEST} + ${kubectl_cmd} apply -f ${AUTOTUNE_RB_MANIFEST} + check_err "Error: Failed to create role binding" + + sed -e "s|{{ AUTOTUNE_NAMESPACE }}|${autotune_ns}|" -e "s|{{ CLUSTER_TYPE }}|aks|" ${AUTOTUNE_QUERY_VARIABLES_MANIFEST_TEMPLATE} > ${AUTOTUNE_QUERY_VARIABLES_MANIFEST} + ${kubectl_cmd} apply -f ${AUTOTUNE_QUERY_VARIABLES_MANIFEST} + check_err "Error: Failed to create query variables" + + ${kubectl_cmd} apply -f ${SERVICE_MONITOR_MANIFEST} + check_err "Error: Failed to create service monitor for Prometheus" +} + +# You can deploy using kubectl +function aks_deploy() { + echo + echo "Creating environment variable in AKS cluster using configMap" + ${kubectl_cmd} apply -f ${AUTOTUNE_CONFIGMAPS}/${cluster_type}-config.yaml + + echo + echo "Deploying AutotuneConfig objects" + ${kubectl_cmd} apply -f ${AUTOTUNE_CONFIGS} + + echo + echo "Deploying Performance Profile objects" + ${kubectl_cmd} apply -f ${AUTOTUNE_PERF_PROFILE_ROS} + + echo "Info: Deploying autotune yaml to AKS cluster" + + # Replace autotune docker image in deployment yaml + sed -e "s|{{ AUTOTUNE_IMAGE }}|${AUTOTUNE_DOCKER_IMAGE}|" ${AUTOTUNE_DEPLOY_MANIFEST_TEMPLATE} > ${AUTOTUNE_DEPLOY_MANIFEST} + #sed -i "s|{{ HPO_IMAGE }}|${HPO_DOCKER_IMAGE}|" ${AUTOTUNE_DEPLOY_MANIFEST} + sed -i'' -e "s|{{ HPO_IMAGE }}|${HPO_DOCKER_IMAGE}|" "${AUTOTUNE_DEPLOY_MANIFEST}" + + ${kubectl_cmd} apply -f ${AUTOTUNE_DEPLOY_MANIFEST} + sleep 2 + check_running autotune ${autotune_ns} + if [ "${err}" != "0" ]; then + # Indicate deploy failed on error + exit 1 + fi + + # Get the Autotune application port in AKS + MINIKUBE_IP=$(minikube ip) + AUTOTUNE_PORT=$(${kubectl_cmd} get svc autotune --no-headers -o=custom-columns=PORT:.spec.ports[*].nodePort) + echo "Info: Access Autotune at http://${MINIKUBE_IP}:${AUTOTUNE_PORT}/listKruizeTunables" + echo +} + +function aks_start() { + echo + echo "### Installing autotune for AKS" + echo + + # If autotune_ns was not set by the user + if [ -z "$autotune_ns" ]; then + autotune_ns="monitoring" + fi + + check_prometheus_installation + aks_first + aks_deploy +} + +function check_prometheus_installation() { + echo + echo "Info: Checking pre requisites for AKS..." + check_kustomize + + kubectl_cmd="kubectl" + prometheus_pod_running=$(${kubectl_cmd} get pods --all-namespaces | grep "prometheus-k8s-1") + if [ "${prometheus_pod_running}" == "" ]; then + echo "Prometheus is not running, use 'scripts/prometheus_on_aks.sh' to install." + exit 1 + fi + echo "Prometheus is installed and running." +} + + +function aks_terminate() { + # If autotune_ns was not set by the user + if [ -z "$autotune_ns" ]; then + autotune_ns="monitoring" + fi + + echo -n "### Removing autotune for AKS" + + kubectl_cmd="kubectl -n ${autotune_ns}" + + echo + echo "Removing Performance Profile" + ${kubectl_cmd} delete -f ${AUTOTUNE_PERF_PROFILE_CRD} 2>/dev/null + + echo + echo "Removing autotune" + ${kubectl_cmd} delete -f ${AUTOTUNE_DEPLOY_MANIFEST} 2>/dev/null + + echo + echo "Removing autotune service account" + ${kubectl_cmd} delete -f ${AUTOTUNE_SA_MANIFEST} 2>/dev/null + + echo + echo "Removing autotune role" + ${kubectl_cmd} delete -f ${AUTOTUNE_ROLE_MANIFEST} 2>/dev/null + + echo + echo "Removing autotune rolebinding" + ${kubectl_cmd} delete -f ${AUTOTUNE_RB_MANIFEST} 2>/dev/null + + echo + echo "Removing autotune serviceMonitor" + ${kubectl_cmd} delete -f ${SERVICE_MONITOR_MANIFEST} 2>/dev/null + + echo + echo "Removing AutotuneConfig objects" + ${kubectl_cmd} delete -f ${AUTOTUNE_CONFIGS} 2>/dev/null + + echo + echo "Removing AutotuneQueryVariable objects" + ${kubectl_cmd} delete -f ${AUTOTUNE_QUERY_VARIABLES} 2>/dev/null + + echo + echo "Removing Autotune configmap" + ${kubectl_cmd} delete -f ${AUTOTUNE_CONFIGMAPS}/${cluster_type}-config.yaml 2>/dev/null + + echo + echo "Removing Autotune CRD" + ${kubectl_cmd} delete -f ${AUTOTUNE_OPERATOR_CRD} 2>/dev/null + + echo + echo "Removing AutotuneConfig CRD" + ${kubectl_cmd} delete -f ${AUTOTUNE_CONFIG_CRD} 2>/dev/null + + echo + echo "Removing AutotuneQueryVariables CRD" + ${kubectl_cmd} delete -f ${AUTOTUNE_QUERY_VARIABLE_CRD} 2>/dev/null + + rm ${AUTOTUNE_DEPLOY_MANIFEST} + rm ${AUTOTUNE_RB_MANIFEST} + rm ${AUTOTUNE_QUERY_VARIABLES_MANIFEST} +} + +# Deploy kruize in remote monitoring mode +function aks_crc_start() { + echo + echo "### Installing kruize for AKS" + echo + # If autotune_ns was not set by the user + if [ -z "$autotune_ns" ]; then + autotune_ns="monitoring" + fi + CRC_MANIFEST_FILE=${KRUIZE_CRC_DEPLOY_MANIFEST_AKS} + + kruize_crc_start +} + +function aks_crc_terminate() { + # If autotune_ns was not set by the user + if [ -z "$autotune_ns" ]; then + autotune_ns="monitoring" + fi + kubectl_cmd="kubectl -n ${autotune_ns}" + CRC_MANIFEST_FILE=${KRUIZE_CRC_DEPLOY_MANIFEST_AKS} + + echo -n "### Removing Kruize for AKS" + echo + ${kubectl_cmd} delete -f ${CRC_MANIFEST_FILE} 2>/dev/null +} diff --git a/scripts/prometheus_on_aks.sh b/scripts/prometheus_on_aks.sh new file mode 100755 index 000000000..f0a3ed96c --- /dev/null +++ b/scripts/prometheus_on_aks.sh @@ -0,0 +1,103 @@ +#!/bin/bash +# +# Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +current_dir="$(dirname "$0")" +non_interactive=0 +# Call setup by default (and not terminate) +setup=1 + +function install_prometheus(){ + echo + echo "Info: Prometheus Setup on AKS" + + prometheus_ns="monitoring" + kubectl_cmd="kubectl -n ${prometheus_ns}" + prometheus_pod_running=$(${kubectl_cmd} get pods | grep "prometheus-k8s-1") + + if [ "${prometheus_pod_running}" != "" ]; then + echo "Prometheus is already installed and running." + return; + fi + + rm -rf aks_prom_download || true + mkdir aks_prom_download 2>/dev/null + pushd aks_prom_download >/dev/null + echo "Info: Cloning Prometheus Operator & few AKS Customisations git" + git clone https://github.com/mukrishn/arohcp-workspace + git clone https://github.com/prometheus-operator/kube-prometheus + pushd kube-prometheus + kubectl apply --server-side -f manifests/setup + kubectl wait \ + --for condition=Established \ + --all CustomResourceDefinition \ + --namespace=monitoring + kubectl apply -f manifests/ + popd + echo "Info: Applying Custom config Changes" + pushd arohcp-workspace/aks-monitoring-config + kubectl apply -f prometheus-roleBindingSpecificNamespaces.yaml || true + kubectl apply -f prometheus-roleSpecificNamespaces.yaml || true + kubectl apply -f prom-public-svc.yaml || true +} + +function delete_prometheus(){ + echo "Info: Removing Prometheus Setup from AKS" + rm -rf aks_remove || true + mkdir aks_prom_remove 2>/dev/null + pushd aks_prom_remove + echo "Info: Cloning Prometheus Operator" + git clone https://github.com/prometheus-operator/kube-prometheus + pushd kube-prometheus + kubectl delete --ignore-not-found=true -f manifests/ -f manifests/setup +} + +# Input from user to install/delete prometheus +function usage() { + echo >&2 "usage: $0 [-a] [-s|t] where -a= non-interactive mode, -s=start, -t=terminate "; + exit 1; +} + +# empty argument validation +if [ $# -eq 0 ]; then + usage +fi + +while getopts "ast" option; +do + case "${option}" in + a) + non_interactive=1 + ;; + s) # For option s to install the prometheus + setup=1 + ;; + t) # For option t terminating and deleting the prometheus + setup=0 + ;; + \?) # For invalid option + usage + ;; + esac +done + +if [ "${setup}" == 1 ]; then + echo "Info: Installing Prometheus on AKS..." + install_prometheus +else + echo "Info: Deleting prometheus from AKS..." + delete_prometheus +fi From 74b0dd9a863441086debaa710b958e5965c33927 Mon Sep 17 00:00:00 2001 From: Krishna Harsha Voora Date: Wed, 3 Jul 2024 00:17:30 +0530 Subject: [PATCH 09/77] Fixes Postgres startup issues --- .../aks/kruize-crc-aks.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml b/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml index 532d94e55..ce32a99c1 100644 --- a/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml +++ b/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml @@ -28,9 +28,6 @@ spec: labels: app: postgres spec: - #securityContext: #todo - # runAsNonRoot: true - # runAsUser: 1000 containers: - name: postgres image: quay.io/kruizehub/postgres:15.2 @@ -42,11 +39,13 @@ spec: value: admin - name: POSTGRES_DB value: kruizeDB + - name: PGDATA + value: /var/lib/postgresql/backup ports: - containerPort: 5432 volumeMounts: - name: postgres-storage - mountPath: /var/lib/postgresql/data + mountPath: /var/lib/postgresql volumes: - name: postgres-storage persistentVolumeClaim: From 77549358545654c94353c729d8e86d3a0ff263ba Mon Sep 17 00:00:00 2001 From: Krishna Harsha Voora Date: Wed, 3 Jul 2024 07:49:54 +0530 Subject: [PATCH 10/77] Add spec.type as LoadBalancer for kruize/kruize-ui Signed-off-by: Krishna Harsha Voora --- .../minikube/kruize-crc-minikube.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml index 572edd19c..861cd16aa 100644 --- a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml +++ b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml @@ -221,7 +221,7 @@ metadata: labels: app: kruize spec: - type: NodePort + type: LoadBalancer selector: app: kruize ports: @@ -323,7 +323,7 @@ metadata: name: kruize-ui-nginx-service namespace: monitoring spec: - type: NodePort + type: LoadBalancer ports: - name: http port: 8080 From c4712f714d27b69a2cac83bba8e7cd6b15b530aa Mon Sep 17 00:00:00 2001 From: Krishna Harsha Voora Date: Wed, 3 Jul 2024 07:57:18 +0530 Subject: [PATCH 11/77] Add spec.type as LoadBalancer for kruize/kruize-ui Signed-off-by: Krishna Harsha Voora --- .../default-db-included-installation/aks/kruize-crc-aks.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml b/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml index ce32a99c1..b0e73be2c 100644 --- a/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml +++ b/manifests/crc/default-db-included-installation/aks/kruize-crc-aks.yaml @@ -195,7 +195,7 @@ metadata: labels: app: kruize spec: - type: NodePort + type: LoadBalancer selector: app: kruize ports: @@ -297,7 +297,7 @@ metadata: name: kruize-ui-nginx-service namespace: monitoring spec: - type: NodePort + type: LoadBalancer ports: - name: http port: 8080 From e0bfe2c4f3ade476eaa97da2d2c9cea18df9cc48 Mon Sep 17 00:00:00 2001 From: Saad Khan Date: Thu, 4 Jul 2024 10:50:48 +0530 Subject: [PATCH 12/77] update recommendationEngine and related files to include support for 'job' Signed-off-by: Saad Khan --- .../engine/RecommendationEngine.java | 16 +++++++++++++--- .../analyzer/utils/AnalyzerConstants.java | 2 ++ .../java/com/autotune/utils/KruizeConstants.java | 3 +++ src/main/java/com/autotune/utils/Utils.java | 2 ++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index ad06a3d69..98af831ea 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -264,8 +264,17 @@ public KruizeObject prepareRecommendations(int calCount) { // continue to generate recommendation when kruizeObject is successfully created try { // set the default terms if the terms aren't provided by the user - if (kruizeObject.getTerms() == null) - KruizeObject.setDefaultTerms(terms, kruizeObject); + if (kruizeObject.getTerms() == null) { + if (kruizeObject.getKubernetes_objects().get(0).getType().equals(AnalyzerConstants.K8sObjectConstants.Types.JOB)) { + // set fixed term for 'jobs' + terms.put(KruizeConstants.JSONKeys.FIXED_TERM, new Terms(KruizeConstants.JSONKeys.FIXED_TERM, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.FIXED_TERM_DURATION_DAYS, KruizeConstants + .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.FIXED_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); // TODO: plots_datapoints, plots_datapoints_delta_in_days needs to be updated after POC + kruizeObject.setTerms(terms); + } else { + KruizeObject.setDefaultTerms(terms, kruizeObject); + } + } // set the performance profile setPerformanceProfile(kruizeObject.getPerformanceProfile()); // get the datasource @@ -779,7 +788,8 @@ private boolean populateRecommendation(Map.Entry termEntry, ( !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.SHORT_TERM) && !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.MEDIUM_TERM) && - !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.LONG_TERM) + !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.LONG_TERM) && + !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.FIXED_TERM) ) ) { LOGGER.error(String.format(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.INVALID_RECOMMENDATION_TERM, recommendationTerm)); diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index c91f600ea..37bc3b336 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -169,6 +169,7 @@ public enum K8S_OBJECT_TYPES { REPLICASET, REPLICATION_CONTROLLER, DAEMONSET, + JOB, } public enum RegisterRecommendationModelStatus { @@ -483,6 +484,7 @@ public static final class Types { public static final String REPLICASET = "replicaset"; public static final String REPLICATION_CONTROLLER = "replicationController"; public static final String DAEMONSET = "daemonset"; + public static final String JOB = "job"; private Types() { diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 27c468210..6b0085d12 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -228,6 +228,7 @@ public static final class JSONKeys { public static final String SHORT_TERM = "short_term"; public static final String MEDIUM_TERM = "medium_term"; public static final String LONG_TERM = "long_term"; + public static final String FIXED_TERM = "fixed_term"; public static final String RECOMMENDATIONS = "recommendations"; public static final String VARIATION = "variation"; public static final String NOTIFICATIONS = "notifications"; @@ -657,6 +658,8 @@ public static final class DurationAmount { public static final int MEDIUM_TERM_DURATION_DAYS_THRESHOLD = 2; public static final int LONG_TERM_DURATION_DAYS = 15; public static final int LONG_TERM_DURATION_DAYS_THRESHOLD = 8; + public static final int FIXED_TERM_DURATION_DAYS = 0; // TODO: temporarily set as zero, need to update this after the POC + public static final int FIXED_TERM_DURATION_DAYS_THRESHOLD = 0; // TODO: temporarily set as zero, need to update this after the POC private DurationAmount() { diff --git a/src/main/java/com/autotune/utils/Utils.java b/src/main/java/com/autotune/utils/Utils.java index 2d5e232f7..3d65dea4c 100644 --- a/src/main/java/com/autotune/utils/Utils.java +++ b/src/main/java/com/autotune/utils/Utils.java @@ -90,6 +90,8 @@ public static AnalyzerConstants.K8S_OBJECT_TYPES getApproriateK8sObjectType(Stri if (objectType.equalsIgnoreCase(AnalyzerConstants.K8sObjectConstants.Types.DAEMONSET)) return AnalyzerConstants.K8S_OBJECT_TYPES.DAEMONSET; + if (objectType.equalsIgnoreCase(AnalyzerConstants.K8sObjectConstants.Types.JOB)) + return AnalyzerConstants.K8S_OBJECT_TYPES.JOB; return null; } From 1dfbdd0b6ba18e31c94a429f694ff91e34927509 Mon Sep 17 00:00:00 2001 From: Saad Khan Date: Thu, 4 Jul 2024 18:28:49 +0530 Subject: [PATCH 13/77] fix issues occurred while generating recommendations, update threshold values and related constants changes Signed-off-by: Saad Khan --- .../recommendations/RecommendationConstants.java | 12 +++++++++++- .../recommendations/RecommendationNotification.java | 2 ++ .../analyzer/recommendations/term/Terms.java | 10 ++++++++++ .../java/com/autotune/utils/KruizeConstants.java | 8 ++++++-- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/RecommendationConstants.java b/src/main/java/com/autotune/analyzer/recommendations/RecommendationConstants.java index 4cc4be488..4d2eb4285 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/RecommendationConstants.java +++ b/src/main/java/com/autotune/analyzer/recommendations/RecommendationConstants.java @@ -52,7 +52,9 @@ public enum RecommendationTerms { .LONG_TERM_TOTAL_DURATION_UPPER_BOUND_MINS, KruizeConstants.RecommendationEngineConstants .DurationBasedEngine.RecommendationDurationRanges - .LONG_TERM_TOTAL_DURATION_LOWER_BOUND_MINS); + .LONG_TERM_TOTAL_DURATION_LOWER_BOUND_MINS), + FIXED_TERM(KruizeConstants.JSONKeys.FIXED_TERM, FIXED_TERM_HOURS, FIXED_TERM_TOTAL_DURATION_UPPER_BOUND_MINS, + FIXED_TERM_TOTAL_DURATION_LOWER_BOUND_MINS); private String value; private double durationInHrs; @@ -93,6 +95,7 @@ public static double getMaxDuration(RecommendationTerms termValue) { case SHORT_TERM -> SHORT_TERM_HOURS; case MEDIUM_TERM -> MEDIUM_TERM_HOURS; case LONG_TERM -> LONG_TERM_HOURS; + case FIXED_TERM -> FIXED_TERM_HOURS; }; } } @@ -118,6 +121,11 @@ public enum RecommendationNotification { RecommendationConstants.RecommendationNotificationMsgConstant.LONG_TERM_RECOMMENDATIONS_AVAILABLE, RecommendationConstants.RecommendationNotificationTypes.INFO ), + INFO_FIXED_TERM_RECOMMENDATIONS_AVAILABLE( + NotificationCodes.INFO_FIXED_TERM_RECOMMENDATIONS_AVAILABLE, + RecommendationNotificationMsgConstant.FIXED_TERM_RECOMMENDATIONS_AVAILABLE, + RecommendationConstants.RecommendationNotificationTypes.INFO + ), INFO_COST_RECOMMENDATIONS_AVAILABLE( RecommendationConstants.NotificationCodes.INFO_COST_RECOMMENDATIONS_AVAILABLE, RecommendationConstants.RecommendationNotificationMsgConstant.COST_RECOMMENDATIONS_AVAILABLE, @@ -316,6 +324,7 @@ public static final class NotificationCodes { public static final int INFO_SHORT_TERM_RECOMMENDATIONS_AVAILABLE = 111101; // TODO: need to discuss the code public static final int INFO_MEDIUM_TERM_RECOMMENDATIONS_AVAILABLE = 111102; // TODO: need to discuss the code public static final int INFO_LONG_TERM_RECOMMENDATIONS_AVAILABLE = 111103; // TODO: need to discuss the code; + public static final int INFO_FIXED_TERM_RECOMMENDATIONS_AVAILABLE = 111104; // TODO: need to discuss the code; public static final int INFO_COST_RECOMMENDATIONS_AVAILABLE = 112101; public static final int INFO_PERFORMANCE_RECOMMENDATIONS_AVAILABLE = 112102; public static final int COST_ENGINE_END = 112199; @@ -645,6 +654,7 @@ public static final class RecommendationNotificationMsgConstant { public static final String SHORT_TERM_RECOMMENDATIONS_AVAILABLE = "Short Term Recommendations Available"; public static final String MEDIUM_TERM_RECOMMENDATIONS_AVAILABLE = "Medium Term Recommendations Available"; public static final String LONG_TERM_RECOMMENDATIONS_AVAILABLE = "Long Term Recommendations Available"; + public static final String FIXED_TERM_RECOMMENDATIONS_AVAILABLE = "Fixed Term Recommendations Available"; public static final String CPU_RECORDS_ARE_IDLE = "CPU Usage is less than a millicore, No CPU Recommendations can be generated"; public static final String CPU_RECORDS_ARE_ZERO = "CPU usage is zero, No CPU Recommendations can be generated"; public static final String MEMORY_RECORDS_ARE_ZERO = "Memory Usage is zero, No Memory Recommendations can be generated"; diff --git a/src/main/java/com/autotune/analyzer/recommendations/RecommendationNotification.java b/src/main/java/com/autotune/analyzer/recommendations/RecommendationNotification.java index 06ec0475a..df5ab61b6 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/RecommendationNotification.java +++ b/src/main/java/com/autotune/analyzer/recommendations/RecommendationNotification.java @@ -59,6 +59,8 @@ public static RecommendationNotification getNotificationForTermAvailability(Stri recommendationNotification = new RecommendationNotification(RecommendationConstants.RecommendationNotification.INFO_MEDIUM_TERM_RECOMMENDATIONS_AVAILABLE); } else if (recommendationTerm.equalsIgnoreCase(RecommendationConstants.RecommendationTerms.LONG_TERM.getValue())) { recommendationNotification = new RecommendationNotification(RecommendationConstants.RecommendationNotification.INFO_LONG_TERM_RECOMMENDATIONS_AVAILABLE); + } else if (recommendationTerm.equalsIgnoreCase(RecommendationConstants.RecommendationTerms.FIXED_TERM.getValue())) { + recommendationNotification = new RecommendationNotification(RecommendationConstants.RecommendationNotification.INFO_FIXED_TERM_RECOMMENDATIONS_AVAILABLE); } return recommendationNotification; } diff --git a/src/main/java/com/autotune/analyzer/recommendations/term/Terms.java b/src/main/java/com/autotune/analyzer/recommendations/term/Terms.java index 16eadcea3..305ef2ec4 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/term/Terms.java +++ b/src/main/java/com/autotune/analyzer/recommendations/term/Terms.java @@ -154,6 +154,7 @@ public static double getMaxDuration(String termValue) { case SHORT_TERM -> SHORT_TERM_HOURS; case MEDIUM_TERM -> MEDIUM_TERM_HOURS; case LONG_TERM -> LONG_TERM_HOURS; + case FIXED_TERM -> FIXED_TERM_HOURS; default -> throw new IllegalStateException("Unexpected value: " + termValue); }; } @@ -190,4 +191,13 @@ public double getPlots_datapoints_delta_in_days() { public void setPlots_datapoints_delta_in_days(double plots_datapoints_delta_in_days) { this.plots_datapoints_delta_in_days = plots_datapoints_delta_in_days; } + + @Override + public String toString() { + return "Terms{" + + "days=" + days + + ", threshold_in_days=" + threshold_in_days + + ", name='" + name + '\'' + + '}'; + } } diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 6b0085d12..9bb6e4f51 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -658,8 +658,8 @@ public static final class DurationAmount { public static final int MEDIUM_TERM_DURATION_DAYS_THRESHOLD = 2; public static final int LONG_TERM_DURATION_DAYS = 15; public static final int LONG_TERM_DURATION_DAYS_THRESHOLD = 8; - public static final int FIXED_TERM_DURATION_DAYS = 0; // TODO: temporarily set as zero, need to update this after the POC - public static final int FIXED_TERM_DURATION_DAYS_THRESHOLD = 0; // TODO: temporarily set as zero, need to update this after the POC + public static final int FIXED_TERM_DURATION_DAYS = 1; // TODO: temporarily set as 1 day, need to update this after the POC + public static final double FIXED_TERM_DURATION_DAYS_THRESHOLD = ((double) 1 / (24 * 60)); // TODO: temporarily set as 1 min, need to update this after the POC private DurationAmount() { @@ -671,6 +671,7 @@ public static final class RecommendationDurationRanges { public static final double SHORT_TERM_MIN_DATA_THRESHOLD_MINS = 30; public static final double MEDIUM_TERM_MIN_DATA_THRESHOLD_MINS = 2 * TimeConv.NO_OF_HOURS_PER_DAY * TimeConv.NO_OF_MINUTES_PER_HOUR; public static final double LONG_TERM_MIN_DATA_THRESHOLD_MINS = 8 * TimeConv.NO_OF_HOURS_PER_DAY * TimeConv.NO_OF_MINUTES_PER_HOUR; + public static final double FIXED_TERM_MIN_DATA_THRESHOLD_MINS = 1; /* LONG TERM */ public static final double LONG_TERM_TOTAL_DURATION_UPPER_BOUND_MINS = LONG_TERM_MIN_DATA_THRESHOLD_MINS + MEASUREMENT_DURATION_BUFFER_IN_MINS; public static final double LONG_TERM_TOTAL_DURATION_LOWER_BOUND_MINS = @@ -681,8 +682,11 @@ public static final class RecommendationDurationRanges { public static final double SHORT_TERM_HOURS = DurationAmount.SHORT_TERM_DURATION_DAYS * KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY; public static final double MEDIUM_TERM_HOURS = DurationAmount.MEDIUM_TERM_DURATION_DAYS * KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY; public static final double LONG_TERM_HOURS = DurationAmount.LONG_TERM_DURATION_DAYS * KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY; + public static final double FIXED_TERM_HOURS = DurationAmount.FIXED_TERM_DURATION_DAYS * KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY; public static final double SHORT_TERM_TOTAL_DURATION_UPPER_BOUND_MINS = SHORT_TERM_MIN_DATA_THRESHOLD_MINS + MEASUREMENT_DURATION_BUFFER_IN_MINS; public static final double SHORT_TERM_TOTAL_DURATION_LOWER_BOUND_MINS = SHORT_TERM_MIN_DATA_THRESHOLD_MINS - MEASUREMENT_DURATION_BUFFER_IN_MINS; + public static final double FIXED_TERM_TOTAL_DURATION_UPPER_BOUND_MINS = FIXED_TERM_MIN_DATA_THRESHOLD_MINS - MEASUREMENT_DURATION_BUFFER_IN_MINS; + public static final double FIXED_TERM_TOTAL_DURATION_LOWER_BOUND_MINS = FIXED_TERM_MIN_DATA_THRESHOLD_MINS - MEASUREMENT_DURATION_BUFFER_IN_MINS; private RecommendationDurationRanges() { From c5226d89c96cd6f40d8016d3704ac92fa9d845d6 Mon Sep 17 00:00:00 2001 From: Krishna Harsha Voora Date: Fri, 5 Jul 2024 19:25:25 +0530 Subject: [PATCH 14/77] Revert changes to normal in minikube Signed-off-by: Krishna Harsha Voora --- .../minikube/kruize-crc-minikube.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml index 861cd16aa..572edd19c 100644 --- a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml +++ b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml @@ -221,7 +221,7 @@ metadata: labels: app: kruize spec: - type: LoadBalancer + type: NodePort selector: app: kruize ports: @@ -323,7 +323,7 @@ metadata: name: kruize-ui-nginx-service namespace: monitoring spec: - type: LoadBalancer + type: NodePort ports: - name: http port: 8080 From 01e90f10bb416ff7d77953c4f723ce456398077a Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 9 Jul 2024 12:14:06 +0530 Subject: [PATCH 15/77] Add create metric profile tests --- tests/scripts/helpers/kruize.py | 44 ++++ tests/scripts/helpers/utils.py | 2 + ...optimization_openshift_metric_profile.json | 198 ++++++++++++++++++ .../rest_apis/test_create_metric_profile.py | 94 +++++++++ 4 files changed, 338 insertions(+) create mode 100644 tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json create mode 100644 tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py diff --git a/tests/scripts/helpers/kruize.py b/tests/scripts/helpers/kruize.py index 9bf240540..96b36697f 100644 --- a/tests/scripts/helpers/kruize.py +++ b/tests/scripts/helpers/kruize.py @@ -364,3 +364,47 @@ def list_metadata(datasource=None, cluster_name=None, namespace=None, verbose=No print(response.text) print("\n************************************************************") return response + + +# Description: This function creates a metric profile using the Kruize createMetricProfile API +# Input Parameters: metric profile json +def create_metric_profile(metric_profile_json_file): + json_file = open(metric_profile_json_file, "r") + metric_profile_json = json.loads(json_file.read()) + + print("\nCreating metric profile...") + url = URL + "/createMetricProfile" + print("URL = ", url) + + response = requests.post(url, json=metric_profile_json) + print("Response status code = ", response.status_code) + print(response.text) + return response + +# Description: This function deletes the metric profile +# Input Parameters: metric profile input json +def delete_metric_profile(input_json_file, invalid_header=False): + json_file = open(input_json_file, "r") + input_json = json.loads(json_file.read()) + + print("\nDeleting the metric profile...") + #TODO change the API endpoint based on the implementation + url = URL + "/createMetricProfile" + print("URL = ", url) + + metric_profile_name = input_json['metadata']['name'] + + delete_json = [{ + "name": metric_profile_name + }] + + headers = {'content-type': 'application/xml'} + if invalid_header: + print("Invalid header") + response = requests.delete(url, json=delete_json, headers=headers) + else: + response = requests.delete(url, json=delete_json) + + print(response) + print("Response status code = ", response.status_code) + return response diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 2c48aedc6..290285a26 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -57,6 +57,8 @@ LIST_METADATA_DATASOURCE_NAME_CLUSTER_NAME_ERROR_MSG = "Metadata for a given datasource name - %s, cluster_name - %s either does not exist or is not valid" LIST_METADATA_MISSING_DATASOURCE = "datasource is mandatory" IMPORT_METADATA_DATASOURCE_CONNECTION_FAILURE_MSG = "Metadata cannot be imported, datasource connection refused or timed out" +CREATE_METRIC_PROFILE_SUCCESS_MSG = "Metric Profile : \"%s\" created successfully. View Metric Profiles at /listMetricProfiles" +METRIC_PROFILE_EXISTS_MSG = "Validation failed: Metric Profile already exists: \"%s\"" # Kruize Recommendations Notification codes NOTIFICATION_CODE_FOR_RECOMMENDATIONS_AVAILABLE = "111000" diff --git a/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json b/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json new file mode 100644 index 000000000..973f65b7f --- /dev/null +++ b/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json @@ -0,0 +1,198 @@ +{ + "apiVersion": "recommender.com/v1", + "kind": "KruizePerformanceProfile", + "metadata": { + "name": "resource-optimization-openshift" + }, + "profile_version": 1, + "k8s_type": "openshift", + "slo": { + "slo_class": "resource_usage", + "direction": "minimize", + "objective_function": { + "function_type": "source" + }, + "function_variables": [ + { + "name": "cpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg(kube_pod_container_resource_requests{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE\", resource=\"cpu\", unit=\"core\"})" + }, + { + "function": "sum", + "query": "sum(kube_pod_container_resource_requests{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE\", resource=\"cpu\", unit=\"core\"})" + } + ] + }, + { + "name": "cpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg(kube_pod_container_resource_limits{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE\", resource=\"cpu\", unit=\"core\"})" + }, + { + "function": "sum", + "query": "sum(kube_pod_container_resource_limits{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\", resource=\"cpu\", unit=\"core\"})" + } + ] + }, + { + "name": "cpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))", + "versions": "<=4.8" + }, + { + "function": "avg", + "query": "avg(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))", + "versions": ">4.9" + }, + { + "function": "min", + "query": "min(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", + "versions": "<=4.8" + }, + { + "function": "min", + "query": "min(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", + "versions": ">4.9" + }, + { + "function": "max", + "query": "max(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", + "versions": "<=4.8" + }, + { + "function": "max", + "query": "max(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", + "versions": ">4.9" + }, + { + "function": "sum", + "query": "sum(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", + "versions": "<=4.8" + }, + { + "function": "sum", + "query": "sum(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", + "versions": ">4.9" + } + ] + }, + { + "name": "cpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg(rate(container_cpu_cfs_throttled_seconds_total{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))" + }, + { + "function": "max", + "query": "max(rate(container_cpu_cfs_throttled_seconds_total{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))" + }, + { + "function": "sum", + "query": "sum(rate(container_cpu_cfs_throttled_seconds_total{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))" + } + ] + }, + { + "name": "memoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg(kube_pod_container_resource_requests{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource=\"memory\", unit=\"byte\"})" + }, + { + "function": "sum", + "query": "sum(kube_pod_container_resource_requests{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource=\"memory\", unit=\"byte\"})" + } + ] + }, + { + "name": "memoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg(kube_pod_container_resource_limits{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE\", resource=\"memory\", unit=\"byte\"})" + }, + { + "function": "sum", + "query": "sum(kube_pod_container_resource_limits{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource=\"memory\", unit=\"byte\"})" + } + ] + }, + { + "name": "memoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg(avg_over_time(container_memory_working_set_bytes{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))" + }, + { + "function": "min", + "query": "min(min_over_time(container_memory_working_set_bytes{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + }, + { + "function": "max", + "query": "max(max_over_time(container_memory_working_set_bytes{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + }, + { + "function": "sum", + "query": "sum(avg_over_time(container_memory_working_set_bytes{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + } + ] + }, + { + "name": "memoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg(avg_over_time(container_memory_rss{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))" + }, + { + "function": "min", + "query": "min(min_over_time(container_memory_rss{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + }, + { + "function": "max", + "query": "max(max_over_time(container_memory_rss{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + }, + { + "function": "sum", + "query": "sum(avg_over_time(container_memory_rss{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py new file mode 100644 index 000000000..70092144b --- /dev/null +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py @@ -0,0 +1,94 @@ +""" +Copyright (c) 2024, 2024 Red Hat, IBM Corporation and others. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import pytest +import json +import sys + +sys.path.append("../../") + +from helpers.fixtures import * +from helpers.kruize import * +from helpers.utils import * + +@pytest.mark.sanity +def test_create_metric_profile(cluster_type): + """ + Test Description: This test validates the response status code of createMetricProfile API by passing a + valid input for the json + """ + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + form_kruize_url(cluster_type) + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + # Create metric profile using the specified json + response = create_metric_profile(input_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + + json_file = open(input_json_file, "r") + input_json = json.loads(json_file.read()) + metric_profile_name = input_json['metadata']['name'] + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + +@pytest.mark.sanity +def test_create_duplicate_metric_profile(cluster_type): + """ + Test Description: This test validates the response status code of createMetricProfile API by specifying the + same metric profile name + """ + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + json_data = json.load(open(input_json_file)) + + metric_profile_name = json_data['metadata']['name'] + print("name = ", metric_profile_name) + + form_kruize_url(cluster_type) + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + # Create metric profile using the specified json + response = create_metric_profile(input_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + # Create metric profile using the specified json + response = create_metric_profile(input_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == ERROR_409_STATUS_CODE + assert data['status'] == ERROR_STATUS + assert data['message'] == METRIC_PROFILE_EXISTS_MSG % metric_profile_name + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) \ No newline at end of file From 69370d31a486aa4bf59b3c721197eff1c916d55d Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 22 Jul 2024 18:40:37 +0530 Subject: [PATCH 16/77] Add mandatory and create multiple metric profile testcases --- tests/scripts/helpers/utils.py | 5 +- .../rest_apis/test_create_metric_profile.py | 112 +++++++++++++++++- 2 files changed, 114 insertions(+), 3 deletions(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 290285a26..49c4aefec 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -28,6 +28,7 @@ ERROR_STATUS_CODE = 400 ERROR_409_STATUS_CODE = 409 DUPLICATE_RECORDS_COUNT = 5 +ERROR_500_STATUS_CODE = 500 SUCCESS_STATUS = "SUCCESS" ERROR_STATUS = "ERROR" @@ -57,8 +58,8 @@ LIST_METADATA_DATASOURCE_NAME_CLUSTER_NAME_ERROR_MSG = "Metadata for a given datasource name - %s, cluster_name - %s either does not exist or is not valid" LIST_METADATA_MISSING_DATASOURCE = "datasource is mandatory" IMPORT_METADATA_DATASOURCE_CONNECTION_FAILURE_MSG = "Metadata cannot be imported, datasource connection refused or timed out" -CREATE_METRIC_PROFILE_SUCCESS_MSG = "Metric Profile : \"%s\" created successfully. View Metric Profiles at /listMetricProfiles" -METRIC_PROFILE_EXISTS_MSG = "Validation failed: Metric Profile already exists: \"%s\"" +CREATE_METRIC_PROFILE_SUCCESS_MSG = "Metric Profile : %s created successfully. View Metric Profiles at /listMetricProfiles" +METRIC_PROFILE_EXISTS_MSG = "Validation failed: Metric Profile already exists: %s" # Kruize Recommendations Notification codes NOTIFICATION_CODE_FOR_RECOMMENDATIONS_AVAILABLE = "111000" diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py index 70092144b..ea9cd622e 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py @@ -16,6 +16,7 @@ import pytest import json import sys +import copy sys.path.append("../../") @@ -23,6 +24,15 @@ from helpers.kruize import * from helpers.utils import * +mandatory_fields = [ + ("apiVersion", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("kind", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("metadata", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("name", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("slo", ERROR_500_STATUS_CODE, ERROR_STATUS) +] + + @pytest.mark.sanity def test_create_metric_profile(cluster_type): """ @@ -91,4 +101,104 @@ def test_create_duplicate_metric_profile(cluster_type): assert data['message'] == METRIC_PROFILE_EXISTS_MSG % metric_profile_name response = delete_metric_profile(input_json_file) - print("delete metric profile = ", response.status_code) \ No newline at end of file + print("delete metric profile = ", response.status_code) + + +@pytest.mark.sanity +def test_create_multiple_metric_profiles(cluster_type): + """ + Test Description: This test validates the creation of multiple metric profiles using different json files + """ + + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + output_json_file = "/tmp/create_metric_profile.json" + temp_json_file = "/tmp/temp_profile.json" + + input_json_data = json.load(open(input_json_file, 'r')) + + form_kruize_url(cluster_type) + + metric_profiles = [] + + input_metric_profile_name = input_json_data['metadata']['name'] + + # Create metric profile using the specified json + num_exps = 100 + for i in range(num_exps): + json_data = copy.deepcopy(input_json_data) + # Modify the name for each profile + metric_profile_name = f"{input_metric_profile_name}_{i}" + json_data['metadata']['name'] = metric_profile_name + + # Write the modified profile to a temporary file + with open(temp_json_file, 'w') as file: + json.dump(json_data, file, indent=4) + + response = delete_metric_profile(temp_json_file) + print("delete metric profile = ", response.status_code) + + response = create_metric_profile(temp_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + metric_profiles.append(copy.deepcopy(json_data)) + + response = delete_metric_profile(temp_json_file) + print("delete metric profile = ", response.status_code) + + # Write the profiles to the output file + with open(output_json_file, 'w') as file: + json.dump(metric_profiles, file, indent=4) + + +@pytest.mark.extended +@pytest.mark.parametrize("field, expected_status_code, expected_status", mandatory_fields) +def test_create_metric_profiles_mandatory_fields(cluster_type, field, expected_status_code, expected_status): + """ + Test Description: This test validates the creation of metric profile by missing the mandatory fields and validating + the error message and status code + """ + + form_kruize_url(cluster_type) + + # Create metric profile using the specified json + json_file = "/tmp/create_metric_profile.json" + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + json_data = json.load(open(input_json_file)) + + if field == "apiVersion": + json_data.pop("apiVersion", None) + elif field == "kind": + json_data.pop("kind", None) + elif field == "metadata": + json_data.pop("metadata", None) + elif field == "name": + json_data['metadata'].pop("name", None) + elif field == "slo": + json_data.pop("slo", None) + + print("\n*****************************************") + print(json_data) + print("*****************************************\n") + data = json.dumps(json_data) + with open(json_file, 'w') as file: + file.write(data) + + response = delete_metric_profile(json_file) + print("delete metric profile = ", response.status_code) + response = create_metric_profile(json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == expected_status_code, \ + f"Mandatory field check failed for {field} actual - {response.status_code} expected - {expected_status_code}" + assert data['status'] == expected_status + + response = delete_metric_profile(json_file) + print("delete metric profile = ", response.status_code) From a3799be108052d573039c685ff5804d1d03a04cf Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 25 Jul 2024 11:19:47 +0530 Subject: [PATCH 17/77] Add list metric profiles schema --- tests/scripts/helpers/kruize.py | 29 ++++++ .../helpers/list_metric_profiles_schema.py | 93 +++++++++++++++++++ ...tric_profiles_without_parameters_schema.py | 12 +++ .../rest_apis/test_create_metric_profile.py | 10 ++ .../rest_apis/test_list_metric_profiles.py | 62 +++++++++++++ 5 files changed, 206 insertions(+) create mode 100644 tests/scripts/helpers/list_metric_profiles_schema.py create mode 100644 tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py create mode 100644 tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py diff --git a/tests/scripts/helpers/kruize.py b/tests/scripts/helpers/kruize.py index 96b36697f..a9c836ace 100644 --- a/tests/scripts/helpers/kruize.py +++ b/tests/scripts/helpers/kruize.py @@ -408,3 +408,32 @@ def delete_metric_profile(input_json_file, invalid_header=False): print(response) print("Response status code = ", response.status_code) return response + + +# Description: This function lists the metric profile from Kruize Autotune using GET listMetricProfiles API +# Input Parameters: metric profile name and verbose - flag indicating granularity of data to be listed +def list_metric_profiles(name=None, verbose=None, logging=True): + print("\nListing the metric profiles...") + + query_params = {} + + if name is not None: + query_params['name'] = name + if verbose is not None: + query_params['verbose'] = verbose + + query_string = "&".join(f"{key}={value}" for key, value in query_params.items()) + + url = URL + "/listMetricProfiles" + if query_string: + url += "?" + query_string + print("URL = ", url) + print("PARAMS = ", query_params) + response = requests.get(url) + + print("Response status code = ", response.status_code) + if logging: + print("\n************************************************************") + print(response.text) + print("\n************************************************************") + return response diff --git a/tests/scripts/helpers/list_metric_profiles_schema.py b/tests/scripts/helpers/list_metric_profiles_schema.py new file mode 100644 index 000000000..f6e7de63b --- /dev/null +++ b/tests/scripts/helpers/list_metric_profiles_schema.py @@ -0,0 +1,93 @@ +list_metric_profiles_schema = { + "type": "array", + "items": { + "type": "object", + "properties": { + "apiVersion": { + "type": "string" + }, + "kind": { + "type": "string" + }, + "metadata": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": ["name"] + }, + "profile_version": { + "type": "number" + }, + "k8s_type": { + "type": "string" + }, + "slo": { + "type": "object", + "properties": { + "sloClass": { + "type": "string" + }, + "objective_function": { + "type": "object", + "properties": { + "function_type": { + "type": "string" + } + }, + "required": ["function_type"] + }, + "direction": { + "type": "string" + }, + "function_variables": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "datasource": { + "type": "string" + }, + "value_type": { + "type": "string" + }, + "kubernetes_object": { + "type": "string" + }, + "aggregation_functions": { + "type": "array", + "items": { + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9_-]+$": { + "type": "object", + "properties": { + "function": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$" + }, + "query": { + "type": "string" + } + }, + "required": ["function", "query"] + }, + }, + } + }, + } + }, + "required": ["name", "datasource", "value_type", "kubernetes_object", "aggregation_functions"] + } + } + }, + "required": ["sloClass", "objective_function", "direction", "function_variables"] + } + }, + "required": ["apiVersion", "kind", "metadata", "profile_version", "k8s_type", "slo"] +} diff --git a/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py b/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py new file mode 100644 index 000000000..a673c2bbd --- /dev/null +++ b/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py @@ -0,0 +1,12 @@ +list_metric_profiles_schema = { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": ["name"] + } +} diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py index ea9cd622e..7e9c56157 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py @@ -23,6 +23,7 @@ from helpers.fixtures import * from helpers.kruize import * from helpers.utils import * +from helpers.list_metric_profiles_validate import * mandatory_fields = [ ("apiVersion", ERROR_500_STATUS_CODE, ERROR_STATUS), @@ -59,6 +60,15 @@ def test_create_metric_profile(cluster_type): metric_profile_name = input_json['metadata']['name'] assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + response = list_metric_profiles(name=metric_profile_name) + metric_profile_json = response.json() + + assert response.status_code == SUCCESS_200_STATUS_CODE + + # Validate the json against the json schema + errorMsg = validate_list_metric_profiles_json(metric_profile_json, list_metric_profiles_schema) + assert errorMsg == "" + response = delete_metric_profile(input_json_file) print("delete metric profile = ", response.status_code) diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py b/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py new file mode 100644 index 000000000..a971a644b --- /dev/null +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py @@ -0,0 +1,62 @@ +""" +Copyright (c) 2024, 2024 Red Hat, IBM Corporation and others. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import pytest +import json +import sys + +sys.path.append("../../") + +from helpers.fixtures import * +from helpers.kruize import * +from helpers.utils import * + +@pytest.mark.sanity +def test_list_metric_profiles_with_name(cluster_type): + """ + Test Description: This test validates the response status code of listMetricProfiles API by validating the output + JSON response + """ + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + form_kruize_url(cluster_type) + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + # Create metric profile using the specified json + response = create_metric_profile(input_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + + json_file = open(input_json_file, "r") + input_json = json.loads(json_file.read()) + metric_profile_name = input_json['metadata']['name'] + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + response = list_metric_profiles(metric_profile_name) + list_metric_profiles_json = response.json() + + # Validate the json against the json schema + errorMsg = validate_import_metadata_json(import_metadata_json, import_metadata_json_schema) + assert errorMsg == "" + + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + From 5e6b3a386fb1f24b6bd25d5e07cd3eafbb364b80 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 25 Jul 2024 15:38:01 +0530 Subject: [PATCH 18/77] Update JSON schema and add validation of metric profile --- .../helpers/list_metric_profiles_schema.py | 8 +- .../helpers/list_metric_profiles_validate.py | 121 ++++++++++++++++++ ...tric_profiles_without_parameters_schema.py | 2 +- .../rest_apis/test_create_metric_profile.py | 9 ++ 4 files changed, 135 insertions(+), 5 deletions(-) create mode 100644 tests/scripts/helpers/list_metric_profiles_validate.py diff --git a/tests/scripts/helpers/list_metric_profiles_schema.py b/tests/scripts/helpers/list_metric_profiles_schema.py index f6e7de63b..827a1347a 100644 --- a/tests/scripts/helpers/list_metric_profiles_schema.py +++ b/tests/scripts/helpers/list_metric_profiles_schema.py @@ -60,7 +60,7 @@ "type": "string" }, "aggregation_functions": { - "type": "array", + "type": "object", "items": { "type": "object", "patternProperties": { @@ -84,9 +84,9 @@ }, "required": ["name", "datasource", "value_type", "kubernetes_object", "aggregation_functions"] } - } - }, - "required": ["sloClass", "objective_function", "direction", "function_variables"] + }, + "required": ["sloClass", "objective_function", "direction", "function_variables"] + } } }, "required": ["apiVersion", "kind", "metadata", "profile_version", "k8s_type", "slo"] diff --git a/tests/scripts/helpers/list_metric_profiles_validate.py b/tests/scripts/helpers/list_metric_profiles_validate.py new file mode 100644 index 000000000..14fe0cdae --- /dev/null +++ b/tests/scripts/helpers/list_metric_profiles_validate.py @@ -0,0 +1,121 @@ +""" +Copyright (c) 2024, 2024 Red Hat, IBM Corporation and others. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import json +import jsonschema +from jsonschema import FormatChecker +from jsonschema.exceptions import ValidationError +from helpers.list_metric_profiles_schema import list_metric_profiles_schema + + +SLO_CLASSES_SUPPORTED = ("throughput", "response_time", "resource_usage") +SLO_CLASSES_NOT_SUPPORTED = "SLO class not supported!" + +DIRECTIONS_SUPPORTED = ("minimize", "maximize") +DIRECTIONS_NOT_SUPPORTED = "Directions not supported!" + +VALUE_TYPES_SUPPORTED = ("double", "int", "string", "categorical") +VALUE_TYPE_NOT_SUPPORTED = "Value type not supported!" + +KUBERNETES_OBJECTS_TYPE_SUPPORTED = ("deployment", "pod", "container") +KUBERNETES_OBJECTS_TYPE_NOT_SUPPORTED = "Kubernetes objects type not supported!" + +FUNCTION_TYPES_SUPPORTED = ("sum", "avg", "min", "max") +FUNCTION_TYPE_NOT_SUPPORTED = "Aggregation function type not supported!" + +JSON_NULL_VALUES = ("is not of type 'string'", "is not of type 'integer'", "is not of type 'number'") +VALUE_MISSING = " cannot be empty or null!" + + +def validate_list_metric_profiles_json(list_metric_profiles_json, json_schema): + errorMsg = "" + try: + # create a validator with the format checker + print("Validating json against the json schema...") + validator = jsonschema.Draft7Validator(json_schema, format_checker=FormatChecker()) + + # validate the JSON data against the schema + errors = "" + errors = list(validator.iter_errors(list_metric_profiles_json)) + print("Validating json against the json schema...done") + errorMsg = validate_list_metric_profiles_json_values(list_metric_profiles_json) + + if errors: + custom_err = ValidationError(errorMsg) + errors.append(custom_err) + return errors + else: + return errorMsg + except ValidationError as err: + print("Received a VaidationError") + + # Check if the exception is due to empty or null required parameters and prepare the response accordingly + if any(word in err.message for word in JSON_NULL_VALUES): + errorMsg = "Parameters" + VALUE_MISSING + return errorMsg + # Modify the error response in case of additional properties error + elif str(err.message).__contains__('('): + errorMsg = str(err.message).split('(') + return errorMsg[0] + else: + return err.message + +def validate_list_metric_profiles_json_values(metric_profile): + validationErrorMsg = "" + slo = "slo" + func_var = "function_variables" + aggr_func = "aggregation_functions" + + for key in metric_profile[0].keys(): + + # Check if any of the key is empty or null + if not (str(metric_profile[0][key]) and str(metric_profile[0][key]).strip()): + validationErrorMsg = ",".join([validationErrorMsg, "Parameters" + VALUE_MISSING]) + + if slo == key: + for subkey in metric_profile[0][key].keys(): + if not (str(metric_profile[0][key][subkey]) and str(metric_profile[0][key][subkey]).strip()): + print(f"FAILED - {str(metric_profile[0][key][subkey])} is empty or null") + validationErrorMsg = ",".join([validationErrorMsg, "Parameters" + VALUE_MISSING]) + elif str(subkey) == "sloClass" and (str(metric_profile[0][key][subkey]) not in SLO_CLASSES_SUPPORTED): + validationErrorMsg = ",".join([validationErrorMsg, SLO_CLASSES_NOT_SUPPORTED]) + elif str(subkey) == "direction" and (str(metric_profile[0][key][subkey]) not in DIRECTIONS_SUPPORTED): + validationErrorMsg = ",".join([validationErrorMsg, DIRECTIONS_NOT_SUPPORTED]) + + if func_var == subkey: + for func_var_object in metric_profile[0][key][subkey]: + for field in func_var_object.keys(): + # Check if any of the key is empty or null + if not (str(func_var_object.get(field)) and str(func_var_object.get(field)).strip()): + print(f"FAILED - {str(func_var_object.get(field))} is empty or null") + validationErrorMsg = ",".join([validationErrorMsg, "Parameters" + VALUE_MISSING]) + elif str(field) == "value_type" and str(func_var_object.get(field)) not in VALUE_TYPES_SUPPORTED: + validationErrorMsg = ",".join([validationErrorMsg, VALUE_TYPE_NOT_SUPPORTED]) + elif str(field) == "kubernetes_object" and str(func_var_object.get(field)) not in KUBERNETES_OBJECTS_TYPE_SUPPORTED: + validationErrorMsg = ",".join([validationErrorMsg, KUBERNETES_OBJECTS_TYPE_NOT_SUPPORTED]) + + if aggr_func == field: + aggr_func_obj = func_var_object.get("aggregation_functions", {}) + for aggr_func_object, aggr_func_value in aggr_func_obj.items(): + for query in aggr_func_value.keys(): + # Check if any of the key is empty or null + if not (str(aggr_func_value.get(query)) and str(aggr_func_value.get(query)).strip()): + print(f"FAILED - {str(aggr_func_value.get(query))} is empty or null") + validationErrorMsg = ",".join([validationErrorMsg, "Parameters" + VALUE_MISSING]) + elif str(query) == "function" and str(aggr_func_value.get(query)) not in FUNCTION_TYPES_SUPPORTED: + validationErrorMsg = ",".join([validationErrorMsg, FUNCTION_TYPE_NOT_SUPPORTED]) + + return validationErrorMsg.lstrip(',') diff --git a/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py b/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py index a673c2bbd..b89bf6ed4 100644 --- a/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py +++ b/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py @@ -1,4 +1,4 @@ -list_metric_profiles_schema = { +list_metric_profiles_without_parameters_schema = { "type": "array", "items": { "type": "object", diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py index 7e9c56157..44b4aa5d2 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py @@ -156,6 +156,15 @@ def test_create_multiple_metric_profiles(cluster_type): assert data['status'] == SUCCESS_STATUS assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + response = list_metric_profiles(name=metric_profile_name) + metric_profile_json = response.json() + + assert response.status_code == SUCCESS_200_STATUS_CODE + + # Validate the json against the json schema + errorMsg = validate_list_metric_profiles_json(metric_profile_json, list_metric_profiles_schema) + assert errorMsg == "" + metric_profiles.append(copy.deepcopy(json_data)) response = delete_metric_profile(temp_json_file) From 347dc0949294d2e986d16604a1aa545085f99dd1 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 25 Jul 2024 16:17:27 +0530 Subject: [PATCH 19/77] Implement test cases for /listMetricProfiles API --- tests/scripts/helpers/utils.py | 3 + .../rest_apis/test_list_metric_profiles.py | 195 +++++++++++++++++- 2 files changed, 196 insertions(+), 2 deletions(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 49c4aefec..ad515376a 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -60,6 +60,9 @@ IMPORT_METADATA_DATASOURCE_CONNECTION_FAILURE_MSG = "Metadata cannot be imported, datasource connection refused or timed out" CREATE_METRIC_PROFILE_SUCCESS_MSG = "Metric Profile : %s created successfully. View Metric Profiles at /listMetricProfiles" METRIC_PROFILE_EXISTS_MSG = "Validation failed: Metric Profile already exists: %s" +METRIC_PROFILE_NOT_FOUND_MSG = "No metric profiles found!" +INVALID_LIST_METRIC_PROFILE_INPUT_QUERY = "The query param(s) - [%s] is/are invalid" +LIST_METRIC_PROFILES_INVALID_NAME = "Given metric profile name - %s is not valid" # Kruize Recommendations Notification codes NOTIFICATION_CODE_FOR_RECOMMENDATIONS_AVAILABLE = "111000" diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py b/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py index a971a644b..b0a597eb9 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py @@ -22,12 +22,14 @@ from helpers.fixtures import * from helpers.kruize import * from helpers.utils import * +from helpers.list_metric_profiles_validate import * +from helpers.list_metric_profiles_without_parameters_schema import * @pytest.mark.sanity def test_list_metric_profiles_with_name(cluster_type): """ Test Description: This test validates the response status code of listMetricProfiles API by validating the output - JSON response + JSON response by passing metric profile 'name' query parameter """ input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" form_kruize_url(cluster_type) @@ -53,7 +55,196 @@ def test_list_metric_profiles_with_name(cluster_type): list_metric_profiles_json = response.json() # Validate the json against the json schema - errorMsg = validate_import_metadata_json(import_metadata_json, import_metadata_json_schema) + errorMsg = validate_list_metric_profiles_json(list_metric_profiles_json, list_metric_profiles_schema) + assert errorMsg == "" + + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + +@pytest.mark.sanity +def test_list_metric_profiles_without_parameters(cluster_type): + """ + Test Description: This test validates the response status code of listMetricProfiles API by validating the output + JSON response without any parameters - expected output is listing all the metric profile names + """ + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + form_kruize_url(cluster_type) + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + # Create metric profile using the specified json + response = create_metric_profile(input_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + + json_file = open(input_json_file, "r") + input_json = json.loads(json_file.read()) + metric_profile_name = input_json['metadata']['name'] + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + response = list_metric_profiles() + list_metric_profiles_json = response.json() + + # Validate the json against the json schema + errorMsg = validate_list_metric_profiles_json(list_metric_profiles_json, list_metric_profiles_without_parameters_schema) + assert errorMsg == "" + + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + +@pytest.mark.negative +def test_list_metric_profiles_without_creating_profile(cluster_type): + """ + Test Description: This test validates the response status code of listMetricProfiles API by validating the output + JSON response without creating metric profile - expected output is an error message + """ + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + form_kruize_url(cluster_type) + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + + json_file = open(input_json_file, "r") + input_json = json.loads(json_file.read()) + metric_profile_name = input_json['metadata']['name'] + + response = list_metric_profiles(metric_profile_name) + data = response.json() + + assert response.status_code == ERROR_STATUS_CODE + assert data['message'] == METRIC_PROFILE_NOT_FOUND_MSG + + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + +@pytest.mark.negative +@pytest.mark.parametrize("test_name, expected_status_code, name", + [ + ("blank_name", 400, ""), + ("null_name", 400, "null"), + ("invalid_name", 400, "xyz") + ] + ) +def test_list_metric_profiles_invalid_name(test_name, expected_status_code, name, cluster_type): + """ + Test Description: This test validates the response status code of listMetricProfiles API by validating the output + JSON response by passing invalid query parameter 'name' - expected output is an error message + """ + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + form_kruize_url(cluster_type) + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + # Create metric profile using the specified json + response = create_metric_profile(input_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + + json_file = open(input_json_file, "r") + input_json = json.loads(json_file.read()) + metric_profile_name = input_json['metadata']['name'] + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + response = list_metric_profiles(name=name) + data = response.json() + + assert response.status_code == ERROR_STATUS_CODE + assert data['message'] == LIST_METRIC_PROFILES_INVALID_NAME % name + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + +@pytest.mark.sanity +@pytest.mark.parametrize("verbose", ["true", "false"]) +def test_list_metric_profiles_with_verbose(verbose, cluster_type): + """ + Test Description: This test validates the response status code of listMetricProfiles API by validating the output + JSON response by passing 'verbose' query parameter - expected output is list of all the metric profiles created + including all the metric profile fields when verbose=true and list of only the profile names when verbose=false + """ + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + form_kruize_url(cluster_type) + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + # Create metric profile using the specified json + response = create_metric_profile(input_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + + json_file = open(input_json_file, "r") + input_json = json.loads(json_file.read()) + metric_profile_name = input_json['metadata']['name'] + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + response = list_metric_profiles(verbose=verbose) + list_metric_profiles_json = response.json() + + # Validate the json against the json schema + errorMsg = validate_list_metric_profiles_json(list_metric_profiles_json, list_metric_profiles_schema) + assert errorMsg == "" + + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + +@pytest.mark.sanity +@pytest.mark.parametrize("verbose", ["false", "true"]) +def test_list_metric_profiles_name_and_verbose(verbose, cluster_type): + """ + Test Description: This test validates the response status code of listMetricProfiles API by validating the output + JSON response by passing both 'name' and 'verbose' query parameters - expected output is metric profile of the specified + name as verbose is set to true when name parameter is passed + """ + input_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + form_kruize_url(cluster_type) + + response = delete_metric_profile(input_json_file) + print("delete metric profile = ", response.status_code) + + # Create metric profile using the specified json + response = create_metric_profile(input_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + + json_file = open(input_json_file, "r") + input_json = json.loads(json_file.read()) + metric_profile_name = input_json['metadata']['name'] + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + response = list_metric_profiles(name= metric_profile_name, verbose=verbose) + list_metric_profiles_json = response.json() + + # Validate the json against the json schema + errorMsg = validate_list_metric_profiles_json(list_metric_profiles_json, list_metric_profiles_schema) assert errorMsg == "" From e85292ad0e5f651ebbd7e786ce87216b05c035a2 Mon Sep 17 00:00:00 2001 From: Shreya Date: Fri, 2 Aug 2024 10:51:55 +0530 Subject: [PATCH 20/77] Update metric profile queries --- .../helpers/list_metric_profiles_validate.py | 2 +- ...optimization_openshift_metric_profile.json | 270 +++++++++++++++--- 2 files changed, 235 insertions(+), 37 deletions(-) diff --git a/tests/scripts/helpers/list_metric_profiles_validate.py b/tests/scripts/helpers/list_metric_profiles_validate.py index 14fe0cdae..3685ef0e3 100644 --- a/tests/scripts/helpers/list_metric_profiles_validate.py +++ b/tests/scripts/helpers/list_metric_profiles_validate.py @@ -30,7 +30,7 @@ VALUE_TYPES_SUPPORTED = ("double", "int", "string", "categorical") VALUE_TYPE_NOT_SUPPORTED = "Value type not supported!" -KUBERNETES_OBJECTS_TYPE_SUPPORTED = ("deployment", "pod", "container") +KUBERNETES_OBJECTS_TYPE_SUPPORTED = ("deployment", "pod", "container", "namespace") KUBERNETES_OBJECTS_TYPE_NOT_SUPPORTED = "Kubernetes objects type not supported!" FUNCTION_TYPES_SUPPORTED = ("sum", "avg", "min", "max") diff --git a/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json b/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json index 973f65b7f..fda38b4f3 100644 --- a/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json +++ b/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json @@ -21,11 +21,11 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg(kube_pod_container_resource_requests{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE\", resource=\"cpu\", unit=\"core\"})" + "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_requests{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"cpu\", unit=\"core\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" }, { "function": "sum", - "query": "sum(kube_pod_container_resource_requests{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE\", resource=\"cpu\", unit=\"core\"})" + "query": "sum by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_requests{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"cpu\", unit=\"core\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" } ] }, @@ -37,11 +37,11 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg(kube_pod_container_resource_limits{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE\", resource=\"cpu\", unit=\"core\"})" + "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_limits{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"cpu\", unit=\"core\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" }, { "function": "sum", - "query": "sum(kube_pod_container_resource_limits{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\", resource=\"cpu\", unit=\"core\"})" + "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_limits{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"cpu\", unit=\"core\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" } ] }, @@ -53,43 +53,43 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))", - "versions": "<=4.8" + "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time(((irate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[5m])) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\", workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "version": "<=4.8" }, { "function": "avg", - "query": "avg(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))", - "versions": ">4.9" + "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time(((node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "version": ">4.9" }, { "function": "min", - "query": "min(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", - "versions": "<=4.8" + "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time(((irate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[5m])) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\", workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "version": "<=4.8" }, { "function": "min", - "query": "min(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", - "versions": ">4.9" + "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time(((node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "version": ">4.9" }, { "function": "max", - "query": "max(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", - "versions": "<=4.8" + "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time(((irate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[5m])) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\", workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "version": "<=4.8" }, { "function": "max", - "query": "max(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", - "versions": ">4.9" + "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time(((node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "version": ">4.9" }, { "function": "sum", - "query": "sum(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", - "versions": "<=4.8" + "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time(((irate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[5m])) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\", workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "version": "<=4.8" }, { "function": "sum", - "query": "sum(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=\"$CONTAINER_NAME$\"}[15m]))", - "versions": ">4.9" + "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time(((node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "version": ">4.9" } ] }, @@ -101,15 +101,20 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg(rate(container_cpu_cfs_throttled_seconds_total{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))" + "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((rate(container_cpu_cfs_throttled_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[15m]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" }, { "function": "max", - "query": "max(rate(container_cpu_cfs_throttled_seconds_total{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))" + "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time((rate(container_cpu_cfs_throttled_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[15m]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + + }, + { + "function": "min", + "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time((rate(container_cpu_cfs_throttled_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[15m]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" }, { "function": "sum", - "query": "sum(rate(container_cpu_cfs_throttled_seconds_total{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=\"$NAMESPACE$\", container=”$CONTAINER_NAME$”}[15m]))" + "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((rate(container_cpu_cfs_throttled_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[15m]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" } ] }, @@ -121,11 +126,13 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg(kube_pod_container_resource_requests{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource=\"memory\", unit=\"byte\"})" + "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_requests{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"memory\", unit=\"byte\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" + }, { "function": "sum", - "query": "sum(kube_pod_container_resource_requests{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource=\"memory\", unit=\"byte\"})" + "query": "sum by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_requests{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"memory\", unit=\"byte\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" + } ] }, @@ -137,11 +144,12 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg(kube_pod_container_resource_limits{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE\", resource=\"memory\", unit=\"byte\"})" + "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_limits{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"memory\", unit=\"byte\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" }, { "function": "sum", - "query": "sum(kube_pod_container_resource_limits{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource=\"memory\", unit=\"byte\"})" + "query": "sum by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_limits{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"memory\", unit=\"byte\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" + } ] }, @@ -153,19 +161,23 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg(avg_over_time(container_memory_working_set_bytes{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))" + "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((container_memory_working_set_bytes{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + }, { "function": "min", - "query": "min(min_over_time(container_memory_working_set_bytes{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time((container_memory_working_set_bytes{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + }, { "function": "max", - "query": "max(max_over_time(container_memory_working_set_bytes{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time((container_memory_working_set_bytes{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + }, { "function": "sum", - "query": "sum(avg_over_time(container_memory_working_set_bytes{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((container_memory_working_set_bytes{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + } ] }, @@ -177,22 +189,208 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg(avg_over_time(container_memory_rss{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))" + "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((container_memory_rss{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + }, { "function": "min", - "query": "min(min_over_time(container_memory_rss{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time((container_memory_rss{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + + }, + { + "function": "max", + "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time((container_memory_rss{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + + }, + { + "function": "sum", + "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((container_memory_rss{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + + } + ] + }, + { + "name": "maxDate", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "max", + "query": "max by(namespace,container,workload,workload_type,owner_kind) (last_over_time((timestamp(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!='',workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15d])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15d])) )" + } + ] + }, + { + "name": "namespaceCpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"requests.cpu\", type=\"hard\"})" + + } + ] + }, + { + "name": "namespaceCpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"limits.cpu\", type=\"hard\"})" + + } + ] + }, + { + "name": "namespaceMemoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"requests.memory\", type=\"hard\"})" + + } + ] + }, + { + "name": "namespaceMemoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"limits.memory\", type=\"hard\"})" + + } + ] + }, + { + "name": "namespaceCpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + }, { "function": "max", - "query": "max(max_over_time(container_memory_rss{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=\"$CONTAINER_NAME$\"}[15m]))" + "query": "max_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + }, + { + "function": "min", + "query": "min_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + + } + ] + }, + { + "name": "namespaceCpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])" + + }, + { + "function": "max", + "query": "max_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])" + + }, + { + "function": "min", + "query": "min_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])" + + } + ] + }, + { + "name": "namespaceMemoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + + }, + { + "function": "max", + "query": "max_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + + }, + { + "function": "min", + "query": "min_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + + } + ] + }, + { + "name": "namespaceMemoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + + }, + { + "function": "max", + "query": "max_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + + }, + { + "function": "min", + "query": "min_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])" + + } + ] + }, + { + "name": "namespaceTotalPods", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum(count(kube_pod_status_phase{namespace=\"$NAMESPACE$\"}))" + + } + ] + }, + { + "name": "namespaceRunningPods", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ { "function": "sum", - "query": "sum(avg_over_time(container_memory_rss{pod=~\"$DEPLOYMENT_NAME$-[^-]*-[^-]*$\", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))" + "query": "sum(count(kube_pod_status_phase{namespace=\"$NAMESPACE$\", phase=\"Running\"}))" + } ] } ] } -} \ No newline at end of file +} From b3fbf0bb7e496b0d3d2b0d38691102502bd5a70b Mon Sep 17 00:00:00 2001 From: Shreya Date: Fri, 2 Aug 2024 11:32:47 +0530 Subject: [PATCH 21/77] Validate multiple profiles --- .../rest_apis/test_create_metric_profile.py | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py index 44b4aa5d2..5428b3974 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py @@ -24,6 +24,7 @@ from helpers.kruize import * from helpers.utils import * from helpers.list_metric_profiles_validate import * +from helpers.list_metric_profiles_without_parameters_schema import * mandatory_fields = [ ("apiVersion", ERROR_500_STATUS_CODE, ERROR_STATUS), @@ -133,8 +134,8 @@ def test_create_multiple_metric_profiles(cluster_type): input_metric_profile_name = input_json_data['metadata']['name'] # Create metric profile using the specified json - num_exps = 100 - for i in range(num_exps): + num_metric_profiles = 100 + for i in range(num_metric_profiles): json_data = copy.deepcopy(input_json_data) # Modify the name for each profile metric_profile_name = f"{input_metric_profile_name}_{i}" @@ -170,6 +171,17 @@ def test_create_multiple_metric_profiles(cluster_type): response = delete_metric_profile(temp_json_file) print("delete metric profile = ", response.status_code) + # list all the metric profile names created + response = list_metric_profiles() + list_metric_profiles_json = response.json() + + assert len(list_metric_profiles_json) == num_metric_profiles, f"Expected {num_metric_profiles} metric profiles in response, but got {len(list_metric_profiles_json)}" + assert response.status_code == SUCCESS_200_STATUS_CODE + + # Validate the json against the json schema + errorMsg = validate_list_metric_profiles_json(list_metric_profiles_json, list_metric_profiles_without_parameters_schema) + assert errorMsg == "" + # Write the profiles to the output file with open(output_json_file, 'w') as file: json.dump(metric_profiles, file, indent=4) @@ -208,7 +220,7 @@ def test_create_metric_profiles_mandatory_fields(cluster_type, field, expected_s with open(json_file, 'w') as file: file.write(data) - response = delete_metric_profile(json_file) + response = delete_metric_profile(input_json_file) print("delete metric profile = ", response.status_code) response = create_metric_profile(json_file) @@ -219,5 +231,5 @@ def test_create_metric_profiles_mandatory_fields(cluster_type, field, expected_s f"Mandatory field check failed for {field} actual - {response.status_code} expected - {expected_status_code}" assert data['status'] == expected_status - response = delete_metric_profile(json_file) + response = delete_metric_profile(input_json_file) print("delete metric profile = ", response.status_code) From 0fe2e477676846b63a9fc412bb9d67bd5c7982d5 Mon Sep 17 00:00:00 2001 From: Shreya Date: Fri, 2 Aug 2024 12:51:46 +0530 Subject: [PATCH 22/77] Update readme --- .../Local_monitoring_tests.md | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md b/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md index 302418779..4923d612f 100644 --- a/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md +++ b/tests/scripts/local_monitoring_tests/Local_monitoring_tests.md @@ -48,9 +48,30 @@ Here are the test scenarios: - List dsmetadata with datasource and namespace but without cluster_name - List the dsmetadata after deleting imported metadata +### **Create Metric Profile API tests** + +Here are the test scenarios: + +- Create metric profile passing a valid input JSON payload with all the metric queries +- Post the same metric profile again - creating it twice and validate the error as metric profile name is a unique field +- Create multiple valid metric profiles using different jsons +- Create Metric profile missing mandatory fields and validate error messages when the mandatory fields are missing + + +### **List Metric Profile API tests** + +Here are the test scenarios: + +- List metric profiles without specifying any query parameters +- List metric profiles specifying profile name query parameter +- List metric profiles specifying verbose query parameter +- List metric profiles specifying profile name and verbose query parameters +- Test with invalid values such as blank, null or an invalid value for name query parameter in listMetricProfiles API +- List metric profiles without creating metric profile + The above tests are developed using pytest framework and the tests are run using shell script wrapper that does the following: - Deploys kruize in non-CRD mode using the [deploy script](https://github.com/kruize/autotune/blob/master/deploy.sh) from the autotune repo -- Creates a resource optimization performance profile using the [createPerformanceProfile API](/design/PerformanceProfileAPI.md) +- Creates a resource optimization metric profile using the [createMetricProfile API](/design/MetricProfileAPI.md) - Runs the above tests using pytest ## Prerequisites for running the tests: From 076800c2ac9aae0d696a67d6166640a69bd001b8 Mon Sep 17 00:00:00 2001 From: Shreya Date: Fri, 2 Aug 2024 13:16:31 +0530 Subject: [PATCH 23/77] Add copright --- .../helpers/list_metric_profiles_schema.py | 16 ++++++++++++++++ ..._metric_profiles_without_parameters_schema.py | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/tests/scripts/helpers/list_metric_profiles_schema.py b/tests/scripts/helpers/list_metric_profiles_schema.py index 827a1347a..7cdd9c00b 100644 --- a/tests/scripts/helpers/list_metric_profiles_schema.py +++ b/tests/scripts/helpers/list_metric_profiles_schema.py @@ -1,3 +1,19 @@ +""" +Copyright (c) 2024, 2024 Red Hat, IBM Corporation and others. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + list_metric_profiles_schema = { "type": "array", "items": { diff --git a/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py b/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py index b89bf6ed4..1de70a140 100644 --- a/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py +++ b/tests/scripts/helpers/list_metric_profiles_without_parameters_schema.py @@ -1,3 +1,19 @@ +""" +Copyright (c) 2024, 2024 Red Hat, IBM Corporation and others. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + list_metric_profiles_without_parameters_schema = { "type": "array", "items": { From 24cf345bb71fbc86d15677082e390d569a8be5e8 Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 5 Aug 2024 12:08:45 +0530 Subject: [PATCH 24/77] Refactor delete metric profile API in the tests --- tests/scripts/helpers/kruize.py | 15 +- .../rest_apis/test_create_metric_profile.py | 13 +- .../rest_apis/test_list_metric_profiles.py | 2 +- tests/setup.log | 134 ------------------ 4 files changed, 19 insertions(+), 145 deletions(-) delete mode 100755 tests/setup.log diff --git a/tests/scripts/helpers/kruize.py b/tests/scripts/helpers/kruize.py index a9c836ace..4b633f6a1 100644 --- a/tests/scripts/helpers/kruize.py +++ b/tests/scripts/helpers/kruize.py @@ -388,22 +388,21 @@ def delete_metric_profile(input_json_file, invalid_header=False): input_json = json.loads(json_file.read()) print("\nDeleting the metric profile...") - #TODO change the API endpoint based on the implementation - url = URL + "/createMetricProfile" - print("URL = ", url) + url = URL + "/deleteMetricProfile" metric_profile_name = input_json['metadata']['name'] + query_string = f"name={metric_profile_name}" - delete_json = [{ - "name": metric_profile_name - }] + if query_string: + url += "?" + query_string + print("URL = ", url) headers = {'content-type': 'application/xml'} if invalid_header: print("Invalid header") - response = requests.delete(url, json=delete_json, headers=headers) + response = requests.delete(url, headers=headers) else: - response = requests.delete(url, json=delete_json) + response = requests.delete(url) print(response) print("Response status code = ", response.status_code) diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py index 5428b3974..e09cb9223 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py @@ -168,8 +168,8 @@ def test_create_multiple_metric_profiles(cluster_type): metric_profiles.append(copy.deepcopy(json_data)) - response = delete_metric_profile(temp_json_file) - print("delete metric profile = ", response.status_code) + # response = delete_metric_profile(temp_json_file) + # print("delete metric profile = ", response.status_code) # list all the metric profile names created response = list_metric_profiles() @@ -186,6 +186,15 @@ def test_create_multiple_metric_profiles(cluster_type): with open(output_json_file, 'w') as file: json.dump(metric_profiles, file, indent=4) + for i in range(num_metric_profiles): + metric_profile = metric_profiles[i] + + with open(temp_json_file, 'w') as file: + json.dump(metric_profile, file, indent=4) + + response = delete_metric_profile(temp_json_file) + print("delete metric profile = ", response.status_code) + @pytest.mark.extended @pytest.mark.parametrize("field, expected_status_code, expected_status", mandatory_fields) diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py b/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py index b0a597eb9..f57f505ba 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_list_metric_profiles.py @@ -122,7 +122,7 @@ def test_list_metric_profiles_without_creating_profile(cluster_type): data = response.json() assert response.status_code == ERROR_STATUS_CODE - assert data['message'] == METRIC_PROFILE_NOT_FOUND_MSG + assert data['message'] == LIST_METRIC_PROFILES_INVALID_NAME % metric_profile_name response = delete_metric_profile(input_json_file) diff --git a/tests/setup.log b/tests/setup.log deleted file mode 100755 index ded3bb8cc..000000000 --- a/tests/setup.log +++ /dev/null @@ -1,134 +0,0 @@ -- Proxy which can point the dynamic kruize service (ports can be changing) -- UI should communicate with the proxy (fixed ip and port) -- UI should read env and figure out the fixed proxy endpoint and port - -- API forwarder fixed ip and port - -API server - http for UI and grpc for internal endpoint - -Every request from UI or curl will go to API server, this will figure out kruize url's and port and then talk via GRPC and respond to curl or UI via http - -[ - { - "version": "v2.0", - "experiment_name": "quarkus-resteasy-autotune-min-http-response-time-db", - "interval_start_time": "2022-01-23T18:25:43.511Z", - "interval_end_time": "2022-01-23T18:40:43.602Z", - "kubernetes_objects": [ - { - "type": "deployment", - "name": "tfb-qrh-deployment", - "namespace": "default", - "containers": [ - { - "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", - "container_name": "tfb-server-0", - "metrics": [ - { - "name": "cpuRequest", - "results": { - "value": 1.1, - "format": "cores", - "aggregation_info": { - "sum": 4.4, - "avg": 1.1, - "format": "cores" - } - } - }, - { - "name": "cpuLimit", - "results": { - "value": 0.5, - "format": "cores", - "aggregation_info": { - "sum": 2.0, - "avg": 0.5, - "format": "cores" - } - } - }, - { - "name": "cpuUsage", - "results": { - "value": 0.12, - "format": "cores", - "aggregation_info": { - "min": 0.14, - "max": 0.84, - "sum": 0.84, - "avg": 0.12, - "format": "cores" - } - } - }, - { - "name": "cpuThrottle", - "results": { - "value": 0.045, - "format": "cores", - "aggregation_info": { - "sum": 0.19, - "max": 0.09, - "avg": 0.045, - "format": "cores" - } - } - }, - { - "name": "memoryRequest", - "results": { - "value": 50.12, - "format": "MiB", - "aggregation_info": { - "sum": 250.85, - "avg": 50.21, - "format": "MiB" - } - } - }, - { - "name": "memoryLimit", - "results": { - "value": 100, - "format": "MiB", - "aggregation_info": { - "sum": 500, - "avg": 100, - "format": "MiB" - } - } - }, - { - "name": "memoryUsage", - "results": { - "value": 40.1, - "format": "MiB", - "aggregation_info": { - "min": 50.6, - "max": 198.50, - "sum": 198.50, - "avg": 40.1, - "format": "MiB" - } - } - }, - { - "name": "memoryRSS", - "results": { - "aggregation_info": { - "min": 50.6, - "max": 123.6, - "sum": 123.6, - "avg": 31.91, - "format": "MiB" - } - } - } - ] - } - ] - } - ] - } -] \ No newline at end of file From 7578eea59ca87c21af960e2b5bc445c6eae5a4c0 Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 5 Aug 2024 12:14:09 +0530 Subject: [PATCH 25/77] Restore deleted tests/setup.log --- tests/setup.log | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 tests/setup.log diff --git a/tests/setup.log b/tests/setup.log new file mode 100644 index 000000000..5d3bc9ee3 --- /dev/null +++ b/tests/setup.log @@ -0,0 +1,134 @@ +- Proxy which can point the dynamic kruize service (ports can be changing) +- UI should communicate with the proxy (fixed ip and port) +- UI should read env and figure out the fixed proxy endpoint and port + +- API forwarder fixed ip and port + +API server - http for UI and grpc for internal endpoint + +Every request from UI or curl will go to API server, this will figure out kruize url's and port and then talk via GRPC and respond to curl or UI via http + +[ + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-autotune-min-http-response-time-db", + "interval_start_time": "2022-01-23T18:25:43.511Z", + "interval_end_time": "2022-01-23T18:40:43.602Z", + "kubernetes_objects": [ + { + "type": "deployment", + "name": "tfb-qrh-deployment", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "value": 1.1, + "format": "cores", + "aggregation_info": { + "sum": 4.4, + "avg": 1.1, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "value": 0.5, + "format": "cores", + "aggregation_info": { + "sum": 2.0, + "avg": 0.5, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "value": 0.12, + "format": "cores", + "aggregation_info": { + "min": 0.14, + "max": 0.84, + "sum": 0.84, + "avg": 0.12, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "value": 0.045, + "format": "cores", + "aggregation_info": { + "sum": 0.19, + "max": 0.09, + "avg": 0.045, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "value": 50.12, + "format": "MiB", + "aggregation_info": { + "sum": 250.85, + "avg": 50.21, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "value": 100, + "format": "MiB", + "aggregation_info": { + "sum": 500, + "avg": 100, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "value": 40.1, + "format": "MiB", + "aggregation_info": { + "min": 50.6, + "max": 198.50, + "sum": 198.50, + "avg": 40.1, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 50.6, + "max": 123.6, + "sum": 123.6, + "avg": 31.91, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + } +] From 403bacce0bde3899f31f912700b5da6571c824a3 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 8 Aug 2024 20:14:15 +0530 Subject: [PATCH 26/77] Validate mandatory slo fields and compress logging --- tests/scripts/helpers/utils.py | 2 + .../rest_apis/test_create_metric_profile.py | 39 ++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index ad515376a..204d6f442 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -63,6 +63,8 @@ METRIC_PROFILE_NOT_FOUND_MSG = "No metric profiles found!" INVALID_LIST_METRIC_PROFILE_INPUT_QUERY = "The query param(s) - [%s] is/are invalid" LIST_METRIC_PROFILES_INVALID_NAME = "Given metric profile name - %s is not valid" +CREATE_METRIC_PROFILE_MISSING_MANDATORY_FIELD_MSG = "Validation failed: JSONObject[\"%s\"] not found." +CREATE_METRIC_PROFILE_MISSING_MANDATORY_PARAMETERS_MSG = "Validation failed: Missing mandatory parameters: [%s] " # Kruize Recommendations Notification codes NOTIFICATION_CODE_FOR_RECOMMENDATIONS_AVAILABLE = "111000" diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py index e09cb9223..d1b9a49c2 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py @@ -31,7 +31,17 @@ ("kind", ERROR_500_STATUS_CODE, ERROR_STATUS), ("metadata", ERROR_500_STATUS_CODE, ERROR_STATUS), ("name", ERROR_500_STATUS_CODE, ERROR_STATUS), - ("slo", ERROR_500_STATUS_CODE, ERROR_STATUS) + ("slo", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("direction", ERROR_STATUS_CODE, ERROR_STATUS), + ("objective_function", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("function_type", ERROR_STATUS_CODE, ERROR_STATUS), + ("function_variables", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("name", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("datasource", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("value_type", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("aggregation_functions", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("function", ERROR_500_STATUS_CODE, ERROR_STATUS), + ("query", ERROR_500_STATUS_CODE, ERROR_STATUS) ] @@ -157,7 +167,7 @@ def test_create_multiple_metric_profiles(cluster_type): assert data['status'] == SUCCESS_STATUS assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name - response = list_metric_profiles(name=metric_profile_name) + response = list_metric_profiles(name=metric_profile_name, logging=False) metric_profile_json = response.json() assert response.status_code == SUCCESS_200_STATUS_CODE @@ -221,6 +231,26 @@ def test_create_metric_profiles_mandatory_fields(cluster_type, field, expected_s json_data['metadata'].pop("name", None) elif field == "slo": json_data.pop("slo", None) + elif field == "direction": + json_data['slo'].pop("direction", None) + elif field == "objective_function": + json_data['slo'].pop("objective_function", None) + elif field == "function_type": + json_data['slo']['objective_function'].pop("function_type", None) + elif field == "function_variables": + json_data['slo'].pop("function_variables", None) + elif field == "name": + json_data['slo']['function_variables'].pop("name", None) + elif field == "datasource": + json_data['slo']['function_variables'][0].pop("datasource", None) + elif field == "value_type": + json_data['slo']['function_variables'][0].pop("value_type", None) + elif field == "aggregation_functions": + json_data['slo']['function_variables'][0].pop("aggregation_functions", None) + elif field == "function": + json_data['slo']['function_variables'][0]['aggregation_functions'][0].pop("function", None) + elif field == "query": + json_data['slo']['function_variables'][0]['aggregation_functions'][0].pop("query", None) print("\n*****************************************") print(json_data) @@ -240,5 +270,10 @@ def test_create_metric_profiles_mandatory_fields(cluster_type, field, expected_s f"Mandatory field check failed for {field} actual - {response.status_code} expected - {expected_status_code}" assert data['status'] == expected_status + if response.status_code == ERROR_500_STATUS_CODE: + assert data['message'] == MISSING_MANDATORY_FIELD_MSG % field + else: + assert data['message'] == MISSING_MANDATORY_PARAMETERS_MSG % field + response = delete_metric_profile(input_json_file) print("delete metric profile = ", response.status_code) From c78f4d99c77e129446bf7159fdb793f3fb9f743f Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 12 Aug 2024 11:14:44 +0530 Subject: [PATCH 27/77] Update test variables --- .../rest_apis/test_create_metric_profile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py index d1b9a49c2..bb497c52b 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_create_metric_profile.py @@ -271,9 +271,9 @@ def test_create_metric_profiles_mandatory_fields(cluster_type, field, expected_s assert data['status'] == expected_status if response.status_code == ERROR_500_STATUS_CODE: - assert data['message'] == MISSING_MANDATORY_FIELD_MSG % field + assert data['message'] == CREATE_METRIC_PROFILE_MISSING_MANDATORY_FIELD_MSG % field else: - assert data['message'] == MISSING_MANDATORY_PARAMETERS_MSG % field + assert data['message'] == CREATE_METRIC_PROFILE_MISSING_MANDATORY_PARAMETERS_MSG % field response = delete_metric_profile(input_json_file) print("delete metric profile = ", response.status_code) From 7bbb33ab785bd6f2ebc401d52d6e41ae431beb0f Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 11:31:10 +0530 Subject: [PATCH 28/77] Add metric profile database table --- migrations/kruize_local_ddl.sql | 1 + .../table/KruizeMetricProfileEntry.java | 107 ++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/main/java/com/autotune/database/table/KruizeMetricProfileEntry.java diff --git a/migrations/kruize_local_ddl.sql b/migrations/kruize_local_ddl.sql index bdfc0aaf4..087ad1bf4 100644 --- a/migrations/kruize_local_ddl.sql +++ b/migrations/kruize_local_ddl.sql @@ -1,3 +1,4 @@ create table IF NOT EXISTS kruize_datasources (version varchar(255), name varchar(255), provider varchar(255), serviceName varchar(255), namespace varchar(255), url varchar(255), primary key (name)); create table IF NOT EXISTS kruize_dsmetadata (id serial, version varchar(255), datasource_name varchar(255), cluster_name varchar(255), namespace varchar(255), workload_type varchar(255), workload_name varchar(255), container_name varchar(255), container_image_name varchar(255), primary key (id)); alter table kruize_experiments add column metadata_id bigint references kruize_dsmetadata(id), alter column datasource type varchar(255); +create table IF NOT EXISTS kruize_metric_profiles (api_version varchar(255), kind varchar(255), metadata jsonb, name varchar(255) not null, k8s_type varchar(255), profile_version float(53) not null, slo jsonb, primary key (name)); diff --git a/src/main/java/com/autotune/database/table/KruizeMetricProfileEntry.java b/src/main/java/com/autotune/database/table/KruizeMetricProfileEntry.java new file mode 100644 index 000000000..ef6dc2953 --- /dev/null +++ b/src/main/java/com/autotune/database/table/KruizeMetricProfileEntry.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2024 Red Hat, IBM Corporation and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.autotune.database.table; + +import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.*; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +/** + * This is a Java class named KruizeMetricProfileEntry annotated with JPA annotations. + * It represents a table named kruize_metric_profiles in a relational database. + *

+ * The class has the following fields: + *

+ * id: A unique identifier for each metric profile detail. + * apiVersion: A string representing version of the Kubernetes API to create this object + * kind: A string representing type of kubernetes object + * metadata: A JSON object containing the metadata of the CRD, including name field + * name: A string representing the name of the metric profile. + * profile_version: A string representing the version of the metric profile. + * k8s_type: A string representing kubernetes type. + * SLO: A string representing the slo class, direction, Objective function and function variables. + */ +@Entity +@Table(name = "kruize_metric_profiles") +public class KruizeMetricProfileEntry { + private String api_version; + private String kind; + @JdbcTypeCode(SqlTypes.JSON) + private JsonNode metadata; + @Id + private String name; + private double profile_version; + private String k8s_type; + @JdbcTypeCode(SqlTypes.JSON) + private JsonNode slo; + + public String getApi_version() { + return api_version; + } + + public void setApi_version(String api_version) { + this.api_version = api_version; + } + + public String getKind() { + return kind; + } + + public void setKind(String kind) { + this.kind = kind; + } + + public JsonNode getMetadata() { + return metadata; + } + + public void setMetadata(JsonNode metadata) { + this.metadata = metadata; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getProfile_version() { + return profile_version; + } + + public void setProfile_version(double profile_version) { + this.profile_version = profile_version; + } + + public String getK8s_type() { + return k8s_type; + } + + public void setK8s_type(String k8s_type) { + this.k8s_type = k8s_type; + } + + public JsonNode getSlo() { + return slo; + } + + public void setSlo(JsonNode slo) { + this.slo = slo; + } +} \ No newline at end of file From b3d1496ba04a812b5e928385d40e79b7f3effb5a Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 13:48:16 +0530 Subject: [PATCH 29/77] Add metric profile servlet with database methods --- .../java/com/autotune/analyzer/Analyzer.java | 2 + .../experiment/ExperimentValidation.java | 1 + .../PerformanceProfile.java | 49 ++- .../PerformanceProfileValidation.java | 403 +++++++++++++----- .../utils/PerformanceProfileUtil.java | 27 ++ .../analyzer/serviceObjects/Converters.java | 49 +++ .../services/MetricProfileService.java | 243 +++++++++++ .../analyzer/utils/AnalyzerConstants.java | 1 + .../utils/AnalyzerErrorConstants.java | 2 + .../autotune/database/dao/ExperimentDAO.java | 6 + .../database/dao/ExperimentDAOImpl.java | 71 +++ .../autotune/database/helper/DBConstants.java | 2 + .../autotune/database/helper/DBHelpers.java | 69 +++ .../database/init/KruizeHibernateUtil.java | 1 + .../database/service/ExperimentDBService.java | 27 ++ .../autotune/service/InitiateListener.java | 14 + .../com/autotune/utils/KruizeConstants.java | 7 + .../com/autotune/utils/ServerContext.java | 2 + 18 files changed, 869 insertions(+), 107 deletions(-) create mode 100644 src/main/java/com/autotune/analyzer/services/MetricProfileService.java diff --git a/src/main/java/com/autotune/analyzer/Analyzer.java b/src/main/java/com/autotune/analyzer/Analyzer.java index 675e7cb54..3a33cbc33 100644 --- a/src/main/java/com/autotune/analyzer/Analyzer.java +++ b/src/main/java/com/autotune/analyzer/Analyzer.java @@ -53,6 +53,8 @@ public static void addServlets(ServletContextHandler context) { context.addServlet(ListRecommendations.class, ServerContext.RECOMMEND_RESULTS); context.addServlet(PerformanceProfileService.class, ServerContext.CREATE_PERF_PROFILE); context.addServlet(PerformanceProfileService.class, ServerContext.LIST_PERF_PROFILES); + context.addServlet(MetricProfileService.class, ServerContext.CREATE_METRIC_PROFILE); + context.addServlet(MetricProfileService.class, ServerContext.LIST_METRIC_PROFILES); context.addServlet(ListDatasources.class, ServerContext.LIST_DATASOURCES); context.addServlet(DSMetadataService.class, ServerContext.DATASOURCE_METADATA); diff --git a/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java b/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java index a3ad10ea5..94850bda8 100644 --- a/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java +++ b/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java @@ -122,6 +122,7 @@ public void validate(List kruizeExptList) { errorMsg = AnalyzerErrorConstants.AutotuneObjectErrors.MISSING_SLO_DATA; validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); } else { + // TODO - set metric profile when local=true String perfProfileName = KruizeOperator.setDefaultPerformanceProfile(kruizeObject.getSloInfo(), mode, target_cluster); kruizeObject.setPerformanceProfile(perfProfileName); proceed = true; diff --git a/src/main/java/com/autotune/analyzer/performanceProfiles/PerformanceProfile.java b/src/main/java/com/autotune/analyzer/performanceProfiles/PerformanceProfile.java index 5f5705867..f5ab5634a 100644 --- a/src/main/java/com/autotune/analyzer/performanceProfiles/PerformanceProfile.java +++ b/src/main/java/com/autotune/analyzer/performanceProfiles/PerformanceProfile.java @@ -17,6 +17,7 @@ import com.autotune.analyzer.kruizeObject.SloInfo; import com.autotune.analyzer.recommendations.term.Terms; +import com.fasterxml.jackson.databind.JsonNode; import com.google.gson.annotations.SerializedName; import java.util.Map; @@ -25,9 +26,17 @@ * Container class for the PerformanceProfile kubernetes kind, which is used to define * a profile * + * This class provides a direct representation of MetricProfile CRD in JSON format, + * corresponding to the structure of PerformanceProfile YAML file. It includes mandatory fields + * for API version, kind, metadata and additional custom fields - profile_version, k8s_type and sloInfo */ public class PerformanceProfile { + private String apiVersion; + + private String kind; + + private JsonNode metadata; private String name; @@ -41,6 +50,30 @@ public class PerformanceProfile { private Map terms; + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + + public String getKind() { + return kind; + } + + public void setKind(String kind) { + this.kind = kind; + } + + public JsonNode getMetadata() { + return metadata; + } + + public void setMetadata(JsonNode metadata) { + this.metadata = metadata; + } + public void setName(String name) { this.name = name; } @@ -68,6 +101,17 @@ public PerformanceProfile(String name, double profile_version, String k8s_type, this.sloInfo = sloInfo; } + // Constructor for MetricProfile + public PerformanceProfile(String apiVersion, String kind, JsonNode metadata, + double profile_version, String k8s_type, SloInfo sloInfo) { + this.apiVersion = apiVersion; + this.kind = kind; + this.metadata = metadata; + this.profile_version = profile_version; + this.k8s_type = k8s_type; + this.sloInfo = sloInfo; + } + public String getName() { return name; } @@ -95,7 +139,10 @@ public void setTerms(Map terms) { @Override public String toString() { return "PerformanceProfile{" + - "name='" + name + '\'' + + "apiVersion='" + apiVersion + '\'' + + ", kind='" + kind + '\'' + + ", metadata=" + metadata + + " name='" + name + '\'' + ", profile_version=" + profile_version + ", k8s_type='" + k8s_type + '\'' + ", sloInfo=" + sloInfo + diff --git a/src/main/java/com/autotune/analyzer/performanceProfiles/PerformanceProfileValidation.java b/src/main/java/com/autotune/analyzer/performanceProfiles/PerformanceProfileValidation.java index 0f99f8890..e4f6677e4 100644 --- a/src/main/java/com/autotune/analyzer/performanceProfiles/PerformanceProfileValidation.java +++ b/src/main/java/com/autotune/analyzer/performanceProfiles/PerformanceProfileValidation.java @@ -26,6 +26,7 @@ import com.autotune.analyzer.utils.AnalyzerErrorConstants; import com.autotune.utils.KruizeConstants; import com.autotune.utils.KruizeSupportedTypes; +import com.fasterxml.jackson.databind.JsonNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,12 +47,20 @@ public class PerformanceProfileValidation { private String errorMessage; private final Map performanceProfilesMap; - //Mandatory fields + //Mandatory fields for PerformanceProfile private final List mandatoryFields = new ArrayList<>(Arrays.asList( AnalyzerConstants.PerformanceProfileConstants.PERF_PROFILE_NAME, AnalyzerConstants.SLO )); + //Mandatory fields for MetricProfile + private final List mandatoryMetricFields = new ArrayList<>(Arrays.asList( + AnalyzerConstants.API_VERSION, + AnalyzerConstants.KIND, + AnalyzerConstants.AutotuneObjectConstants.METADATA, + AnalyzerConstants.SLO + )); + private final List mandatorySLOPerf = new ArrayList<>(Arrays.asList( AnalyzerConstants.AutotuneObjectConstants.DIRECTION, AnalyzerConstants.PerformanceProfileConstants.OBJECTIVE_FUNCTION, @@ -80,6 +89,17 @@ public ValidationOutputData validate(PerformanceProfile performanceProfile) { return validatePerformanceProfileData(performanceProfile); } + /** + * Validates function variables + * + * @param metricProfile Metric Profile Object to be validated + * @return Returns the ValidationOutputData containing the response based on the validation + */ + public ValidationOutputData validateMetricProfile(PerformanceProfile metricProfile) { + + return validateMetricProfileData(metricProfile); + } + /** * Validates the data present in the performance profile object before adding it to the map * @param performanceProfile @@ -102,118 +122,17 @@ private ValidationOutputData validatePerformanceProfileData(PerformanceProfile p errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.DUPLICATE_PERF_PROFILE).append(performanceProfile.getName()); return new ValidationOutputData(false, errorString.toString(), HttpServletResponse.SC_CONFLICT); } - // Check if k8s type is supported - String k8sType = performanceProfile.getK8S_TYPE(); - if (!KruizeSupportedTypes.K8S_TYPES_SUPPORTED.contains(k8sType)) { - errorString.append(AnalyzerConstants.PerformanceProfileConstants.K8S_TYPE).append(k8sType) - .append(AnalyzerErrorConstants.AutotuneObjectErrors.UNSUPPORTED); - } - - SloInfo sloInfo = performanceProfile.getSloInfo(); - // Check if direction is supported - if (!KruizeSupportedTypes.DIRECTIONS_SUPPORTED.contains(sloInfo.getDirection())) - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.DIRECTION_NOT_SUPPORTED); - // if slo_class is present, do further validations - if (sloInfo.getSloClass() != null) { - // Check if slo_class is supported - if (!KruizeSupportedTypes.SLO_CLASSES_SUPPORTED.contains(sloInfo.getSloClass())) - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.SLO_CLASS_NOT_SUPPORTED); - - //check if slo_class is 'response_time' and direction is 'minimize' - if (sloInfo.getSloClass().equalsIgnoreCase(EMConstants.StandardDefaults.RESPONSE_TIME) && !sloInfo.getDirection() - .equalsIgnoreCase(AnalyzerConstants.AutotuneObjectConstants.MINIMIZE)) { - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.INVALID_DIRECTION_FOR_SLO_CLASS); - } - - //check if slo_class is 'throughput' and direction is 'maximize' - if (sloInfo.getSloClass().equalsIgnoreCase(EMConstants.StandardDefaults.THROUGHPUT) && !sloInfo.getDirection() - .equalsIgnoreCase(AnalyzerConstants.AutotuneObjectConstants.MAXIMIZE)) { - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.INVALID_DIRECTION_FOR_SLO_CLASS); - } - } - // Check if function_variables is empty - if (sloInfo.getFunctionVariables().isEmpty()) - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.FUNCTION_VARIABLES_EMPTY); - - // Check if objective_function and it's type exists - if (sloInfo.getObjectiveFunction() == null) - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.OBJECTIVE_FUNCTION_MISSING); - - // Get the objective_function type - String objFunctionType = sloInfo.getObjectiveFunction().getFunction_type(); - String expression = null; - for (Metric functionVariable : sloInfo.getFunctionVariables()) { - // Check if datasource is supported - if (!KruizeSupportedTypes.MONITORING_AGENTS_SUPPORTED.contains(functionVariable.getDatasource().toLowerCase())) { - errorString.append(AnalyzerConstants.AutotuneObjectConstants.FUNCTION_VARIABLE) - .append(functionVariable.getName()) - .append(AnalyzerErrorConstants.AutotuneObjectErrors.DATASOURCE_NOT_SUPPORTED); - } - // Check if value_type is supported - if (!KruizeSupportedTypes.VALUE_TYPES_SUPPORTED.contains(functionVariable.getValueType().toLowerCase())) { - errorString.append(AnalyzerConstants.AutotuneObjectConstants.FUNCTION_VARIABLE) - .append(functionVariable.getName()) - .append(AnalyzerErrorConstants.AutotuneObjectErrors.VALUE_TYPE_NOT_SUPPORTED); - } - - // Check if kubernetes_object type is supported, set default to 'container' if it's absent. - String kubernetes_object = functionVariable.getKubernetesObject(); - if (null == kubernetes_object) - functionVariable.setKubernetesObject(KruizeConstants.JSONKeys.CONTAINER); - else { - if (!KruizeSupportedTypes.KUBERNETES_OBJECTS_SUPPORTED.contains(kubernetes_object.toLowerCase())) - errorString.append(AnalyzerConstants.KUBERNETES_OBJECTS).append(kubernetes_object) - .append(AnalyzerErrorConstants.AutotuneObjectErrors.UNSUPPORTED); - } - - // Validate Objective Function - try { - if (objFunctionType.equals(AnalyzerConstants.AutotuneObjectConstants.EXPRESSION)) { - - expression = sloInfo.getObjectiveFunction().getExpression(); - if (null == expression || expression.equals(AnalyzerConstants.NULL)) { - throw new NullPointerException(AnalyzerErrorConstants.AutotuneObjectErrors.MISSING_EXPRESSION); - } - - } else if (objFunctionType.equals(AnalyzerConstants.PerformanceProfileConstants.SOURCE)) { - if (null != sloInfo.getObjectiveFunction().getExpression()) { - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.MISPLACED_EXPRESSION); - throw new InvalidValueException(errorString.toString()); - } - } else { - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.INVALID_TYPE); - throw new InvalidValueException(errorString.toString()); - } - } catch (NullPointerException | InvalidValueException npe) { - errorString.append(npe.getMessage()); - validationOutputData.setSuccess(false); - validationOutputData.setMessage(errorString.toString()); - } - - // Check if function_variable is part of objective_function - if (objFunctionType.equals(AnalyzerConstants.AutotuneObjectConstants.EXPRESSION)) { - if (!expression.contains(functionVariable.getName())) { - errorString.append(AnalyzerConstants.AutotuneObjectConstants.FUNCTION_VARIABLE) - .append(functionVariable.getName()).append(" ") - .append(AnalyzerErrorConstants.AutotuneObjectErrors.FUNCTION_VARIABLE_ERROR); - } - } - } - - // Check if objective_function is correctly formatted - if (objFunctionType.equals(AnalyzerConstants.AutotuneObjectConstants.EXPRESSION)) { - if (expression.equals(AnalyzerConstants.NULL) || !new EvalExParser().validate(sloInfo.getObjectiveFunction().getExpression(), sloInfo.getFunctionVariables())) { - errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.INVALID_OBJECTIVE_FUNCTION); - } - } + // Validates fields like k8s_type and slo object + validateCommonProfileFields(performanceProfile, errorString, validationOutputData); if (!errorString.toString().isEmpty()) { validationOutputData.setSuccess(false); validationOutputData.setMessage(errorString.toString()); validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); - } else + } else { validationOutputData.setSuccess(true); + } } return validationOutputData; } @@ -302,6 +221,278 @@ public ValidationOutputData validateMandatoryFieldsAndData(PerformanceProfile pe return validationOutputData; } + + /** + * Validates the data present in the metric profile object before adding it to the map + * @param metricProfile Metric Profile Object to be validated + * @return Returns the ValidationOutputData containing the response based on the validation + */ + private ValidationOutputData validateMetricProfileData(PerformanceProfile metricProfile) { + ValidationOutputData validationOutputData = new ValidationOutputData(false, null, null); + StringBuilder errorString = new StringBuilder(); + try { + // validate the mandatory values first + validationOutputData = validateMandatoryMetricProfileFieldsAndData(metricProfile); + + // If the mandatory values are present,proceed for further validation else return the validation object directly + if (validationOutputData.isSuccess()) { + try { + new ExperimentDBService().loadAllMetricProfiles(performanceProfilesMap); + } catch (Exception e) { + LOGGER.error("Loading saved metric profiles failed: {} ", e.getMessage()); + } + + // Check if metadata exists + JsonNode metadata = metricProfile.getMetadata(); + if (null == metadata) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.MISSING_METRIC_PROFILE_METADATA); + } + // check if the performance profile already exists + if (null != performanceProfilesMap.get(metricProfile.getMetadata().get("name").asText())) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.DUPLICATE_METRIC_PROFILE).append(metricProfile.getMetadata().get("name").asText()); + return new ValidationOutputData(false, errorString.toString(), HttpServletResponse.SC_CONFLICT); + } + + // Validates fields like k8s_type and slo object + validateCommonProfileFields(metricProfile, errorString, validationOutputData); + + if (!errorString.toString().isEmpty()) { + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorString.toString()); + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + } else { + validationOutputData.setSuccess(true); + } + } + } catch (Exception e){ + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorString.toString()); + validationOutputData.setErrorCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + return validationOutputData; + } + + /** + * Check if all mandatory values are present. + * + * @param metricObj Mandatory fields of this Metric Profile Object will be validated + * @return ValidationOutputData object containing status of the validations + */ + public ValidationOutputData validateMandatoryMetricProfileFieldsAndData(PerformanceProfile metricObj) { + List missingMandatoryFields = new ArrayList<>(); + ValidationOutputData validationOutputData = new ValidationOutputData(false, null, null); + String errorMsg; + errorMsg = ""; + mandatoryMetricFields.forEach( + mField -> { + String methodName = "get" + mField.substring(0, 1).toUpperCase() + mField.substring(1); + try { + LOGGER.debug("MethodName = {}",methodName); + Method getNameMethod = metricObj.getClass().getMethod(methodName); + if (null == getNameMethod.invoke(metricObj) || getNameMethod.invoke(metricObj).toString().isEmpty()) + missingMandatoryFields.add(mField); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + LOGGER.error("Method name {} doesn't exist!", mField); + } + } + ); + if (missingMandatoryFields.size() == 0) { + try { + String mandatoryMetadataPerf = AnalyzerConstants.PerformanceProfileConstants.PERF_PROFILE_NAME; + try { + JsonNode metadata = metricObj.getMetadata(); + String metricProfileName = metadata.get(mandatoryMetadataPerf).asText(); + if (null == metricProfileName || metricProfileName.isEmpty() || metricProfileName.equals("null")) { + missingMandatoryFields.add(mandatoryMetadataPerf); + } + } catch (Exception e) { + LOGGER.error("Method name doesn't exist for: {}!", mandatoryMetadataPerf); + } + + if (missingMandatoryFields.size() == 0) { + mandatorySLOPerf.forEach( + mField -> { + String methodName = "get" + mField.substring(0, 1).toUpperCase() + mField.substring(1); + try { + LOGGER.debug("MethodName = {}", methodName); + Method getNameMethod = metricObj.getSloInfo().getClass().getMethod(methodName); + if (getNameMethod.invoke(metricObj.getSloInfo()) == null) + missingMandatoryFields.add(mField); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + LOGGER.error("Method name {} doesn't exist!", mField); + } + + }); + if (missingMandatoryFields.size() == 0) { + mandatoryFuncVariables.forEach( + mField -> { + String methodName = "get" + mField.substring(0, 1).toUpperCase() + mField.substring(1); + try { + LOGGER.debug("MethodName = {}", methodName); + Method getNameMethod = metricObj.getSloInfo().getFunctionVariables().get(0) + .getClass().getMethod(methodName); + if (getNameMethod.invoke(metricObj.getSloInfo().getFunctionVariables().get(0)) == null) + missingMandatoryFields.add(mField); + } catch (NoSuchMethodException | IllegalAccessException | + InvocationTargetException e) { + LOGGER.error("Method name {} doesn't exist!", mField); + } + + }); + String mandatoryObjFuncData = AnalyzerConstants.AutotuneObjectConstants.OBJ_FUNCTION_TYPE; + String methodName = "get" + mandatoryObjFuncData.substring(0, 1).toUpperCase() + + mandatoryObjFuncData.substring(1); + try { + LOGGER.debug("MethodName = {}", methodName); + Method getNameMethod = metricObj.getSloInfo().getObjectiveFunction() + .getClass().getMethod(methodName); + if (getNameMethod.invoke(metricObj.getSloInfo().getObjectiveFunction()) == null) + missingMandatoryFields.add(mandatoryObjFuncData); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + LOGGER.error("Method name {} doesn't exist!", mandatoryObjFuncData); + } + validationOutputData.setSuccess(true); + } + } + + if (!missingMandatoryFields.isEmpty()) { + errorMsg = errorMsg.concat(String.format("Missing mandatory parameters: %s ", missingMandatoryFields)); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorMsg); + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + LOGGER.error("Validation error message :{}", errorMsg); + } + } catch (Exception e) { + validationOutputData.setSuccess(false); + errorMsg = errorMsg.concat(e.getMessage()); + validationOutputData.setMessage(errorMsg); + validationOutputData.setErrorCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } else { + errorMsg = errorMsg.concat(String.format("Missing mandatory parameters: %s ", missingMandatoryFields)); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorMsg); + validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); + LOGGER.error("Validation error message :{}", errorMsg); + } + + return validationOutputData; + } + + /** + * Validates fields like k8s_type and slo object common to both Metric and Performance Profile + * @param metricProfile Metric/Performance Profile object to be validated + * @param errorString StringBuilder to collect error messages during validation of multiple fields + * @param validationOutputData ValidationOutputData containing the response based on the validation + */ + private void validateCommonProfileFields(PerformanceProfile metricProfile, StringBuilder errorString, ValidationOutputData validationOutputData){ + // Check if k8s type is supported + String k8sType = metricProfile.getK8S_TYPE(); + if (!KruizeSupportedTypes.K8S_TYPES_SUPPORTED.contains(k8sType)) { + errorString.append(AnalyzerConstants.PerformanceProfileConstants.K8S_TYPE).append(k8sType) + .append(AnalyzerErrorConstants.AutotuneObjectErrors.UNSUPPORTED); + } + + SloInfo sloInfo = metricProfile.getSloInfo(); + // Check if direction is supported + if (!KruizeSupportedTypes.DIRECTIONS_SUPPORTED.contains(sloInfo.getDirection())) + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.DIRECTION_NOT_SUPPORTED); + // if slo_class is present, do further validations + if (sloInfo.getSloClass() != null) { + // Check if slo_class is supported + if (!KruizeSupportedTypes.SLO_CLASSES_SUPPORTED.contains(sloInfo.getSloClass())) + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.SLO_CLASS_NOT_SUPPORTED); + + //check if slo_class is 'response_time' and direction is 'minimize' + if (sloInfo.getSloClass().equalsIgnoreCase(EMConstants.StandardDefaults.RESPONSE_TIME) && !sloInfo.getDirection() + .equalsIgnoreCase(AnalyzerConstants.AutotuneObjectConstants.MINIMIZE)) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.INVALID_DIRECTION_FOR_SLO_CLASS); + } + + //check if slo_class is 'throughput' and direction is 'maximize' + if (sloInfo.getSloClass().equalsIgnoreCase(EMConstants.StandardDefaults.THROUGHPUT) && !sloInfo.getDirection() + .equalsIgnoreCase(AnalyzerConstants.AutotuneObjectConstants.MAXIMIZE)) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.INVALID_DIRECTION_FOR_SLO_CLASS); + } + } + // Check if function_variables is empty + if (sloInfo.getFunctionVariables().isEmpty()) + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.FUNCTION_VARIABLES_EMPTY); + + // Check if objective_function and it's type exists + if (sloInfo.getObjectiveFunction() == null) + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.OBJECTIVE_FUNCTION_MISSING); + + // Get the objective_function type + String objFunctionType = sloInfo.getObjectiveFunction().getFunction_type(); + String expression = null; + for (Metric functionVariable : sloInfo.getFunctionVariables()) { + // Check if datasource is supported + if (!KruizeSupportedTypes.MONITORING_AGENTS_SUPPORTED.contains(functionVariable.getDatasource().toLowerCase())) { + errorString.append(AnalyzerConstants.AutotuneObjectConstants.FUNCTION_VARIABLE) + .append(functionVariable.getName()) + .append(AnalyzerErrorConstants.AutotuneObjectErrors.DATASOURCE_NOT_SUPPORTED); + } + + // Check if value_type is supported + if (!KruizeSupportedTypes.VALUE_TYPES_SUPPORTED.contains(functionVariable.getValueType().toLowerCase())) { + errorString.append(AnalyzerConstants.AutotuneObjectConstants.FUNCTION_VARIABLE) + .append(functionVariable.getName()) + .append(AnalyzerErrorConstants.AutotuneObjectErrors.VALUE_TYPE_NOT_SUPPORTED); + } + + // Check if kubernetes_object type is supported, set default to 'container' if it's absent. + String kubernetes_object = functionVariable.getKubernetesObject(); + if (null == kubernetes_object) + functionVariable.setKubernetesObject(KruizeConstants.JSONKeys.CONTAINER); + else { + if (!KruizeSupportedTypes.KUBERNETES_OBJECTS_SUPPORTED.contains(kubernetes_object.toLowerCase())) + errorString.append(AnalyzerConstants.KUBERNETES_OBJECTS).append(kubernetes_object) + .append(AnalyzerErrorConstants.AutotuneObjectErrors.UNSUPPORTED); + } + + // Validate Objective Function + try { + if (objFunctionType.equals(AnalyzerConstants.AutotuneObjectConstants.EXPRESSION)) { + + expression = sloInfo.getObjectiveFunction().getExpression(); + if (null == expression || expression.equals(AnalyzerConstants.NULL)) { + throw new NullPointerException(AnalyzerErrorConstants.AutotuneObjectErrors.MISSING_EXPRESSION); + } + + } else if (objFunctionType.equals(AnalyzerConstants.PerformanceProfileConstants.SOURCE)) { + if (null != sloInfo.getObjectiveFunction().getExpression()) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.MISPLACED_EXPRESSION); + throw new InvalidValueException(errorString.toString()); + } + } else { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.INVALID_TYPE); + throw new InvalidValueException(errorString.toString()); + } + } catch (NullPointerException | InvalidValueException npe) { + errorString.append(npe.getMessage()); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(errorString.toString()); + } + + // Check if function_variable is part of objective_function + if (objFunctionType.equals(AnalyzerConstants.AutotuneObjectConstants.EXPRESSION)) { + if (!expression.contains(functionVariable.getName())) { + errorString.append(AnalyzerConstants.AutotuneObjectConstants.FUNCTION_VARIABLE) + .append(functionVariable.getName()).append(" ") + .append(AnalyzerErrorConstants.AutotuneObjectErrors.FUNCTION_VARIABLE_ERROR); + } + } + } + + // Check if objective_function is correctly formatted + if (objFunctionType.equals(AnalyzerConstants.AutotuneObjectConstants.EXPRESSION)) { + if (expression.equals(AnalyzerConstants.NULL) || !new EvalExParser().validate(sloInfo.getObjectiveFunction().getExpression(), sloInfo.getFunctionVariables())) { + errorString.append(AnalyzerErrorConstants.AutotuneObjectErrors.INVALID_OBJECTIVE_FUNCTION); + } + } + } + public boolean isSuccess() { return success; } diff --git a/src/main/java/com/autotune/analyzer/performanceProfiles/utils/PerformanceProfileUtil.java b/src/main/java/com/autotune/analyzer/performanceProfiles/utils/PerformanceProfileUtil.java index b37dffb3f..cfd9763b9 100644 --- a/src/main/java/com/autotune/analyzer/performanceProfiles/utils/PerformanceProfileUtil.java +++ b/src/main/java/com/autotune/analyzer/performanceProfiles/utils/PerformanceProfileUtil.java @@ -61,6 +61,28 @@ public static ValidationOutputData validateAndAddProfile(Map metricProfilesMap, PerformanceProfile metricProfile) { + ValidationOutputData validationOutputData; + try { + validationOutputData = new PerformanceProfileValidation(metricProfilesMap).validateMetricProfile(metricProfile); + if (validationOutputData.isSuccess()) { + addMetricProfile(metricProfilesMap, metricProfile); + } else { + validationOutputData.setMessage("Validation failed: " + validationOutputData.getMessage()); + } + } catch (Exception e) { + LOGGER.error("Validate and add metric profile failed: {}", e.getMessage()); + validationOutputData = new ValidationOutputData(false, "Validation failed: " + e.getMessage(), HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + return validationOutputData; + } + /** * @param performanceProfile * @param updateResultsAPIObject @@ -162,6 +184,11 @@ public static void addPerformanceProfile(Map perform LOGGER.debug("Added PerformanceProfile: {} ",performanceProfile.getName()); } + public static void addMetricProfile(Map performanceProfileMap, PerformanceProfile performanceProfile) { + performanceProfileMap.put(performanceProfile.getMetadata().get("name").asText(), performanceProfile); + LOGGER.debug("Added MetricProfile: {} ",performanceProfile.getMetadata().get("name")); + } + /** * Validates the aggregation function objects against the aggregationInfoResult metrics * diff --git a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java index 489ac1b7e..564584fdc 100644 --- a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java +++ b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java @@ -31,6 +31,8 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; public class Converters { private Converters() { @@ -290,6 +292,53 @@ public static PerformanceProfile convertInputJSONToCreatePerfProfile(String inpu return performanceProfile; } + public static PerformanceProfile convertInputJSONToCreateMetricProfile(String inputData) throws InvalidValueException, Exception { + PerformanceProfile metricProfile = null; + if (inputData != null) { + JSONObject jsonObject = new JSONObject(inputData); + String apiVersion = jsonObject.getString(AnalyzerConstants.API_VERSION); + String kind = jsonObject.getString(AnalyzerConstants.KIND); + + JSONObject metadataObject = jsonObject.getJSONObject(AnalyzerConstants.AutotuneObjectConstants.METADATA); + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode metadata = objectMapper.readValue(metadataObject.toString(), ObjectNode.class); + metadata.put("name", metadataObject.getString("name")); + + Double profileVersion = jsonObject.has(AnalyzerConstants.PROFILE_VERSION) ? jsonObject.getDouble(AnalyzerConstants.PROFILE_VERSION) : null; + String k8sType = jsonObject.has(AnalyzerConstants.PerformanceProfileConstants.K8S_TYPE) ? jsonObject.getString(AnalyzerConstants.PerformanceProfileConstants.K8S_TYPE) : null; + JSONObject sloJsonObject = jsonObject.getJSONObject(AnalyzerConstants.AutotuneObjectConstants.SLO); + JSONArray functionVariableArray = sloJsonObject.getJSONArray(AnalyzerConstants.AutotuneObjectConstants.FUNCTION_VARIABLES); + ArrayList functionVariablesList = new ArrayList<>(); + for (Object object : functionVariableArray) { + JSONObject functionVarObj = (JSONObject) object; + String name = functionVarObj.getString(AnalyzerConstants.AutotuneObjectConstants.NAME); + String datasource = functionVarObj.getString(AnalyzerConstants.AutotuneObjectConstants.DATASOURCE); + String query = functionVarObj.has(AnalyzerConstants.AutotuneObjectConstants.QUERY) ? functionVarObj.getString(AnalyzerConstants.AutotuneObjectConstants.QUERY) : null; + String valueType = functionVarObj.getString(AnalyzerConstants.AutotuneObjectConstants.VALUE_TYPE); + String kubeObject = functionVarObj.has(AnalyzerConstants.KUBERNETES_OBJECT) ? functionVarObj.getString(AnalyzerConstants.KUBERNETES_OBJECT) : null; + Metric metric = new Metric(name, query, datasource, valueType, kubeObject); + JSONArray aggrFunctionArray = functionVarObj.has(AnalyzerConstants.AGGREGATION_FUNCTIONS) ? functionVarObj.getJSONArray(AnalyzerConstants.AGGREGATION_FUNCTIONS) : null; + for (Object innerObject : aggrFunctionArray) { + JSONObject aggrFuncJsonObject = (JSONObject) innerObject; + HashMap aggregationFunctionsMap = new HashMap<>(); + String function = aggrFuncJsonObject.getString(AnalyzerConstants.FUNCTION); + String aggrFuncQuery = aggrFuncJsonObject.getString(KruizeConstants.JSONKeys.QUERY); + String version = aggrFuncJsonObject.has(KruizeConstants.JSONKeys.VERSION) ? aggrFuncJsonObject.getString(KruizeConstants.JSONKeys.VERSION) : null; + AggregationFunctions aggregationFunctions = new AggregationFunctions(function, aggrFuncQuery, version); + aggregationFunctionsMap.put(function, aggregationFunctions); + metric.setAggregationFunctionsMap(aggregationFunctionsMap); + } + functionVariablesList.add(metric); + } + String sloClass = sloJsonObject.has(AnalyzerConstants.AutotuneObjectConstants.SLO_CLASS) ? sloJsonObject.get(AnalyzerConstants.AutotuneObjectConstants.SLO_CLASS).toString() : null; + String direction = sloJsonObject.has(AnalyzerConstants.AutotuneObjectConstants.DIRECTION) ? sloJsonObject.get(AnalyzerConstants.AutotuneObjectConstants.DIRECTION).toString() : null; + ObjectiveFunction objectiveFunction = new Gson().fromJson(sloJsonObject.getJSONObject(AnalyzerConstants.AutotuneObjectConstants.OBJECTIVE_FUNCTION).toString(), ObjectiveFunction.class); + SloInfo sloInfo = new SloInfo(sloClass, objectiveFunction, direction, functionVariablesList); + metricProfile = new PerformanceProfile(apiVersion, kind, metadata, profileVersion, k8sType, sloInfo); + } + return metricProfile; + } + public static ConcurrentHashMap ConvertUpdateResultDataToAPIResponse(ConcurrentHashMap mainKruizeExperimentMap) { return null; } diff --git a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java new file mode 100644 index 000000000..af66bf6f3 --- /dev/null +++ b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2024 Red Hat, IBM Corporation and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ + +package com.autotune.analyzer.services; + +import com.autotune.analyzer.exceptions.InvalidValueException; +import com.autotune.analyzer.exceptions.PerformanceProfileResponse; +import com.autotune.analyzer.performanceProfiles.PerformanceProfile; +import com.autotune.analyzer.performanceProfiles.utils.PerformanceProfileUtil; +import com.autotune.analyzer.serviceObjects.Converters; +import com.autotune.analyzer.utils.AnalyzerConstants; +import com.autotune.analyzer.utils.AnalyzerErrorConstants; +import com.autotune.analyzer.utils.GsonUTCDateAdapter; +import com.autotune.common.data.ValidationOutputData; +import com.autotune.common.data.metrics.Metric; +import com.autotune.database.service.ExperimentDBService; +import com.autotune.utils.KruizeConstants; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.gson.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.Serial; +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Date; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import static com.autotune.analyzer.utils.AnalyzerConstants.ServiceConstants.CHARACTER_ENCODING; +import static com.autotune.analyzer.utils.AnalyzerConstants.ServiceConstants.JSON_CONTENT_TYPE; + +/** + * REST API to create metric profile . + */ +@WebServlet(asyncSupported = true) +public class MetricProfileService extends HttpServlet { + @Serial + private static final long serialVersionUID = 1L; + private static final Logger LOGGER = LoggerFactory.getLogger(MetricProfileService.class); + private ConcurrentHashMap metricProfilesMap; + + @Override + public void init(ServletConfig config) throws ServletException { + super.init(config); + metricProfilesMap = (ConcurrentHashMap) getServletContext() + .getAttribute(AnalyzerConstants.PerformanceProfileConstants.METRIC_PROFILE_MAP); + } + + /** + * Validate and create new Metric Profile. + * + * @param request + * @param response + * @throws IOException + */ + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { + try { + Map metricProfilesMap = new ConcurrentHashMap<>(); + String inputData = request.getReader().lines().collect(Collectors.joining()); + PerformanceProfile metricProfile = Converters.KruizeObjectConverters.convertInputJSONToCreateMetricProfile(inputData); + ValidationOutputData validationOutputData = PerformanceProfileUtil.validateAndAddMetricProfile(metricProfilesMap, metricProfile); + if (validationOutputData.isSuccess()) { + ValidationOutputData addedToDB = new ExperimentDBService().addMetricProfileToDB(metricProfile); + if (addedToDB.isSuccess()) { + metricProfilesMap.put(String.valueOf(metricProfile.getMetadata().get("name")), metricProfile); + getServletContext().setAttribute(AnalyzerConstants.PerformanceProfileConstants.METRIC_PROFILE_MAP, metricProfilesMap); + LOGGER.debug(KruizeConstants.MetricProfileAPIMessages.ADD_METRIC_PROFILE_TO_DB_WITH_VERSION, + metricProfile.getMetadata().get("name").asText(), metricProfile.getProfile_version()); + sendSuccessResponse(response, String.format(KruizeConstants.MetricProfileAPIMessages.CREATE_METRIC_PROFILE_SUCCESS_MSG, metricProfile.getMetadata().get("name").asText())); + } else { + sendErrorResponse(response, null, HttpServletResponse.SC_BAD_REQUEST, addedToDB.getMessage()); + } + } else + sendErrorResponse(response, null, validationOutputData.getErrorCode(), validationOutputData.getMessage()); + } catch (Exception e) { + sendErrorResponse(response, e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Validation failed: " + e.getMessage()); + } catch (InvalidValueException e) { + throw new RuntimeException(e); + } + } + + /** + * Get List of Metric Profiles + * + * @param req + * @param response + * @throws ServletException + * @throws IOException + */ + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException { + response.setContentType(JSON_CONTENT_TYPE); + response.setCharacterEncoding(CHARACTER_ENCODING); + response.setStatus(HttpServletResponse.SC_OK); + String gsonStr = "[]"; + // Fetch all metric profiles from the DB + try { + new ExperimentDBService().loadAllMetricProfiles(metricProfilesMap); + } catch (Exception e) { + LOGGER.error(KruizeConstants.MetricProfileAPIMessages.LOAD_METRIC_PROFILE_FAILURE, e.getMessage()); + } + if (metricProfilesMap.size() > 0) { + Collection values = metricProfilesMap.values(); + Gson gsonObj = new GsonBuilder() + .disableHtmlEscaping() + .setPrettyPrinting() + .enableComplexMapKeySerialization() + .registerTypeAdapter(Date.class, new GsonUTCDateAdapter()) + // a custom serializer for serializing metadata of JsonNode type. + .registerTypeAdapter(JsonNode.class, new JsonSerializer() { + @Override + public JsonElement serialize(JsonNode jsonNode, Type typeOfSrc, JsonSerializationContext context) { + if (jsonNode instanceof ObjectNode) { + ObjectNode objectNode = (ObjectNode) jsonNode; + JsonObject metadataJson = new JsonObject(); + + // Extract the "name" field directly if it exists + if (objectNode.has("name")) { + metadataJson.addProperty("name", objectNode.get("name").asText()); + } + + return metadataJson; + } + return context.serialize(jsonNode); + } + }) + .setExclusionStrategies(new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes f) { + return f.getDeclaringClass() == Metric.class && ( + f.getName().equals("trialSummaryResult") + || f.getName().equals("cycleDataMap") + ); + } + + @Override + public boolean shouldSkipClass(Class aClass) { + return false; + } + }) + .create(); + gsonStr = gsonObj.toJson(values); + } else { + LOGGER.debug(AnalyzerErrorConstants.AutotuneObjectErrors.NO_PERF_PROFILE); + } + response.getWriter().println(gsonStr); + response.getWriter().close(); + } + + /** + * TODO: Need to implement + * Update Metric Profile + * + * @param req + * @param resp + * @throws ServletException + * @throws IOException + */ + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + super.doPut(req, resp); + } + + /** + * TODO: Need to implement + * Delete Metric profile + * + * @param req + * @param resp + * @throws ServletException + * @throws IOException + */ + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + super.doDelete(req, resp); + } + + /** + * Send success response in case of no errors or exceptions. + * + * @param response + * @param message + * @throws IOException + */ + private void sendSuccessResponse(HttpServletResponse response, String message) throws IOException { + response.setContentType(JSON_CONTENT_TYPE); + response.setCharacterEncoding(CHARACTER_ENCODING); + response.setStatus(HttpServletResponse.SC_CREATED); + PrintWriter out = response.getWriter(); + out.append( + new Gson().toJson( + new PerformanceProfileResponse(message + + KruizeConstants.MetricProfileAPIMessages.VIEW_METRIC_PROFILES_MSG, + HttpServletResponse.SC_CREATED, "", "SUCCESS") + ) + ); + out.flush(); + } + + /** + * Send response containing corresponding error message in case of failures and exceptions + * + * @param response + * @param e + * @param httpStatusCode + * @param errorMsg + * @throws IOException + */ + public void sendErrorResponse(HttpServletResponse response, Exception e, int httpStatusCode, String errorMsg) throws + IOException { + if (null != e) { + LOGGER.error(e.toString()); + if (null == errorMsg) + errorMsg = e.getMessage(); + } + response.sendError(httpStatusCode, errorMsg); + } +} \ No newline at end of file diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index c91f600ea..a8677da1b 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -453,6 +453,7 @@ public static final class PerformanceProfileConstants { public static final String K8S_TYPE = "k8s_type"; public static final String PERF_PROFILE = "performanceProfile"; public static final String PERF_PROFILE_MAP = "performanceProfileMap"; + public static final String METRIC_PROFILE_MAP = "metricProfileMap"; public static final String PERF_PROFILE_NAME = "name"; public static final String OBJECTIVE_FUNCTION = "objectiveFunction"; public static final String FUNCTION_VARIABLES = "functionVariables"; diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java index a07426521..791223401 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -79,6 +79,8 @@ public static final class AutotuneObjectErrors { public static final String SLO_REDUNDANCY_ERROR = "SLO Data and Performance Profile cannot exist simultaneously!"; public static final String DUPLICATE_PERF_PROFILE = "Performance Profile already exists: "; public static final String MISSING_PERF_PROFILE = "Not Found: performance_profile does not exist: "; + public static final String MISSING_METRIC_PROFILE_METADATA= "metadata missing\n"; + public static final String DUPLICATE_METRIC_PROFILE = "Metric Profile already exists: "; public static final String MISSING_EXPERIMENT_NAME = "Not Found: experiment_name does not exist: "; public static final String NO_METRICS_AVAILABLE = "No metrics available from %s to %s"; public static final String UNSUPPORTED_EXPERIMENT = String.format("At present, the system does not support bulk entries!"); diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAO.java b/src/main/java/com/autotune/database/dao/ExperimentDAO.java index bc6dc6055..8975bbb71 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAO.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAO.java @@ -25,6 +25,9 @@ public interface ExperimentDAO { // Add Performance Profile to DB public ValidationOutputData addPerformanceProfileToDB(KruizePerformanceProfileEntry kruizePerformanceProfileEntry); + // Add Metric Profile to DB + public ValidationOutputData addMetricProfileToDB(KruizeMetricProfileEntry kruizeMetricProfileEntry); + // Add DataSource to DB ValidationOutputData addDataSourceToDB(KruizeDataSourceEntry kruizeDataSourceEntry); @@ -46,6 +49,9 @@ public interface ExperimentDAO { // If Kruize restarts load all performance profiles List loadAllPerformanceProfiles() throws Exception; + // If Kruize restarts load all metric profiles + List loadAllMetricProfiles() throws Exception; + // Load a single experiment based on experimentName List loadExperimentByName(String experimentName) throws Exception; diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java index 7ffa026af..5efcc54b6 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java @@ -384,6 +384,38 @@ public ValidationOutputData addPerformanceProfileToDB(KruizePerformanceProfileEn return validationOutputData; } + /** + * Adds MetricProfile to database + * @param kruizeMetricProfileEntry Metric Profile Database object to be added + * @return validationOutputData contains the status of the DB insert operation + */ + public ValidationOutputData addMetricProfileToDB(KruizeMetricProfileEntry kruizeMetricProfileEntry) { + ValidationOutputData validationOutputData = new ValidationOutputData(false, null, null); + String statusValue = "failure"; + Timer.Sample timerAddMetricProfileDB = Timer.start(MetricsConfig.meterRegistry()); + Transaction tx = null; + try (Session session = KruizeHibernateUtil.getSessionFactory().openSession()) { + try { + tx = session.beginTransaction(); + session.persist(kruizeMetricProfileEntry); + tx.commit(); + validationOutputData.setSuccess(true); + statusValue = "success"; + } catch (HibernateException e) { + LOGGER.error("Not able to save metric profile due to {}", e.getMessage()); + if (tx != null) tx.rollback(); + e.printStackTrace(); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(e.getMessage()); + //todo save error to API_ERROR_LOG + } + } catch (Exception e) { + LOGGER.error("Not able to save metric profile due to {}", e.getMessage()); + validationOutputData.setMessage(e.getMessage()); + } + return validationOutputData; + } + /** * @param kruizeDataSourceEntry * @return validationOutputData contains the status of the DB insert operation @@ -622,6 +654,25 @@ public List loadAllPerformanceProfiles() throws E return entries; } + /** + * Fetches all the Metric Profile records from KruizeMetricProfileEntry database table + * @return List of all KruizeMetricProfileEntry database objects + * @throws Exception + */ + @Override + public List loadAllMetricProfiles() throws Exception { + String statusValue = "failure"; + Timer.Sample timerLoadAllMetricProfiles = Timer.start(MetricsConfig.meterRegistry()); + List entries = null; + try (Session session = KruizeHibernateUtil.getSessionFactory().openSession()) { + entries = session.createQuery(DBConstants.SQLQUERY.SELECT_FROM_METRIC_PROFILE, KruizeMetricProfileEntry.class).list(); + } catch (Exception e) { + LOGGER.error("Not able to load Metric Profile due to {}", e.getMessage()); + throw new Exception("Error while loading existing Metric Profile from database due to : " + e.getMessage()); + } + return entries; + } + @Override public List loadExperimentByName(String experimentName) throws Exception { //todo load only experimentStatus=inprogress , playback may not require completed experiments @@ -798,6 +849,26 @@ public List loadPerformanceProfileByName(String p return entries; } + /** + * Fetched Metric Profile by name from KruizeMetricProfileEntry database table + * @param metricProfileName Metric profile name + * @return List of KruizeMetricProfileEntry objects + * @throws Exception + */ + public List loadMetricProfileByName(String metricProfileName) throws Exception { + String statusValue = "failure"; + Timer.Sample timerLoadMetricProfileName = Timer.start(MetricsConfig.meterRegistry()); + List entries = null; + try (Session session = KruizeHibernateUtil.getSessionFactory().openSession()) { + entries = session.createQuery(DBConstants.SQLQUERY.SELECT_FROM_METRIC_PROFILE_BY_NAME, KruizeMetricProfileEntry.class) + .setParameter("name", metricProfileName).list(); + } catch (Exception e) { + LOGGER.error("Not able to load Metric Profile {} due to {}", metricProfileName, e.getMessage()); + throw new Exception("Error while loading existing metric profile from database due to : " + e.getMessage()); + } + return entries; + } + @Override public List getKruizeResultsEntry(String experiment_name, String cluster_name, Timestamp interval_start_time, Timestamp interval_end_time) throws Exception { diff --git a/src/main/java/com/autotune/database/helper/DBConstants.java b/src/main/java/com/autotune/database/helper/DBConstants.java index b5b704225..cf5b89f2e 100644 --- a/src/main/java/com/autotune/database/helper/DBConstants.java +++ b/src/main/java/com/autotune/database/helper/DBConstants.java @@ -57,6 +57,8 @@ public static final class SQLQUERY { public static final String SELECT_FROM_RECOMMENDATIONS = "from KruizeRecommendationEntry"; public static final String SELECT_FROM_PERFORMANCE_PROFILE = "from KruizePerformanceProfileEntry"; public static final String SELECT_FROM_PERFORMANCE_PROFILE_BY_NAME = "from KruizePerformanceProfileEntry k WHERE k.name = :name"; + public static final String SELECT_FROM_METRIC_PROFILE = "from KruizeMetricProfileEntry"; + public static final String SELECT_FROM_METRIC_PROFILE_BY_NAME = "from KruizeMetricProfileEntry k WHERE k.name = :name"; public static final String DELETE_FROM_EXPERIMENTS_BY_EXP_NAME = "DELETE FROM KruizeExperimentEntry k WHERE k.experiment_name = :experimentName"; public static final String DELETE_FROM_RESULTS_BY_EXP_NAME = "DELETE FROM KruizeResultsEntry k WHERE k.experiment_name = :experimentName"; public static final String DELETE_FROM_RECOMMENDATIONS_BY_EXP_NAME = "DELETE FROM KruizeRecommendationEntry k WHERE k.experiment_name = :experimentName"; diff --git a/src/main/java/com/autotune/database/helper/DBHelpers.java b/src/main/java/com/autotune/database/helper/DBHelpers.java index 8bae35c82..47f1c0493 100644 --- a/src/main/java/com/autotune/database/helper/DBHelpers.java +++ b/src/main/java/com/autotune/database/helper/DBHelpers.java @@ -655,6 +655,75 @@ public static List convertPerformanceProfileEntryToPerforman return performanceProfiles; } + /** + * converts MetricProfile object to KruizeMetricProfileEntry table object + * @param metricProfile metricProfile object to be converted + * @return KruizeMetricProfileEntry table object + */ + public static KruizeMetricProfileEntry convertMetricProfileObjToMetricProfileDBObj(PerformanceProfile metricProfile) { + KruizeMetricProfileEntry kruizeMetricProfileEntry = null; + try { + kruizeMetricProfileEntry = new KruizeMetricProfileEntry(); + kruizeMetricProfileEntry.setApi_version(metricProfile.getApiVersion()); + kruizeMetricProfileEntry.setKind(metricProfile.getKind()); + kruizeMetricProfileEntry.setProfile_version(metricProfile.getProfile_version()); + kruizeMetricProfileEntry.setK8s_type(metricProfile.getK8S_TYPE()); + + ObjectMapper objectMapper = new ObjectMapper(); + + try { + JsonNode metadataNode = objectMapper.readTree(metricProfile.getMetadata().toString()); + kruizeMetricProfileEntry.setMetadata(metadataNode); + } catch (JsonProcessingException e) { + throw new Exception("Error while creating metadata due to : " + e.getMessage()); + } + kruizeMetricProfileEntry.setName(metricProfile.getMetadata().get("name").asText()); + + try { + kruizeMetricProfileEntry.setSlo( + objectMapper.readTree(new Gson().toJson(metricProfile.getSloInfo()))); + } catch (JsonProcessingException e) { + throw new Exception("Error while creating SLO data due to : " + e.getMessage()); + } + } catch (Exception e) { + LOGGER.error("Error occurred while converting MetricProfile Object to MetricProfile table due to {}", e.getMessage()); + e.printStackTrace(); + } + return kruizeMetricProfileEntry; + } + + /** + * converts KruizeMetricProfileEntry table objects to MetricProfile objects + * @param kruizeMetricProfileEntryList List of KruizeMetricProfileEntry table objects to be converted + * @return List containing the MetricProfile objects + * @throws Exception + */ + public static List convertMetricProfileEntryToMetricProfileObject(List kruizeMetricProfileEntryList) throws Exception { + List metricProfiles = new ArrayList<>(); + int failureThreshHold = kruizeMetricProfileEntryList.size(); + int failureCount = 0; + for (KruizeMetricProfileEntry entry : kruizeMetricProfileEntryList) { + try { + JsonNode metadata = entry.getMetadata(); + JsonNode sloData = entry.getSlo(); + String slo_rawJson = sloData.toString(); + SloInfo sloInfo = new Gson().fromJson(slo_rawJson, SloInfo.class); + PerformanceProfile performanceProfile = new PerformanceProfile( + entry.getApi_version(), entry.getKind(), metadata, entry.getProfile_version(), entry.getK8s_type(), sloInfo); + metricProfiles.add(performanceProfile); + } catch (Exception e) { + LOGGER.error("Error occurred while reading from MetricProfile DB object due to : {}", e.getMessage()); + LOGGER.error(entry.toString()); + failureCount++; + } + } + if (failureThreshHold > 0 && failureCount == failureThreshHold) + throw new Exception("None of the Metric Profiles loaded from DB."); + + return metricProfiles; + } + + /** * converts KruizeDataSourceEntry table objects to DataSourceInfo objects * @param kruizeDataSourceList List containing the KruizeDataSourceEntry table objects diff --git a/src/main/java/com/autotune/database/init/KruizeHibernateUtil.java b/src/main/java/com/autotune/database/init/KruizeHibernateUtil.java index 3361d4a8f..e518bde28 100644 --- a/src/main/java/com/autotune/database/init/KruizeHibernateUtil.java +++ b/src/main/java/com/autotune/database/init/KruizeHibernateUtil.java @@ -59,6 +59,7 @@ public static void buildSessionFactory() { if (KruizeDeploymentInfo.local) { configuration.addAnnotatedClass(KruizeDataSourceEntry.class); configuration.addAnnotatedClass(KruizeDSMetadataEntry.class); + configuration.addAnnotatedClass(KruizeMetricProfileEntry.class); } LOGGER.info("DB is trying to connect to {}", connectionURL); sfTemp = configuration.buildSessionFactory(); diff --git a/src/main/java/com/autotune/database/service/ExperimentDBService.java b/src/main/java/com/autotune/database/service/ExperimentDBService.java index 005107ba6..56fec50ef 100644 --- a/src/main/java/com/autotune/database/service/ExperimentDBService.java +++ b/src/main/java/com/autotune/database/service/ExperimentDBService.java @@ -140,6 +140,17 @@ public void loadAllPerformanceProfiles(Map performan } } + public void loadAllMetricProfiles(Map metricProfileMap) throws Exception { + List entries = experimentDAO.loadAllMetricProfiles(); + if (null != entries && !entries.isEmpty()) { + List performanceProfiles = DBHelpers.Converters.KruizeObjectConverters.convertMetricProfileEntryToMetricProfileObject(entries); + if (!performanceProfiles.isEmpty()) { + performanceProfiles.forEach(performanceProfile -> + PerformanceProfileUtil.addMetricProfile(metricProfileMap, performanceProfile)); + } + } + } + public boolean loadResultsFromDBByName(Map mainKruizeExperimentMap, String experimentName, Timestamp calculated_start_time, Timestamp interval_end_time) throws Exception { ExperimentInterface experimentInterface = new ExperimentInterfaceImpl(); KruizeObject kruizeObject = mainKruizeExperimentMap.get(experimentName); @@ -271,6 +282,22 @@ public ValidationOutputData addPerformanceProfileToDB(PerformanceProfile perform return validationOutputData; } + /** + * Adds Metric Profile to kruizeMetricProfileEntry + * @param metricProfile Metric profile object to be added + * @return ValidationOutputData object + */ + public ValidationOutputData addMetricProfileToDB(PerformanceProfile metricProfile) { + ValidationOutputData validationOutputData = new ValidationOutputData(false, null, null); + try { + KruizeMetricProfileEntry kruizeMetricProfileEntry = DBHelpers.Converters.KruizeObjectConverters.convertMetricProfileObjToMetricProfileDBObj(metricProfile); + validationOutputData = this.experimentDAO.addMetricProfileToDB(kruizeMetricProfileEntry); + } catch (Exception e) { + LOGGER.error("Not able to save Metric Profile due to {}", e.getMessage()); + } + return validationOutputData; + } + /* * This is a Java method that loads all experiments from the database using an experimentDAO object. * The method then converts the retrieved data into KruizeObject format, adds them to a list, diff --git a/src/main/java/com/autotune/service/InitiateListener.java b/src/main/java/com/autotune/service/InitiateListener.java index 9fff47d27..c78861be9 100644 --- a/src/main/java/com/autotune/service/InitiateListener.java +++ b/src/main/java/com/autotune/service/InitiateListener.java @@ -25,6 +25,7 @@ import com.autotune.experimentManager.utils.EMConstants; import com.autotune.experimentManager.utils.EMConstants.ParallelEngineConfigs; import com.autotune.experimentManager.workerimpl.IterationManager; +import com.autotune.operator.KruizeDeploymentInfo; import com.autotune.operator.KruizeOperator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -156,6 +157,19 @@ public void run() { LOGGER.error("Failed to load performance profile: {} ", e.getMessage()); } sce.getServletContext().setAttribute(AnalyzerConstants.PerformanceProfileConstants.PERF_PROFILE_MAP, performanceProfilesMap); + + if(KruizeDeploymentInfo.local == true) { + /* + Kruize Metric Profile configuration + */ + ConcurrentHashMap metricProfilesMap = new ConcurrentHashMap<>(); + try { + new ExperimentDBService().loadAllMetricProfiles(metricProfilesMap); + } catch (Exception e) { + LOGGER.error("Failed to load metric profile: {} ", e.getMessage()); + } + sce.getServletContext().setAttribute(AnalyzerConstants.PerformanceProfileConstants.METRIC_PROFILE_MAP, metricProfilesMap); + } } @Override diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 27c468210..fad1f73ca 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -66,6 +66,13 @@ public static class APIMessages { public static final String UPDATE_RECOMMENDATIONS_FAILURE_MSG = "UpdateRecommendations API failed for experiment_name: %s and intervalEndTimeStr : %s due to %s"; } + public static class MetricProfileAPIMessages { + public static final String CREATE_METRIC_PROFILE_SUCCESS_MSG = "Metric Profile : %s created successfully."; + public static final String VIEW_METRIC_PROFILES_MSG = " View Metric Profiles at /listMetricProfiles"; + public static final String LOAD_METRIC_PROFILE_FAILURE = "Failed to load saved metric profile data: {}"; + public static final String ADD_METRIC_PROFILE_TO_DB_WITH_VERSION = "Added Metric Profile : {} into the DB with version: {}"; + } + /** * Holds the constants of env vars and values to start Autotune in different Modes */ diff --git a/src/main/java/com/autotune/utils/ServerContext.java b/src/main/java/com/autotune/utils/ServerContext.java index 7a3732517..6d407d55b 100644 --- a/src/main/java/com/autotune/utils/ServerContext.java +++ b/src/main/java/com/autotune/utils/ServerContext.java @@ -43,6 +43,8 @@ public class ServerContext { public static final String RECOMMEND_RESULTS = ROOT_CONTEXT + "listRecommendations"; public static final String CREATE_PERF_PROFILE = ROOT_CONTEXT + "createPerformanceProfile"; public static final String LIST_PERF_PROFILES = ROOT_CONTEXT + "listPerformanceProfiles"; + public static final String CREATE_METRIC_PROFILE = ROOT_CONTEXT + "createMetricProfile"; + public static final String LIST_METRIC_PROFILES = ROOT_CONTEXT + "listMetricProfiles"; public static final String KRUIZE_SERVER_URL = "http://localhost:" + KRUIZE_SERVER_PORT; public static final String SEARCH_SPACE_END_POINT = KRUIZE_SERVER_URL + SEARCH_SPACE; From a80562a2fc0a41a576e2444215d2c1400113f0ec Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 13:58:38 +0530 Subject: [PATCH 30/77] Refactor input conversion to include all the specified aggregation functions --- .../java/com/autotune/analyzer/serviceObjects/Converters.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java index 564584fdc..913b57017 100644 --- a/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java +++ b/src/main/java/com/autotune/analyzer/serviceObjects/Converters.java @@ -318,16 +318,16 @@ public static PerformanceProfile convertInputJSONToCreateMetricProfile(String in String kubeObject = functionVarObj.has(AnalyzerConstants.KUBERNETES_OBJECT) ? functionVarObj.getString(AnalyzerConstants.KUBERNETES_OBJECT) : null; Metric metric = new Metric(name, query, datasource, valueType, kubeObject); JSONArray aggrFunctionArray = functionVarObj.has(AnalyzerConstants.AGGREGATION_FUNCTIONS) ? functionVarObj.getJSONArray(AnalyzerConstants.AGGREGATION_FUNCTIONS) : null; + HashMap aggregationFunctionsMap = new HashMap<>(); for (Object innerObject : aggrFunctionArray) { JSONObject aggrFuncJsonObject = (JSONObject) innerObject; - HashMap aggregationFunctionsMap = new HashMap<>(); String function = aggrFuncJsonObject.getString(AnalyzerConstants.FUNCTION); String aggrFuncQuery = aggrFuncJsonObject.getString(KruizeConstants.JSONKeys.QUERY); String version = aggrFuncJsonObject.has(KruizeConstants.JSONKeys.VERSION) ? aggrFuncJsonObject.getString(KruizeConstants.JSONKeys.VERSION) : null; AggregationFunctions aggregationFunctions = new AggregationFunctions(function, aggrFuncQuery, version); aggregationFunctionsMap.put(function, aggregationFunctions); - metric.setAggregationFunctionsMap(aggregationFunctionsMap); } + metric.setAggregationFunctionsMap(aggregationFunctionsMap); functionVariablesList.add(metric); } String sloClass = sloJsonObject.has(AnalyzerConstants.AutotuneObjectConstants.SLO_CLASS) ? sloJsonObject.get(AnalyzerConstants.AutotuneObjectConstants.SLO_CLASS).toString() : null; From 9b7a0666549924428dbdc9bebc457573ea1ec6e0 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 14:37:07 +0530 Subject: [PATCH 31/77] Add namespace as supported kubernetes object --- src/main/java/com/autotune/utils/KruizeSupportedTypes.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/utils/KruizeSupportedTypes.java b/src/main/java/com/autotune/utils/KruizeSupportedTypes.java index 73091557f..135cd1127 100644 --- a/src/main/java/com/autotune/utils/KruizeSupportedTypes.java +++ b/src/main/java/com/autotune/utils/KruizeSupportedTypes.java @@ -75,7 +75,7 @@ private KruizeSupportedTypes() { } "((request_count / (request_sum / request_count)) / request_max) * 100")); public static final Set KUBERNETES_OBJECTS_SUPPORTED = - new HashSet<>(Arrays.asList("deployment", "pod", "container")); + new HashSet<>(Arrays.asList("deployment", "pod", "container", "namespace")); public static final Set DSMETADATA_QUERY_PARAMS_SUPPORTED = new HashSet<>(Arrays.asList( "datasource", "cluster_name", "namespace", "verbose" From 260cfc00326499b3f5082cdb982333ed8cb796f6 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 15:27:24 +0530 Subject: [PATCH 32/77] Add metric profile in-memory collection --- .../MetricProfileCollection.java | 75 +++++++++++++++++++ .../services/MetricProfileService.java | 5 ++ .../com/autotune/utils/KruizeConstants.java | 9 +++ 3 files changed, 89 insertions(+) create mode 100644 src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java diff --git a/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java b/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java new file mode 100644 index 000000000..75dd92ada --- /dev/null +++ b/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2024, 2024 Red Hat, IBM Corporation and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.autotune.analyzer.performanceProfiles; + +import com.autotune.database.service.ExperimentDBService; +import com.autotune.utils.KruizeConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +public class MetricProfileCollection { + private static final Logger LOGGER = LoggerFactory.getLogger(MetricProfileCollection.class); + private static MetricProfileCollection metricProfileCollectionInstance = new MetricProfileCollection(); + private HashMap metricProfileCollection; + + private MetricProfileCollection() { + this.metricProfileCollection = new HashMap<>(); + } + + public static MetricProfileCollection getInstance() { + return metricProfileCollectionInstance; + } + + public HashMap getMetricProfileCollection() { + return metricProfileCollection; + } + + public void loadMetricProfilesFromDB() { + try { + LOGGER.info(KruizeConstants.MetricProfileConstants.CHECKING_AVAILABLE_METRIC_PROFILE_FROM_DB); + Map availableMetricProfiles = new HashMap<>(); + new ExperimentDBService().loadAllMetricProfiles(availableMetricProfiles); + if (availableMetricProfiles.isEmpty()) { + LOGGER.info(KruizeConstants.MetricProfileConstants.NO_METRIC_PROFILE_FOUND_IN_DB); + }else { + for (Map.Entry metricProfile : availableMetricProfiles.entrySet()) { + LOGGER.info(KruizeConstants.MetricProfileConstants.METRIC_PROFILE_FOUND, metricProfile.getKey()); + metricProfileCollection.put(metricProfile.getKey(), metricProfile.getValue()); + } + } + + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + } + + + public void addMetricProfile(PerformanceProfile metricProfile) { + String metricProfileName = metricProfile.getMetadata().get("name").asText(); + + LOGGER.info(KruizeConstants.MetricProfileConstants.ADDING_METRIC_PROFILE + "{}", metricProfileName); + + if(metricProfileCollection.containsKey(metricProfileName)) { + LOGGER.error(KruizeConstants.MetricProfileConstants.METRIC_PROFILE_ALREADY_EXISTS + "{}", metricProfileName); + } else { + LOGGER.info(KruizeConstants.MetricProfileConstants.METRIC_PROFILE_ADDED + "{}", metricProfileName); + metricProfileCollection.put(metricProfileName, metricProfile); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java index af66bf6f3..217c21f79 100644 --- a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java +++ b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java @@ -18,6 +18,7 @@ import com.autotune.analyzer.exceptions.InvalidValueException; import com.autotune.analyzer.exceptions.PerformanceProfileResponse; +import com.autotune.analyzer.performanceProfiles.MetricProfileCollection; import com.autotune.analyzer.performanceProfiles.PerformanceProfile; import com.autotune.analyzer.performanceProfiles.utils.PerformanceProfileUtil; import com.autotune.analyzer.serviceObjects.Converters; @@ -91,6 +92,10 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) getServletContext().setAttribute(AnalyzerConstants.PerformanceProfileConstants.METRIC_PROFILE_MAP, metricProfilesMap); LOGGER.debug(KruizeConstants.MetricProfileAPIMessages.ADD_METRIC_PROFILE_TO_DB_WITH_VERSION, metricProfile.getMetadata().get("name").asText(), metricProfile.getProfile_version()); + // Store metric profile in-memory collection + MetricProfileCollection metricProfileCollection = MetricProfileCollection.getInstance(); + metricProfileCollection.addMetricProfile(metricProfile); + sendSuccessResponse(response, String.format(KruizeConstants.MetricProfileAPIMessages.CREATE_METRIC_PROFILE_SUCCESS_MSG, metricProfile.getMetadata().get("name").asText())); } else { sendErrorResponse(response, null, HttpServletResponse.SC_BAD_REQUEST, addedToDB.getMessage()); diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index fad1f73ca..9c28c9428 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -73,6 +73,15 @@ public static class MetricProfileAPIMessages { public static final String ADD_METRIC_PROFILE_TO_DB_WITH_VERSION = "Added Metric Profile : {} into the DB with version: {}"; } + public static class MetricProfileConstants { + public static final String CHECKING_AVAILABLE_METRIC_PROFILE_FROM_DB = "Checking available metric profiles from database: "; + public static final String NO_METRIC_PROFILE_FOUND_IN_DB = "No metric profile found in database."; + public static final String METRIC_PROFILE_FOUND = "MetricProfile found: "; + public static final String ADDING_METRIC_PROFILE = "Trying to add the metric profile to collection: "; + public static final String METRIC_PROFILE_ALREADY_EXISTS = "MetricProfile already exists: "; + public static final String METRIC_PROFILE_ADDED = "MetricProfile added to the collection successfully: "; + } + /** * Holds the constants of env vars and values to start Autotune in different Modes */ From e49f026e2eb3f9b0ed8f3628bede4fa2a00f3391 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 15:33:06 +0530 Subject: [PATCH 33/77] Load available metric profiles during autotune initialization --- src/main/java/com/autotune/Autotune.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/autotune/Autotune.java b/src/main/java/com/autotune/Autotune.java index b6247c035..ad6ad9834 100644 --- a/src/main/java/com/autotune/Autotune.java +++ b/src/main/java/com/autotune/Autotune.java @@ -20,6 +20,7 @@ import com.autotune.analyzer.exceptions.KruizeErrorHandler; import com.autotune.analyzer.exceptions.MonitoringAgentNotFoundException; import com.autotune.analyzer.exceptions.MonitoringAgentNotSupportedException; +import com.autotune.analyzer.performanceProfiles.MetricProfileCollection; import com.autotune.analyzer.utils.AnalyzerConstants; import com.autotune.common.datasource.DataSourceCollection; import com.autotune.common.datasource.DataSourceInfo; @@ -114,6 +115,8 @@ public static void main(String[] args) { setUpDataSources(); // checking available DataSources checkAvailableDataSources(); + // load available metric profiles from db + loadMetricProfilesFromDB(); } // close the existing session factory before recreating @@ -195,6 +198,14 @@ private static void checkAvailableDataSources() { } } + /** + * loads metric profiles from database + */ + private static void loadMetricProfilesFromDB() { + MetricProfileCollection metricProfileCollection = MetricProfileCollection.getInstance(); + metricProfileCollection.loadMetricProfilesFromDB(); + } + private static void addAutotuneServlets(ServletContextHandler context) { context.addServlet(HealthService.class, HEALTH_SERVICE); // Start the Prometheus end point (/metrics) for Autotune From d0b4cf74f23eb1b0bcf35d938f3e28baa9a89e8f Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 16:25:02 +0530 Subject: [PATCH 34/77] Support name and verbose query parameters --- .../services/MetricProfileService.java | 204 +++++++++++++----- .../analyzer/utils/AnalyzerConstants.java | 1 + .../utils/AnalyzerErrorConstants.java | 11 + .../autotune/utils/KruizeSupportedTypes.java | 6 +- 4 files changed, 168 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java index 217c21f79..b8575c7bf 100644 --- a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java +++ b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java @@ -27,8 +27,10 @@ import com.autotune.analyzer.utils.GsonUTCDateAdapter; import com.autotune.common.data.ValidationOutputData; import com.autotune.common.data.metrics.Metric; +import com.autotune.common.data.result.ContainerData; import com.autotune.database.service.ExperimentDBService; import com.autotune.utils.KruizeConstants; +import com.autotune.utils.KruizeSupportedTypes; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.gson.*; @@ -45,9 +47,7 @@ import java.io.PrintWriter; import java.io.Serial; import java.lang.reflect.Type; -import java.util.Collection; -import java.util.Date; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -112,69 +112,102 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) /** * Get List of Metric Profiles * - * @param req + * @param request * @param response * @throws ServletException * @throws IOException */ @Override - protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException { + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(JSON_CONTENT_TYPE); response.setCharacterEncoding(CHARACTER_ENCODING); response.setStatus(HttpServletResponse.SC_OK); String gsonStr = "[]"; - // Fetch all metric profiles from the DB - try { - new ExperimentDBService().loadAllMetricProfiles(metricProfilesMap); - } catch (Exception e) { - LOGGER.error(KruizeConstants.MetricProfileAPIMessages.LOAD_METRIC_PROFILE_FAILURE, e.getMessage()); + + ConcurrentHashMap metricProfilesMap = new ConcurrentHashMap<>(); + String metricProfileName = request.getParameter(AnalyzerConstants.PerformanceProfileConstants.METRIC_PROFILE_NAME); + String verbose = request.getParameter(AnalyzerConstants.ServiceConstants.VERBOSE); + String internalVerbose = "false"; + boolean error = false; + + // validate Query params + Set invalidParams = new HashSet<>(); + for (String param : request.getParameterMap().keySet()) { + if (!KruizeSupportedTypes.LIST_METRIC_PROFILES_QUERY_PARAMS_SUPPORTED.contains(param)) { + invalidParams.add(param); + } } - if (metricProfilesMap.size() > 0) { - Collection values = metricProfilesMap.values(); - Gson gsonObj = new GsonBuilder() - .disableHtmlEscaping() - .setPrettyPrinting() - .enableComplexMapKeySerialization() - .registerTypeAdapter(Date.class, new GsonUTCDateAdapter()) - // a custom serializer for serializing metadata of JsonNode type. - .registerTypeAdapter(JsonNode.class, new JsonSerializer() { - @Override - public JsonElement serialize(JsonNode jsonNode, Type typeOfSrc, JsonSerializationContext context) { - if (jsonNode instanceof ObjectNode) { - ObjectNode objectNode = (ObjectNode) jsonNode; - JsonObject metadataJson = new JsonObject(); - - // Extract the "name" field directly if it exists - if (objectNode.has("name")) { - metadataJson.addProperty("name", objectNode.get("name").asText()); - } - - return metadataJson; - } - return context.serialize(jsonNode); - } - }) - .setExclusionStrategies(new ExclusionStrategy() { - @Override - public boolean shouldSkipField(FieldAttributes f) { - return f.getDeclaringClass() == Metric.class && ( - f.getName().equals("trialSummaryResult") - || f.getName().equals("cycleDataMap") - ); - } - @Override - public boolean shouldSkipClass(Class aClass) { - return false; + // Fetch metric profiles based on the query parameters using the in-memory storage collection + try { + if (invalidParams.isEmpty()) { + if (null != verbose) { + internalVerbose = verbose; + } + + try { + if (null != metricProfileName && !metricProfileName.isEmpty()) { + internalVerbose = "true"; + loadMetricProfilesFromCollection(metricProfilesMap, metricProfileName); + } else { + loadAllMetricProfilesFromCollection(metricProfilesMap); + } + + // Check if metric profile exists + if (metricProfileName != null && !metricProfilesMap.containsKey(metricProfileName)) { + error = true; + sendErrorResponse( + response, + new Exception(AnalyzerErrorConstants.APIErrors.ListMetricProfileAPI.INVALID_METRIC_PROFILE_NAME_EXCPTN), + HttpServletResponse.SC_BAD_REQUEST, + String.format(AnalyzerErrorConstants.APIErrors.ListMetricProfileAPI.INVALID_METRIC_PROFILE_NAME_MSG, metricProfileName) + ); + } else if (null == metricProfileName && metricProfilesMap.isEmpty()) { + error = true; + sendErrorResponse( + response, + new Exception(AnalyzerErrorConstants.APIErrors.ListMetricProfileAPI.NO_METRIC_PROFILES_EXCPTN), + HttpServletResponse.SC_BAD_REQUEST, + AnalyzerErrorConstants.APIErrors.ListMetricProfileAPI.NO_METRIC_PROFILES + ); + } + + if (!error) { + Collection values = metricProfilesMap.values(); + // create Gson Object + Gson gsonObj = createGsonObject(); + + if (internalVerbose.equals("false")) { + Collection filteredValues = new ArrayList<>(); + for(PerformanceProfile performanceProfile: values) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("name", performanceProfile.getMetadata().get("name").asText()); + filteredValues.add(jsonObject); + } + gsonStr = gsonObj.toJson(filteredValues); + } else { + gsonStr = gsonObj.toJson(values); } - }) - .create(); - gsonStr = gsonObj.toJson(values); - } else { - LOGGER.debug(AnalyzerErrorConstants.AutotuneObjectErrors.NO_PERF_PROFILE); + response.getWriter().println(gsonStr); + response.getWriter().close(); + } + } catch (Exception e) { + LOGGER.error("Exception: {}", e.getMessage()); + e.printStackTrace(); + sendErrorResponse(response, e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + } + } else { + sendErrorResponse( + response, + new Exception(AnalyzerErrorConstants.APIErrors.ListMetricProfileAPI.INVALID_QUERY_PARAM), + HttpServletResponse.SC_BAD_REQUEST, + String.format(AnalyzerErrorConstants.APIErrors.ListMetricProfileAPI.INVALID_QUERY_PARAM, invalidParams) + ); + } + } catch (Exception e) { + LOGGER.error(KruizeConstants.MetricProfileAPIMessages.LOAD_METRIC_PROFILE_FAILURE, e.getMessage()); + sendErrorResponse(response, e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } - response.getWriter().println(gsonStr); - response.getWriter().close(); } /** @@ -245,4 +278,69 @@ public void sendErrorResponse(HttpServletResponse response, Exception e, int htt } response.sendError(httpStatusCode, errorMsg); } + + private void loadMetricProfilesFromCollection(Map metricProfilesMap, String metricProfileName) { + try { + MetricProfileCollection metricProfileCollection = MetricProfileCollection.getInstance(); + if (null != metricProfileName && !metricProfileName.isEmpty()) { + PerformanceProfile metricProfile = metricProfileCollection.getMetricProfileCollection().get(metricProfileName); + metricProfilesMap.put(metricProfileName, metricProfile); + } + } catch (Exception e) { + LOGGER.error("Failed to load saved metric profile data: {} ", e.getMessage()); + } + } + + private void loadAllMetricProfilesFromCollection(Map metricProfilesMap) { + try { + MetricProfileCollection metricProfileCollection = MetricProfileCollection.getInstance(); + metricProfilesMap.putAll(metricProfileCollection.getMetricProfileCollection()); + } catch (Exception e) { + LOGGER.error("Failed to load all the metric profiles data: {} ", e.getMessage()); + } + } + + private Gson createGsonObject() { + return new GsonBuilder() + .disableHtmlEscaping() + .setPrettyPrinting() + .enableComplexMapKeySerialization() + .registerTypeAdapter(Date.class, new GsonUTCDateAdapter()) + // a custom serializer for serializing metadata of JsonNode type. + .registerTypeAdapter(JsonNode.class, new JsonSerializer() { + @Override + public JsonElement serialize(JsonNode jsonNode, Type typeOfSrc, JsonSerializationContext context) { + if (jsonNode instanceof ObjectNode) { + ObjectNode objectNode = (ObjectNode) jsonNode; + JsonObject metadataJson = new JsonObject(); + + // Extract the "name" field directly if it exists + if (objectNode.has("name")) { + metadataJson.addProperty("name", objectNode.get("name").asText()); + } + + return metadataJson; + } + return context.serialize(jsonNode); + } + }) + .setExclusionStrategies(new ExclusionStrategy() { + @Override + public boolean shouldSkipField(FieldAttributes f) { + return f.getDeclaringClass() == Metric.class && ( + f.getName().equals("trialSummaryResult") + || f.getName().equals("cycleDataMap") + ) || + f.getDeclaringClass() == ContainerData.class && ( + f.getName().equalsIgnoreCase("metrics") + ); + } + + @Override + public boolean shouldSkipClass(Class aClass) { + return false; + } + }) + .create(); + } } \ No newline at end of file diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index a8677da1b..10d48cbfb 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -457,6 +457,7 @@ public static final class PerformanceProfileConstants { public static final String PERF_PROFILE_NAME = "name"; public static final String OBJECTIVE_FUNCTION = "objectiveFunction"; public static final String FUNCTION_VARIABLES = "functionVariables"; + public static final String METRIC_PROFILE_NAME = "name"; public static final String VALUE_TYPE = "valueType"; public static final String SOURCE = "source"; public static final String PERFORMANCE_PROFILE_PKG = "com.autotune.analyzer.performanceProfiles.PerformanceProfileInterface."; diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java index 791223401..015c9b03b 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -223,6 +223,17 @@ private DSMetadataAPI(){ public static final String DATASOURCE_METADATA_MISSING_REQUEST_INPUT_EXCPTN = "Request input data cannot be null or empty"; public static final String DATASOURCE_METADATA_CONNECTION_FAILED = "Metadata cannot be imported, datasource connection refused or timed out"; } + + public static final class ListMetricProfileAPI { + public ListMetricProfileAPI() { + } + public static final String INVALID_QUERY_PARAM = "The query param(s) - %s is/are invalid"; + public static final String INVALID_QUERY_PARAM_VALUE = "The query param value(s) is/are invalid"; + public static final String INVALID_METRIC_PROFILE_NAME_EXCPTN = "Invalid Metric Profile Name"; + public static final String INVALID_METRIC_PROFILE_NAME_MSG = "Given metric profile name - %s either does not exist or is not valid"; + public static final String NO_METRIC_PROFILES_EXCPTN = "No metric profile"; + public static final String NO_METRIC_PROFILES = "No metric profiles found!"; + } } public static final class ConversionErrors { diff --git a/src/main/java/com/autotune/utils/KruizeSupportedTypes.java b/src/main/java/com/autotune/utils/KruizeSupportedTypes.java index 135cd1127..d297efd2f 100644 --- a/src/main/java/com/autotune/utils/KruizeSupportedTypes.java +++ b/src/main/java/com/autotune/utils/KruizeSupportedTypes.java @@ -81,10 +81,14 @@ private KruizeSupportedTypes() { } "datasource", "cluster_name", "namespace", "verbose" )); - public static final Set SUPPORTED_FORMATS = + public static final Set SUPPORTED_FORMATS = new HashSet<>(Arrays.asList("cores", "m", "Bytes", "bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "kB", "KB", "MB", "GB", "TB", "PB", "EB", "K", "k", "M", "G", "T", "P", "E")); public static final Set QUERY_PARAMS_SUPPORTED = new HashSet<>(Arrays.asList( "experiment_name", "results", "recommendations", "latest" )); + + public static final Set LIST_METRIC_PROFILES_QUERY_PARAMS_SUPPORTED = new HashSet<>(Arrays.asList( + "name", "verbose" + )); } From 700579c5ac244eb913bb1e4772aecac5984d744a Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 17:25:33 +0530 Subject: [PATCH 35/77] Add metricProfile in local experiment codeflow --- .../experiment/ExperimentValidation.java | 18 +++++++--- .../analyzer/utils/AnalyzerConstants.java | 4 +++ .../autotune/database/dao/ExperimentDAO.java | 2 ++ .../database/dao/ExperimentDAOImpl.java | 2 +- .../database/service/ExperimentDBService.java | 21 +++++++++++ .../com/autotune/operator/KruizeOperator.java | 35 +++++++++++++++++++ 6 files changed, 77 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java b/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java index 94850bda8..51aef7529 100644 --- a/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java +++ b/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Red Hat, IBM Corporation and others. + * Copyright (c) 2022, 2024 Red Hat, IBM Corporation and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import com.autotune.common.data.result.ContainerData; import com.autotune.common.k8sObjects.K8sObject; import com.autotune.database.service.ExperimentDBService; +import com.autotune.operator.KruizeDeploymentInfo; import com.autotune.operator.KruizeOperator; import com.autotune.utils.KruizeConstants; import org.slf4j.Logger; @@ -105,9 +106,13 @@ public void validate(List kruizeExptList) { errorMsg = AnalyzerErrorConstants.AutotuneObjectErrors.SLO_REDUNDANCY_ERROR; validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); } else { - // fetch the Performance Profile from the DB + // fetch the Performance / Metric Profile from the DB try { - new ExperimentDBService().loadPerformanceProfileFromDBByName(performanceProfilesMap, kruizeObject.getPerformanceProfile()); + if (!KruizeDeploymentInfo.local) { + new ExperimentDBService().loadPerformanceProfileFromDBByName(performanceProfilesMap, kruizeObject.getPerformanceProfile()); + } else { + new ExperimentDBService().loadMetricProfileFromDBByName(performanceProfilesMap, kruizeObject.getPerformanceProfile()); + } } catch (Exception e) { LOGGER.error("Loading saved Performance Profile {} failed: {} ", expName, e.getMessage()); } @@ -123,7 +128,12 @@ public void validate(List kruizeExptList) { validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); } else { // TODO - set metric profile when local=true - String perfProfileName = KruizeOperator.setDefaultPerformanceProfile(kruizeObject.getSloInfo(), mode, target_cluster); + String perfProfileName; + if (!KruizeDeploymentInfo.local) { + perfProfileName = KruizeOperator.setDefaultPerformanceProfile(kruizeObject.getSloInfo(), mode, target_cluster); + } else { + perfProfileName = KruizeOperator.setDefaultMetricProfile(kruizeObject.getSloInfo(), mode, target_cluster); + } kruizeObject.setPerformanceProfile(perfProfileName); proceed = true; } diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index 10d48cbfb..0e855a41a 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -463,6 +463,10 @@ public static final class PerformanceProfileConstants { public static final String PERFORMANCE_PROFILE_PKG = "com.autotune.analyzer.performanceProfiles.PerformanceProfileInterface."; public static final String DEFAULT_PROFILE = "default"; + //Metric profile constants + public static final String DEFAULT_API_VERSION = "recommender.com/v1"; + public static final String DEFAULT_KIND = "KruizePerformanceProfile"; + // Perf profile names public static final String RESOURCE_OPT_OPENSHIFT_PROFILE = "resource-optimization-openshift"; public static final String RESOURCE_OPT_LOCAL_MON_PROFILE = "resource-optimization-local-monitoring"; diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAO.java b/src/main/java/com/autotune/database/dao/ExperimentDAO.java index 8975bbb71..aad4442e4 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAO.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAO.java @@ -69,6 +69,8 @@ public interface ExperimentDAO { // Load a single Performance Profile based on name List loadPerformanceProfileByName(String performanceProfileName) throws Exception; + // Load a single Metric Profile based on name + List loadMetricProfileByName(String metricProfileName) throws Exception; // Load all recommendations of a particular experiment and interval end Time KruizeRecommendationEntry loadRecommendationsByExperimentNameAndDate(String experimentName, String cluster_name, Timestamp interval_end_time) throws Exception; diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java index 5efcc54b6..099ac7397 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java @@ -850,7 +850,7 @@ public List loadPerformanceProfileByName(String p } /** - * Fetched Metric Profile by name from KruizeMetricProfileEntry database table + * Fetches Metric Profile by name from KruizeMetricProfileEntry database table * @param metricProfileName Metric profile name * @return List of KruizeMetricProfileEntry objects * @throws Exception diff --git a/src/main/java/com/autotune/database/service/ExperimentDBService.java b/src/main/java/com/autotune/database/service/ExperimentDBService.java index 56fec50ef..ab02f8312 100644 --- a/src/main/java/com/autotune/database/service/ExperimentDBService.java +++ b/src/main/java/com/autotune/database/service/ExperimentDBService.java @@ -388,6 +388,27 @@ public void loadPerformanceProfileFromDBByName(Map p } } + /** + * Fetches Metric Profile by name from kruizeMetricProfileEntry + * @param metricProfileMap Map to store metric profile loaded from the database + * @param metricProfileName Metric profile name to be fetched + * @return ValidationOutputData object + */ + public void loadMetricProfileFromDBByName(Map metricProfileMap, String metricProfileName) throws Exception { + List entries = experimentDAO.loadMetricProfileByName(metricProfileName); + if (null != entries && !entries.isEmpty()) { + List metricProfiles = DBHelpers.Converters.KruizeObjectConverters + .convertMetricProfileEntryToMetricProfileObject(entries); + if (!metricProfiles.isEmpty()) { + for (PerformanceProfile performanceProfile : metricProfiles) { + if (null != performanceProfile) { + PerformanceProfileUtil.addMetricProfile(metricProfileMap, performanceProfile); + } + } + } + } + } + public void loadAllExperimentsAndRecommendations(Map mainKruizeExperimentMap) throws Exception { loadAllExperiments(mainKruizeExperimentMap); diff --git a/src/main/java/com/autotune/operator/KruizeOperator.java b/src/main/java/com/autotune/operator/KruizeOperator.java index 61f77da25..9baeb14a9 100644 --- a/src/main/java/com/autotune/operator/KruizeOperator.java +++ b/src/main/java/com/autotune/operator/KruizeOperator.java @@ -40,6 +40,8 @@ import com.autotune.common.variables.Variables; import com.autotune.utils.EventLogger; import com.autotune.utils.KubeEventLogger; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.gson.Gson; import io.fabric8.kubernetes.api.model.Container; import io.fabric8.kubernetes.api.model.ObjectMeta; @@ -451,6 +453,39 @@ public static String setDefaultPerformanceProfile(SloInfo sloInfo, String mode, return performanceProfile.getName(); } + public static String setDefaultMetricProfile(SloInfo sloInfo, String mode, String targetCluster) { + PerformanceProfile metricProfile = null; + try { + String apiVersion = AnalyzerConstants.PerformanceProfileConstants.DEFAULT_API_VERSION; + String kind = AnalyzerConstants.PerformanceProfileConstants.DEFAULT_KIND; + String name = AnalyzerConstants.PerformanceProfileConstants.DEFAULT_PROFILE; + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode metadataNode = objectMapper.createObjectNode(); + metadataNode.put("name",name); + + double profile_version = AnalyzerConstants.DEFAULT_PROFILE_VERSION; + String k8s_type = AnalyzerConstants.DEFAULT_K8S_TYPE; + metricProfile = new PerformanceProfile(apiVersion, kind, metadataNode, profile_version, k8s_type, sloInfo); + + if (null != metricProfile) { + ValidationOutputData validationOutputData = PerformanceProfileUtil.validateAndAddMetricProfile(PerformanceProfilesDeployment.performanceProfilesMap, metricProfile); + if (validationOutputData.isSuccess()) { + LOGGER.info("Added metric Profile : {} into the map with version: {}", + metricProfile.getName(), metricProfile.getProfile_version()); + } else { + new KubeEventLogger(Clock.systemUTC()).log("Failed", validationOutputData.getMessage(), EventLogger.Type.Warning, null, null, null, null); + } + } else { + new KubeEventLogger(Clock.systemUTC()).log("Failed", "Unable to create metric profile ", EventLogger.Type.Warning, null, null, null, null); + } + } catch (Exception e) { + LOGGER.error("Exception while adding Metric profile with message: {} ", e.getMessage()); + new KubeEventLogger(Clock.systemUTC()).log("Failed", e.getMessage(), EventLogger.Type.Warning, null, null, null, null); + return null; + } + return metricProfile.getName(); + } + /** * Parse KruizeLayer JSON and create matching KruizeLayer object * From 09e03093b6ab51e47400c110e5e6c949ad83e9db Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 18:00:43 +0530 Subject: [PATCH 36/77] Integrate MetricProfile with genRecomm to fetch cpu/memory queries dynamically --- .../engine/RecommendationEngine.java | 219 +++++++++++++++++- .../analyzer/utils/AnalyzerConstants.java | 7 +- 2 files changed, 223 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index ad06a3d69..f55ce0fd3 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -2,6 +2,8 @@ import com.autotune.analyzer.kruizeObject.KruizeObject; import com.autotune.analyzer.kruizeObject.RecommendationSettings; +import com.autotune.analyzer.performanceProfiles.MetricProfileCollection; +import com.autotune.analyzer.performanceProfiles.PerformanceProfile; import com.autotune.analyzer.plots.PlotManager; import com.autotune.analyzer.recommendations.ContainerRecommendations; import com.autotune.analyzer.recommendations.RecommendationConfigItem; @@ -19,6 +21,8 @@ import com.autotune.analyzer.utils.AnalyzerErrorConstants; import com.autotune.common.data.ValidationOutputData; import com.autotune.common.data.dataSourceQueries.PromQLDataSourceQueries; +import com.autotune.common.data.metrics.AggregationFunctions; +import com.autotune.common.data.metrics.Metric; import com.autotune.common.data.metrics.MetricAggregationInfoResults; import com.autotune.common.data.metrics.MetricResults; import com.autotune.common.data.result.ContainerData; @@ -1423,8 +1427,8 @@ private String getResults(Map mainKruizeExperimentMAP, Kru if (dataSourceInfo == null) { throw new DataSourceNotExist(KruizeConstants.DataSourceConstants.DataSourceErrorMsgs.MISSING_DATASOURCE_INFO); } - // Fetch metrics based on the datasource - fetchMetricsBasedOnDatasource(kruizeObject, interval_end_time, intervalStartTime, dataSourceInfo); + // Fetch metrics dynamically from Metric Profile based on the datasource + fetchMetricsBasedOnProfileAndDatasource(kruizeObject, interval_end_time, intervalStartTime, dataSourceInfo); } return errorMsg; } @@ -1608,4 +1612,215 @@ public void fetchMetricsBasedOnDatasource(KruizeObject kruizeObject, Timestamp i throw new Exception(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.METRIC_EXCEPTION + e.getMessage()); } } + + /** + * Fetches metrics based on the specified datasource using queries from the metricProfile for the given time interval. + * + * @param kruizeObject + * @param interval_end_time + * @param interval_start_time + * @param dataSourceInfo + * @throws Exception + */ + public void fetchMetricsBasedOnProfileAndDatasource(KruizeObject kruizeObject, Timestamp interval_end_time, Timestamp interval_start_time, DataSourceInfo dataSourceInfo) throws Exception { + try { + long interval_end_time_epoc = 0; + long interval_start_time_epoc = 0; + SimpleDateFormat sdf = new SimpleDateFormat(KruizeConstants.DateFormats.STANDARD_JSON_DATE_FORMAT, Locale.ROOT); + + String metricProfileName = kruizeObject.getPerformanceProfile(); + PerformanceProfile metricProfile = MetricProfileCollection.getInstance().getMetricProfileCollection().get(metricProfileName); + if (null == metricProfile) { + LOGGER.error("MetricProfile does not exist or is not valid: {}", metricProfileName); + return; + } + + String maxDateQuery = null; + Listmetrics = metricProfile.getSloInfo().getFunctionVariables(); + for (Metric metric: metrics) { + String name = metric.getName(); + if(name.equals("maxDate")){ + String query = metric.getAggregationFunctionsMap().get("max").getQuery(); + maxDateQuery = query; + break; + } + } + + Double measurementDurationMinutesInDouble = kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble(); + List kubernetes_objects = kruizeObject.getKubernetes_objects(); + + // Iterate over Kubernetes objects + for (K8sObject k8sObject : kubernetes_objects) { + String namespace = k8sObject.getNamespace(); + String workload = k8sObject.getName(); + String workload_type = k8sObject.getType(); + HashMap containerDataMap = k8sObject.getContainerDataMap(); + // Iterate over containers + for (Map.Entry entry : containerDataMap.entrySet()) { + ContainerData containerData = entry.getValue(); + String containerName = containerData.getContainer_name(); + if (null == interval_end_time) { + LOGGER.info(KruizeConstants.APIMessages.CONTAINER_USAGE_INFO); + String queryToEncode; + if (null != maxDateQuery) { + LOGGER.info("maxDateQuery: {}", maxDateQuery); + queryToEncode = maxDateQuery + .replace(AnalyzerConstants.NAMESPACE_VARIABLE, namespace) + .replace(AnalyzerConstants.CONTAINER_VARIABLE, containerName) + .replace(AnalyzerConstants.WORKLOAD_VARIABLE, workload) + .replace(AnalyzerConstants.WORKLOAD_TYPE_VARIABLE, workload_type); + } else { + queryToEncode = String.format(PromQLDataSourceQueries.MAX_DATE, containerName, namespace); + } + String dateMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATE_ENDPOINT_WITH_QUERY, + dataSourceInfo.getUrl(), + URLEncoder.encode(queryToEncode, CHARACTER_ENCODING) + ); + LOGGER.info(dateMetricsUrl); + JSONObject genericJsonObject = new GenericRestApiClient(dateMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); + JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); + JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); + // Process fetched metrics + if (null != resultArray && !resultArray.isEmpty()) { + resultArray = resultArray.get(0) + .getAsJsonObject().getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.VALUE); + long epochTime = resultArray.get(0).getAsLong(); + String timestamp = sdf.format(new Date(epochTime * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC)); + Date date = sdf.parse(timestamp); + Timestamp dateTS = new Timestamp(date.getTime()); + interval_end_time_epoc = dateTS.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC + - ((long) dateTS.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); + int maxDay = Terms.getMaxDays(kruizeObject.getTerms()); + LOGGER.info(KruizeConstants.APIMessages.MAX_DAY, maxDay); + Timestamp startDateTS = Timestamp.valueOf(Objects.requireNonNull(dateTS).toLocalDateTime().minusDays(maxDay)); + interval_start_time_epoc = startDateTS.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC + - ((long) startDateTS.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC); + } + } else { + // Convert timestamps to epoch time + interval_end_time_epoc = interval_end_time.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC + - ((long) interval_end_time.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); + interval_start_time_epoc = interval_start_time.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC + - ((long) interval_start_time.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC); + } + HashMap containerDataResults = new HashMap<>(); + IntervalResults intervalResults; + HashMap resMap; + HashMap resultMap; + MetricResults metricResults; + MetricAggregationInfoResults metricAggregationInfoResults; + + List metricList = metricProfile.getSloInfo().getFunctionVariables(); + + // Iterate over metrics and aggregation functions + for (Metric metricEntry : metricList) { + HashMap aggregationFunctions = metricEntry.getAggregationFunctionsMap(); + for (Map.Entry aggregationFunctionsEntry: aggregationFunctions.entrySet()) { + // Determine promQL query on metric type + String metricQuery = aggregationFunctionsEntry.getValue().getQuery(); + String promQL = metricQuery; + String format = null; + + + // Determine format based on metric type - Todo move this metric profile + List cpuFunction = Arrays.asList(AnalyzerConstants.MetricName.cpuUsage.toString(), AnalyzerConstants.MetricName.cpuThrottle.toString(), AnalyzerConstants.MetricName.cpuLimit.toString(), AnalyzerConstants.MetricName.cpuRequest.toString()); + List memFunction = Arrays.asList(AnalyzerConstants.MetricName.memoryLimit.toString(), AnalyzerConstants.MetricName.memoryRequest.toString(), AnalyzerConstants.MetricName.memoryRSS.toString(), AnalyzerConstants.MetricName.memoryUsage.toString()); + if (cpuFunction.contains(metricEntry.getName())) { + format = KruizeConstants.JSONKeys.CORES; + } else if (memFunction.contains(metricEntry.getName())) { + format = KruizeConstants.JSONKeys.BYTES; + } + + promQL = promQL + .replace(AnalyzerConstants.NAMESPACE_VARIABLE, namespace) + .replace(AnalyzerConstants.CONTAINER_VARIABLE, containerName) + .replace(AnalyzerConstants.MEASUREMENT_DURATION_IN_MIN_VARAIBLE, Integer.toString(measurementDurationMinutesInDouble.intValue())) + .replace(AnalyzerConstants.WORKLOAD_VARIABLE, workload) + .replace(AnalyzerConstants.WORKLOAD_TYPE_VARIABLE, workload_type); + + // If promQL is determined, fetch metrics from the datasource + if (promQL != null) { + LOGGER.info(promQL); + String podMetricsUrl; + try { + podMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATASOURCE_ENDPOINT_WITH_QUERY, + dataSourceInfo.getUrl(), + URLEncoder.encode(promQL, CHARACTER_ENCODING), + interval_start_time_epoc, + interval_end_time_epoc, + measurementDurationMinutesInDouble.intValue() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); + LOGGER.info(podMetricsUrl); + JSONObject genericJsonObject = new GenericRestApiClient(podMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); + JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); + JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); + // Process fetched metrics + if (null != resultArray && !resultArray.isEmpty()) { + resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray( + KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT).get(0) + .getAsJsonObject().getAsJsonArray(KruizeConstants.DataSourceConstants + .DataSourceQueryJSONKeys.VALUES); + sdf.setTimeZone(TimeZone.getTimeZone(KruizeConstants.TimeUnitsExt.TimeZones.UTC)); + + // Iterate over fetched metrics + Timestamp sTime = new Timestamp(interval_start_time_epoc); + for (JsonElement element : resultArray) { + JsonArray valueArray = element.getAsJsonArray(); + long epochTime = valueArray.get(0).getAsLong(); + double value = valueArray.get(1).getAsDouble(); + String timestamp = sdf.format(new Date(epochTime * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC)); + Date date = sdf.parse(timestamp); + Timestamp eTime = new Timestamp(date.getTime()); + + // Prepare interval results + if (containerDataResults.containsKey(eTime)) { + intervalResults = containerDataResults.get(eTime); + resMap = intervalResults.getMetricResultsMap(); + } else { + intervalResults = new IntervalResults(); + resMap = new HashMap<>(); + } + AnalyzerConstants.MetricName metricName = AnalyzerConstants.MetricName.valueOf(metricEntry.getName()); + if (resMap.containsKey(metricName)) { + metricResults = resMap.get(metricName); + metricAggregationInfoResults = metricResults.getAggregationInfoResult(); + } else { + metricResults = new MetricResults(); + metricAggregationInfoResults = new MetricAggregationInfoResults(); + } + + Method method = MetricAggregationInfoResults.class.getDeclaredMethod(KruizeConstants.APIMessages.SET + aggregationFunctionsEntry.getKey().substring(0, 1).toUpperCase() + aggregationFunctionsEntry.getKey().substring(1), Double.class); + method.invoke(metricAggregationInfoResults, value); + metricAggregationInfoResults.setFormat(format); + metricResults.setAggregationInfoResult(metricAggregationInfoResults); + metricResults.setName(metricEntry.getName()); + metricResults.setFormat(format); + resMap.put(metricName, metricResults); + intervalResults.setMetricResultsMap(resMap); + intervalResults.setIntervalStartTime(sTime); //Todo this will change + intervalResults.setIntervalEndTime(eTime); + intervalResults.setDurationInMinutes((double) ((eTime.getTime() - sTime.getTime()) + / ((long) KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE + * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC))); + containerDataResults.put(eTime, intervalResults); + sTime = eTime; + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } + + containerData.setResults(containerDataResults); + if (!containerDataResults.isEmpty()) + setInterval_end_time(Collections.max(containerDataResults.keySet())); //TODO Temp fix invalid date is set if experiment having two container with different last seen date + + } + } + } catch (Exception e) { + e.printStackTrace(); + throw new Exception(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.METRIC_EXCEPTION + e.getMessage()); + } + } } diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index 0e855a41a..facfdd199 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -63,6 +63,10 @@ public class AnalyzerConstants { public static final String NONE = "none"; public static final String POD_VARIABLE = "$POD$"; public static final String NAMESPACE_VARIABLE = "$NAMESPACE$"; + public static final String CONTAINER_VARIABLE = "$CONTAINER_NAME$"; + public static final String MEASUREMENT_DURATION_IN_MIN_VARAIBLE = "$MEASUREMENT_DURATION_IN_MIN$"; + public static final String WORKLOAD_VARIABLE = "$WORKLOAD$"; + public static final String WORKLOAD_TYPE_VARIABLE = "$WORKLOAD_TYPE$"; public static final String API_VERSION = "apiVersion"; public static final String KIND = "kind"; public static final String RESOURCE_VERSION = "resourceVersion"; @@ -159,7 +163,8 @@ public enum MetricName { memoryRequest, memoryLimit, memoryUsage, - memoryRSS + memoryRSS, + maxDate } public enum K8S_OBJECT_TYPES { From 7b0463b174e5639bea08383173ff8dd68845cdd9 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 18:05:20 +0530 Subject: [PATCH 37/77] Include namespace and GPU metric names --- .../autotune/analyzer/utils/AnalyzerConstants.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index facfdd199..4a41c0a9d 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -164,7 +164,19 @@ public enum MetricName { memoryLimit, memoryUsage, memoryRSS, - maxDate + maxDate, + namespaceCpuRequest, + namespaceCpuLimit, + namespaceCpuUsage, + namespaceCpuThrottle, + namespaceMemoryRequest, + namespaceMemoryLimit, + namespaceMemoryUsage, + namespaceMemoryRSS, + namespaceTotalPods, + namespaceRunningPods, + gpuCoreUsage, + gpuMemoryUsage, } public enum K8S_OBJECT_TYPES { From bcb0289517ea3be1b58099f236c2113094c2fcdc Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 18:56:05 +0530 Subject: [PATCH 38/77] Update CPU and memory queries in local monitoring manifest --- ...esource_optimization_local_monitoring.yaml | 91 +++++++++++++------ 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/manifests/autotune/performance-profiles/resource_optimization_local_monitoring.yaml b/manifests/autotune/performance-profiles/resource_optimization_local_monitoring.yaml index 1e233720b..3c18c8d1e 100644 --- a/manifests/autotune/performance-profiles/resource_optimization_local_monitoring.yaml +++ b/manifests/autotune/performance-profiles/resource_optimization_local_monitoring.yaml @@ -23,12 +23,17 @@ slo: aggregation_functions: - function: 'avg' - query: 'avg(kube_pod_container_resource_requests{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE", resource="cpu", unit="core"})' + query: 'avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core" ,namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' # Show sum of cpu requests in bytes for a container in a deployment - function: 'sum' - query: 'sum(kube_pod_container_resource_requests{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE", resource="cpu", unit="core"})' + query: 'sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core" ,namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' + - function: 'min' + query: 'min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core" ,namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' + + - function: 'max' + query: 'max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core" ,namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' # CPU Limit # Show cpu limits in bytes for a container in a deployment @@ -39,11 +44,17 @@ slo: aggregation_functions: - function: avg - query: 'avg(kube_pod_container_resource_limits{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE", resource="cpu", unit="core"})' + query: 'avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core",namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' # Show sum of cpu limits in bytes for a container in a deployment - function: sum - query: 'sum(kube_pod_container_resource_limits{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE$", resource="cpu", unit="core"})' + query: 'sum by(container,namespace) (kube_pod_container_resource_limits{container!='',container!="", container!="POD", pod!="", resource="cpu", unit="core",namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' + + - function: 'max' + query: 'max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core",namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' + + - function: 'max' + query: 'min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core",namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' # CPU Usage @@ -65,45 +76,45 @@ slo: # For openshift versions <=4.8 aggregation_functions: - function: avg - query: 'avg(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!="POD", pod!="",namespace="$NAMESPACE$",container="$CONTAINER_NAME$" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: "<=4.8" # For openshift versions >=4.9 - function: avg - query: 'avg(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!="POD", pod!="",namespace="$NAMESPACE$",container="$CONTAINER_NAME$" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: ">4.9" # Approx minimum CPU per container in a deployment # For openshift versions <=4.8 - function: min - query: 'min(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: "<=4.8" # For openshift versions >=4.9 - function: min - query: 'min(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: ">4.9" # Approx maximum CPU per container in a deployment # For openshift versions <=4.8 - function: max - query: 'max(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: "<=4.8" # For openshift versions >=4.9 - function: max - query: 'max(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: ">4.9" # Sum of CPU usage for a container in all pods of a deployment # For openshift versions <=4.8 - function: sum - query: 'sum(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: "<=4.8" # For openshift versions >=4.9 - function: sum - query: 'sum(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: ">4.9" @@ -116,15 +127,19 @@ slo: aggregation_functions: # Average CPU throttling per container in a deployment - function: avg - query: 'avg(rate(container_cpu_cfs_throttled_seconds_total{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Maximum CPU throttling per container in a deployment - function: max - query: 'max(rate(container_cpu_cfs_throttled_seconds_total{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m])))' + + # Min of CPU throttling for a container in all pods of a deployment + - function: min + query: 'min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m])' # Sum of CPU throttling for a container in all pods of a deployment - function: sum - query: 'sum(rate(container_cpu_cfs_throttled_seconds_total{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' @@ -139,11 +154,17 @@ slo: aggregation_functions: - function: avg - query: 'avg(kube_pod_container_resource_requests{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource="memory", unit="byte"})' + query: 'avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' # Show sum of memory requests in bytes for a container in a deployment - function: sum - query: 'sum(kube_pod_container_resource_requests{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource="memory", unit="byte"})' + query: 'sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' + + - function: max + query: 'max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' + + - function: min + query: 'min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' # Memory Limit @@ -155,12 +176,17 @@ slo: aggregation_functions: - function: avg - query: 'avg(kube_pod_container_resource_limits{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE", resource="memory", unit="byte"})' + query: 'avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' # Show sum of memory limits in bytes for a container in a deployment - function: sum - query: 'sum(kube_pod_container_resource_limits{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource="memory", unit="byte"})' + query: 'sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' + + - function: max + query: 'max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' + - function: min + query: 'min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' # Memory Usage # Average memory per container in a deployment @@ -171,19 +197,19 @@ slo: aggregation_functions: - function: avg - query: 'avg(avg_over_time(container_memory_working_set_bytes{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!="POD", pod!="", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Approx minimum memory per container in a deployment - function: min - query: 'min(min_over_time(container_memory_working_set_bytes{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!="POD", pod!="", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m])' # Approx maximum memory per container in a deployment - function: max - query: 'max(max_over_time(container_memory_working_set_bytes{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!="POD", pod!="", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Sum of memory usage for a contianer in all pods of a deployment - function: sum - query: 'sum(avg_over_time(container_memory_working_set_bytes{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!="POD", pod!="", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # 2.4 Memory RSS @@ -195,17 +221,28 @@ slo: aggregation_functions: # Average memory RSS per container in a deployment - function: avg - query: 'avg(avg_over_time(container_memory_rss{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!="POD", pod!="" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Approx minimum memory RSS per container in a deployment - function: min - query: 'min(min_over_time(container_memory_rss{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!="POD", pod!="" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m])' # Approx maximum memory RSS per container in a deployment - function: max - query: 'max(max_over_time(container_memory_rss{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!="POD", pod!="" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Sum of memory RSS for a contianer in all pods of a deployment - function: sum - query: 'sum(avg_over_time(container_memory_rss{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))' + query: 'sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!="POD", pod!="" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' + + + # Container Last Active Timestamp + - name: maxDate + datasource: prometheus + value_type: "double" + kubernetes_object: "container" + + aggregation_functions: + - function: max + query: 'max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))' From 7428dedcc376b82b47b7e64d52a791557c394d6c Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 18:56:59 +0530 Subject: [PATCH 39/77] Add metric profile readme --- design/KruizeLocalAPI.md | 1030 ++++++++++++++++++++++++++++++++++++ design/MetricProfileAPI.md | 1019 +++++++++++++++++++++++++++++++++++ 2 files changed, 2049 insertions(+) create mode 100644 design/MetricProfileAPI.md diff --git a/design/KruizeLocalAPI.md b/design/KruizeLocalAPI.md index 1d5e22f39..6e75a3547 100644 --- a/design/KruizeLocalAPI.md +++ b/design/KruizeLocalAPI.md @@ -30,6 +30,16 @@ Documentation still in progress stay tuned. - Example Request and Response - Invalid Scenarios +- [Create Metric Profile API](#create-metric-profile-api) + - Introduction + - Example Request and Response + - Invalid Scenarios + +- [List Metric Profiles API](#list-metric-profiles-api) + - Introduction + - Example Request and Response + - Invalid Scenarios + - [Create Experiment API](#create-experiment-api) - Introduction - Example Request and Response @@ -1023,6 +1033,1026 @@ This is quick guide instructions to delete metadata using input JSON as follows.
+ + +### Create Metric Profile API + +This is quick guide instructions to create metric profiles using input JSON as follows. For a more detailed guide, +see [Create MetricProfile](/design/MetricProfileAPI.md) + +**Request** +`POST /createMetricProfile` + +`curl -H 'Accept: application/json' -X POST --data 'copy paste below JSON' http://:/createMetricProfile` + +

+ +Example Request for profile name - `resource-optimization-local-monitoring` + +### Example Request + +```json +{ + "apiVersion": "recommender.com/v1", + "kind": "KruizePerformanceProfile", + "metadata": { + "name": "resource-optimization-local-monitoring" + }, + "profile_version": 1, + "k8s_type": "openshift", + "slo": { + "slo_class": "resource_usage", + "direction": "minimize", + "objective_function": { + "function_type": "source" + }, + "function_variables": [ + { + "name": "cpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD ', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + ] + }, + { + "name": "cpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + ] + }, + { + "name": "cpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + + }, + { + "function": "min", + "query": "min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + + }, + { + "function": "max", + "query": "max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + + }, + { + "function": "sum", + "query": "sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + ] + }, + { + "name": "cpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "max", + "query": "max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "min", + "query": "min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "sum", + "query": "sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + ] + }, + { + "name": "memoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + ] + }, + { + "name": "memoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + ] + }, + { + "name": "memoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + ] + }, + { + "name": "memoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + ] + }, + { + "name": "maxDate", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "max", + "query": "max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))" + } + ] + } + ] + } +} +``` + +
+ + +**Response** + +
+Example Response + +### Example Response + +```json +{ + "message": "Metric Profile : resource-optimization-local-monitoring created successfully. View all metric profiles at /listMetricProfiles", + "httpcode": 201, + "documentationLink": "", + "status": "SUCCESS" +} +``` + +
+ +
+ + + +### List Metric Profiles API + +This is quick guide instructions to retrieve metric profiles created as follows. + +**Request Parameters** + +| Parameter | Type | Required | Description | +|-----------|--------|----------|-----------------------------------------| +| name | string | optional | The name of the metric profile | +| verbose | string | optional | Flag to retrieve all the metric queries | + +**Request without passing parameters** + +`GET /listMetricProfiles` + +`curl -H 'Accept: application/json' http://:/listMetricProfiles` + +Returns list of all the metric profile names created + +
+Example Response + +### Example Response + +```json +[ + { + "name": "resource-optimization-local-monitoring" + }, + { + "name": "resource-optimization-local-monitoring1" + } +] +``` + +
+ +
+ +**Request with metric profile name** + +`GET /listMetricProfiles` + +`curl -H 'Accept: application/json' http://:/listMetricProfiles?name=resource-optimization-local-monitoring` + +Returns metric profile of the name specified + +
+Example Response + +### Example Response + +```json +[ + { + "apiVersion": "recommender.com/v1", + "kind": "KruizePerformanceProfile", + "metadata": { + "name": "resource-optimization-local-monitoring" + }, + "profile_version": 1.0, + "k8s_type": "openshift", + "slo": { + "sloClass": "resource_usage", + "objective_function": { + "function_type": "source" + }, + "direction": "minimize", + "function_variables": [ + { + "name": "cpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD ', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "cpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "cpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "cpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "memoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "memoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "memoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "memoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "maxDate", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "max": { + "function": "max", + "query": "max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))" + } + } + } + ] + } + } +] +``` + +
+ +
+ +**Request** + +`GET /listMetricProfiles` + +`curl -H 'Accept: application/json' http://:/listMetricProfiles?verbose=true` + +Returns list of all the metric profile created with all the metric queries + +
+Example Response + +### Example Response + +```json +[ + { + "apiVersion": "recommender.com/v1", + "kind": "KruizePerformanceProfile", + "metadata": { + "name": "resource-optimization-local-monitoring" + }, + "profile_version": 1.0, + "k8s_type": "openshift", + "slo": { + "sloClass": "resource_usage", + "objective_function": { + "function_type": "source" + }, + "direction": "minimize", + "function_variables": [ + { + "name": "cpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD ', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "cpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "cpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "cpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "memoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "memoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "memoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "memoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "maxDate", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "max": { + "function": "max", + "query": "max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))" + } + } + } + ] + } + }, + { + "apiVersion": "recommender.com/v1", + "kind": "KruizePerformanceProfile", + "metadata": { + "name": "resource-optimization-local-monitoring1" + }, + "profile_version": 1.0, + "k8s_type": "openshift", + "slo": { + "sloClass": "resource_usage", + "objective_function": { + "function_type": "source" + }, + "direction": "minimize", + "function_variables": [ + { + "name": "cpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD ', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "cpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "cpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "cpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "memoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "memoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "memoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "memoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "maxDate", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "max": { + "function": "max", + "query": "max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))" + } + } + } + ] + } + } +] +``` + +
+ +
+ ### Create Experiment API diff --git a/design/MetricProfileAPI.md b/design/MetricProfileAPI.md new file mode 100644 index 000000000..021841e8f --- /dev/null +++ b/design/MetricProfileAPI.md @@ -0,0 +1,1019 @@ +# Metric Profile + +The metric profile contains a list of queries used to retrieve metrics such as CPU usage, throttling, memory +usage, and more. Users can create metric profiles based on their cluster or datasource provider, such as Prometheus or +Thanos. These profiles can be tagged to create experiment APIs, which will then fetch metrics according to the metric +profile to generate recommendations. + +This article describes how to add and list Metric Profiles with REST APIs using curl command. +Documentation still in progress stay tuned. + +# Attributes + +- **apiVersion** \ + A string representing version of the Kubernetes API to create metric profile +- **kind** \ + A string representing type of kubernetes object +- **metadata** \ + A JSON object containing Data that helps to uniquely identify the metric profile, including a name string + - **name** \ + A unique string name for identifying each metric profile. +- **profile_version** \ + a double value specifying the current version of the profile. +- **slo** \ + Service Level Objective containing the _direction_, _objective_function_ and _function_variables_ + - **slo_class** \ + a standard slo "bucket" defined by Kruize. Can be "_resource_usage_", "_throughput_" or "_response_time_" + - **direction** \ + based on the slo_class, it can be '_maximize_' or '_minimize_' + - **objective_function** \ + Define the performance objective here. + - **function_type** \ + can be specified as '_source_' (a java file) or as an '_expression_'(algebraic). If it's an expression, it needs to defined below. + - **expression** \ + an algebraic expression that details the calculation using function variables. Only valid if the "_function_type_" is "expression" + - **function_variables** \ + Define the variables used in the _objective_function_ + - **name** \ + name of the variable + - **datasource** \ + datasource of the query + - **value_type** \ + can be double or integer + - **query** \ + one of the query or _aggregation_functions_ is mandatory. Both can be present. + - **kubernetes_object** \ + k8s object that this query is tied to: "_deployment_", "_pod_" or "_container_" + - **aggregation_functions** \ + aggregate functions associated with this variable + - **function** \ + can be '_avg_', '_sum_', '_min_', '_max_' + - **query** \ + corresponding query + - **versions** \ + Any specific versions that this query is tied to + + +## CreateMetricProfile + +This is quick guide instructions to create metric profile using input JSON as follows. + +**Request** +`POST /createMetricProfile` + +`curl -H 'Accept: application/json' -X POST --data 'copy paste below JSON' http://:/createMetricProfile` + +``` +{ + "apiVersion": "recommender.com/v1", + "kind": "KruizePerformanceProfile", + "metadata": { + "name": "resource-optimization-openshift" + }, + "profile_version": 1, + "k8s_type": "openshift", + "slo": { + "slo_class": "resource_usage", + "direction": "minimize", + "objective_function": { + "function_type": "source" + }, + "function_variables": [ + { + "name": "cpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD ', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + ] + }, + { + "name": "cpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + ] + }, + { + "name": "cpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + + }, + { + "function": "min", + "query": "min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + + }, + { + "function": "max", + "query": "max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + + }, + { + "function": "sum", + "query": "sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + ] + }, + { + "name": "cpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "max", + "query": "max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "min", + "query": "min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "sum", + "query": "sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + ] + }, + { + "name": "memoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + ] + }, + { + "name": "memoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + ] + }, + { + "name": "memoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + ] + }, + { + "name": "memoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + ] + }, + { + "name": "maxDate", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "max", + "query": "max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))" + } + ] + }, + { + "name": "namespaceCpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"requests.cpu\", type=\"hard\"})", + "version": "" + } + ] + }, + { + "name": "namespaceCpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"limits.cpu\", type=\"hard\"})", + "version": "" + } + ] + }, + { + "name": "namespaceMemoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"requests.memory\", type=\"hard\"})", + "version": "" + } + ] + }, + { + "name": "namespaceMemoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"limits.memory\", type=\"hard\"})", + "version": "" + } + ] + }, + { + "name": "namespaceCpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + { + "function": "max", + "query": "max_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + { + "function": "min", + "query": "min_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + } + ] + }, + { + "name": "namespaceCpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + { + "function": "max", + "query": "max_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + { + "function": "min", + "query": "min_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + } + ] + }, + { + "name": "namespaceMemoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + { + "function": "max", + "query": "max_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + { + "function": "min", + "query": "min_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + } + ] + }, + { + "name": "namespaceMemoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + { + "function": "max", + "query": "max_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + { + "function": "min", + "query": "min_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + } + ] + }, + { + "name": "namespaceTotalPods", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum(count(kube_pod_status_phase{namespace=\"$NAMESPACE$\"}))", + "version": "" + } + ] + }, + { + "name": "namespaceRunningPods", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": [ + { + "function": "sum", + "query": "sum(count(kube_pod_status_phase{namespace=\"$NAMESPACE$\", phase=\"Running\"}))", + "version": "" + } + ] + }, + { + "name": "gpuCoreUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (avg_over_time(DCGM_FI_DEV_GPU_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + }, + { + "function": "min", + "query": "min by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (min_over_time(DCGM_FI_DEV_GPU_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + }, + { + "function": "max", + "query": "max by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (max_over_time(DCGM_FI_DEV_GPU_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + } + ] + }, + { + "name": "gpuMemoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": [ + { + "function": "avg", + "query": "avg by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (avg_over_time(DCGM_FI_DEV_MEM_COPY_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + }, + { + "function": "min", + "query": "min by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (min_over_time(DCGM_FI_DEV_MEM_COPY_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + }, + { + "function": "max", + "query": "max by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (max_over_time(DCGM_FI_DEV_MEM_COPY_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + } + ] + } + ] + } +} +``` + +**Response** + +* Success +``` +{ + "message": "Metric Profile : created successfully. View all metric profiles at /listMetricProfiles", + "httpcode": 201, + "documentationLink": "", + "status": "SUCCESS" +} +``` + +* Failure + * Duplicate Metric Profile name. + ``` + { + "message": "Metric Profile already exists", + "httpcode": 409, + "documentationLink": "", + "status": "ERROR" + } + ``` + * Mandatory parameters are missing. + ``` + { + "message": "Missing mandatory parameters", + "httpcode": 400, + "documentationLink": "", + "status": "ERROR" + } + ``` + * Any unknown exception on server side + ``` + { + "message": "Internal Server Error", + "httpcode": 500, + "documentationLink": "", + "status": "ERROR" + } + ``` +#### Note: One of query or aggregation_functions is mandatory. Both can be present together. + +## List Metric Profiles + +List metric profiles output JSON as follows. + +**Request** +`GET /listMetricProfiles` + +`curl -H 'Accept: application/json' http://:/listMetricProfiles` + +**Response** +``` +[ + { + "name": "resource-optimization-openshift" + } +] +``` + +**Request** +`GET /listMetricProfiles` + +`curl -H 'Accept: application/json' http://:/listMetricProfiles?name=resource-optimization-openshift` + + +**Response** + +``` +[ + { + "apiVersion": "recommender.com/v1", + "kind": "KruizePerformanceProfile", + "metadata": { + "name": "resource-optimization-openshift" + }, + "profile_version": 1.0, + "k8s_type": "openshift", + "slo": { + "sloClass": "resource_usage", + "objective_function": { + "function_type": "source" + }, + "direction": "minimize", + "function_variables": [ + { + "name": "cpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD ', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "cpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "cpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "cpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "memoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "memoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "min": { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "max": { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + "sum": { + "function": "sum", + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + } + } + }, + { + "name": "memoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "memoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "min": { + "function": "min", + "query": "min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "max": { + "function": "max", + "query": "max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + }, + "sum": { + "function": "sum", + "query": "sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" + } + } + }, + { + "name": "maxDate", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "max": { + "function": "max", + "query": "max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))" + } + } + }, + { + "name": "namespaceCpuRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "sum": { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"requests.cpu\", type=\"hard\"})", + "version": "" + } + } + }, + { + "name": "namespaceCpuLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "sum": { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"limits.cpu\", type=\"hard\"})", + "version": "" + } + } + }, + { + "name": "namespaceMemoryRequest", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "sum": { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"requests.memory\", type=\"hard\"})", + "version": "" + } + } + }, + { + "name": "namespaceMemoryLimit", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "sum": { + "function": "sum", + "query": "sum by (namespace) (kube_resourcequota{namespace=\"$NAMESPACE$\", resource=\"limits.memory\", type=\"hard\"})", + "version": "" + } + } + }, + { + "name": "namespaceCpuUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + "min": { + "function": "min", + "query": "min_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + "max": { + "function": "max", + "query": "max_over_time(sum by(namespace) (node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + } + } + }, + { + "name": "namespaceCpuThrottle", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + "min": { + "function": "min", + "query": "min_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + "max": { + "function": "max", + "query": "max_over_time(sum by(namespace) (rate(container_cpu_cfs_throttled_seconds_total{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''}[5m]))[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + } + } + }, + { + "name": "namespaceMemoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + "min": { + "function": "min", + "query": "min_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + "max": { + "function": "max", + "query": "max_over_time(sum by(namespace) (container_memory_working_set_bytes{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + } + } + }, + { + "name": "namespaceMemoryRSS", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + "min": { + "function": "min", + "query": "min_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + }, + "max": { + "function": "max", + "query": "max_over_time(sum by(namespace) (container_memory_rss{namespace=\"$NAMESPACE$\", container!='', container!='POD', pod!=''})[$MEASUREMENT_DURATION_IN_MIN$m:])", + "version": "" + } + } + }, + { + "name": "namespaceTotalPods", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "sum": { + "function": "sum", + "query": "sum(count(kube_pod_status_phase{namespace=\"$NAMESPACE$\"}))", + "version": "" + } + } + }, + { + "name": "namespaceRunningPods", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "namespace", + "aggregation_functions": { + "sum": { + "function": "sum", + "query": "sum(count(kube_pod_status_phase{namespace=\"$NAMESPACE$\", phase=\"Running\"}))", + "version": "" + } + } + }, + { + "name": "gpuCoreUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (avg_over_time(DCGM_FI_DEV_GPU_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + }, + "min": { + "function": "min", + "query": "min by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (min_over_time(DCGM_FI_DEV_GPU_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + }, + "max": { + "function": "max", + "query": "max by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (max_over_time(DCGM_FI_DEV_GPU_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + } + } + }, + { + "name": "gpuMemoryUsage", + "datasource": "prometheus", + "value_type": "double", + "kubernetes_object": "container", + "aggregation_functions": { + "avg": { + "function": "avg", + "query": "avg by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (avg_over_time(DCGM_FI_DEV_MEM_COPY_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + }, + "min": { + "function": "min", + "query": "min by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (min_over_time(DCGM_FI_DEV_MEM_COPY_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + }, + "max": { + "function": "max", + "query": "max by (Hostname,device,modelName,UUID,exported_container,exported_namespace) (max_over_time(DCGM_FI_DEV_MEM_COPY_UTIL{exported_namespace=\"$NAMESPACE$\",exported_container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))", + "version": "" + } + } + } + ] + } + } +] +``` \ No newline at end of file From 6e8d0608ab601cd01ebb95d8ae01f41d91565243 Mon Sep 17 00:00:00 2001 From: Shreya Date: Fri, 16 Aug 2024 11:09:40 +0530 Subject: [PATCH 40/77] Add delete metric profile API --- .../java/com/autotune/analyzer/Analyzer.java | 1 + .../services/MetricProfileService.java | 82 +++++++++++++++++-- .../utils/AnalyzerErrorConstants.java | 11 +++ .../autotune/database/dao/ExperimentDAO.java | 3 + .../database/dao/ExperimentDAOImpl.java | 38 +++++++++ .../autotune/database/helper/DBConstants.java | 1 + .../com/autotune/utils/KruizeConstants.java | 2 + .../com/autotune/utils/ServerContext.java | 1 + 8 files changed, 134 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/Analyzer.java b/src/main/java/com/autotune/analyzer/Analyzer.java index 3a33cbc33..9ebf49199 100644 --- a/src/main/java/com/autotune/analyzer/Analyzer.java +++ b/src/main/java/com/autotune/analyzer/Analyzer.java @@ -55,6 +55,7 @@ public static void addServlets(ServletContextHandler context) { context.addServlet(PerformanceProfileService.class, ServerContext.LIST_PERF_PROFILES); context.addServlet(MetricProfileService.class, ServerContext.CREATE_METRIC_PROFILE); context.addServlet(MetricProfileService.class, ServerContext.LIST_METRIC_PROFILES); + context.addServlet(MetricProfileService.class, ServerContext.DELETE_METRIC_PROFILE); context.addServlet(ListDatasources.class, ServerContext.LIST_DATASOURCES); context.addServlet(DSMetadataService.class, ServerContext.DATASOURCE_METADATA); diff --git a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java index b8575c7bf..4c9ba15bc 100644 --- a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java +++ b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java @@ -28,6 +28,7 @@ import com.autotune.common.data.ValidationOutputData; import com.autotune.common.data.metrics.Metric; import com.autotune.common.data.result.ContainerData; +import com.autotune.database.dao.ExperimentDAOImpl; import com.autotune.database.service.ExperimentDBService; import com.autotune.utils.KruizeConstants; import com.autotune.utils.KruizeSupportedTypes; @@ -225,17 +226,70 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se } /** - * TODO: Need to implement * Delete Metric profile + * Handles the DELETE request for deleting metric profile - DELETE /deleteMetricProfile * - * @param req - * @param resp + * Supported Query Parameters - + * name - metric profile name to be deleted(required) + * + * @param request + * @param response * @throws ServletException * @throws IOException */ @Override - protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doDelete(req, resp); + protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + response.setContentType(JSON_CONTENT_TYPE); + response.setCharacterEncoding(CHARACTER_ENCODING); + response.setStatus(HttpServletResponse.SC_OK); + + ConcurrentHashMap metricProfilesMap = new ConcurrentHashMap<>(); + String metricProfileName = request.getParameter(AnalyzerConstants.PerformanceProfileConstants.METRIC_PROFILE_NAME); + + if (null == metricProfileName || metricProfileName.isEmpty()) { + sendErrorResponse( + response, + new Exception(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.MISSING_METRIC_PROFILE_NAME_EXCPTN), + HttpServletResponse.SC_BAD_REQUEST, + String.format(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.MISSING_METRIC_PROFILE_NAME_MSG) + ); + return; + } + + try { + // load specified metric profile + loadMetricProfilesFromCollection(metricProfilesMap, metricProfileName); + + // Check if metric profile exists + if (!metricProfilesMap.isEmpty() && metricProfilesMap.containsKey(metricProfileName)) { + try { + // Deletes database and in-memory metric profile object stored + deleteMetricProfile(metricProfileName); + metricProfilesMap.remove(metricProfileName); + } catch (Exception e) { + sendErrorResponse( + response, + e, + HttpServletResponse.SC_BAD_REQUEST, + e.getMessage()); + return; + } + } else { + sendErrorResponse( + response, + new Exception(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.INVALID_METRIC_PROFILE_NAME_EXCPTN), + HttpServletResponse.SC_BAD_REQUEST, + String.format(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.INVALID_METRIC_PROFILE_NAME_MSG, metricProfileName) + ); + return; + } + + sendSuccessResponse(response, String.format(KruizeConstants.MetricProfileAPIMessages.DELETE_METRIC_PROFILE_SUCCESS_MSG, metricProfileName)); + + } catch (Exception e) { + LOGGER.error(e.getMessage()); + sendErrorResponse(response, e, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + } } /** @@ -300,6 +354,24 @@ private void loadAllMetricProfilesFromCollection(Map } } + private void deleteMetricProfile(String metricProfileName) { + ValidationOutputData deletedMetricProfileFromDB = null; + try { + // delete the metric profile from DB + deletedMetricProfileFromDB = new ExperimentDAOImpl().deleteKruizeMetricProfileEntryByName(metricProfileName); + if (deletedMetricProfileFromDB.isSuccess()) { + // remove in-memory metric profile + MetricProfileCollection.getInstance().getMetricProfileCollection().remove(metricProfileName); + LOGGER.debug(KruizeConstants.MetricProfileAPIMessages.DELETE_METRIC_PROFILE_FROM_DB_SUCCESS_MSG); + } else { + LOGGER.error(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.DELETE_METRIC_PROFILE_FROM_DB_FAILURE_MSG, deletedMetricProfileFromDB.getMessage()); + } + + } catch (Exception e) { + LOGGER.error(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.DELETE_METRIC_PROFILE_FAILURE_MSG, e.getMessage()); + } + } + private Gson createGsonObject() { return new GsonBuilder() .disableHtmlEscaping() diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java index 015c9b03b..a365fb74e 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -234,6 +234,17 @@ public ListMetricProfileAPI() { public static final String NO_METRIC_PROFILES_EXCPTN = "No metric profile"; public static final String NO_METRIC_PROFILES = "No metric profiles found!"; } + + public static final class DeleteMetricProfileAPI { + public DeleteMetricProfileAPI() { + } + public static final String INVALID_METRIC_PROFILE_NAME_EXCPTN = "Invalid Metric Profile Name"; + public static final String INVALID_METRIC_PROFILE_NAME_MSG = "Given metric profile name - %s either does not exist or is not valid"; + public static final String MISSING_METRIC_PROFILE_NAME_EXCPTN = "Missing Metric Profile Name"; + public static final String MISSING_METRIC_PROFILE_NAME_MSG = "Missing metric profile 'name' parameter"; + public static final String DELETE_METRIC_PROFILE_FROM_DB_FAILURE_MSG = "Failed to delete metric profile from DB: %s"; + public static final String DELETE_METRIC_PROFILE_FAILURE_MSG = "Failed to delete the specified metric profile data: %s"; + } } public static final class ConversionErrors { diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAO.java b/src/main/java/com/autotune/database/dao/ExperimentDAO.java index aad4442e4..039ca641a 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAO.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAO.java @@ -72,6 +72,9 @@ public interface ExperimentDAO { // Load a single Metric Profile based on name List loadMetricProfileByName(String metricProfileName) throws Exception; + // Delete metric profile for the specified metric profile name + public ValidationOutputData deleteKruizeMetricProfileEntryByName(String metricProfileName); + // Load all recommendations of a particular experiment and interval end Time KruizeRecommendationEntry loadRecommendationsByExperimentNameAndDate(String experimentName, String cluster_name, Timestamp interval_end_time) throws Exception; diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java index 099ac7397..7ec7e7d82 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java @@ -570,6 +570,44 @@ public ValidationOutputData deleteKruizeDSMetadataEntryByName(String dataSourceN return validationOutputData; } + /** + * Delete metric profile with specified profile name + * This deletes the metadata from the KruizeMetricProfileEntry table + * @param metricProfileName + * @return + */ + @Override + public ValidationOutputData deleteKruizeMetricProfileEntryByName(String metricProfileName) { + ValidationOutputData validationOutputData = new ValidationOutputData(false, null, null); + Transaction tx = null; + try (Session session = KruizeHibernateUtil.getSessionFactory().openSession()) { + try { + tx = session.beginTransaction(); + Query query = session.createQuery(DELETE_FROM_METRIC_PROFILE_BY_PROFILE_NAME, null); + query.setParameter("metricProfileName", metricProfileName); + int deletedCount = query.executeUpdate(); + + if (deletedCount == 0) { + validationOutputData.setSuccess(false); + validationOutputData.setMessage("KruizeMetricProfileEntry not found with metric profile name: " + metricProfileName); + } else { + validationOutputData.setSuccess(true); + } + tx.commit(); + } catch (HibernateException e) { + LOGGER.error("Not able to delete metric profile for metric profile {} due to {}", metricProfileName, e.getMessage()); + if (tx != null) tx.rollback(); + e.printStackTrace(); + validationOutputData.setSuccess(false); + validationOutputData.setMessage(e.getMessage()); + //todo save error to API_ERROR_LOG + } + } catch (Exception e) { + LOGGER.error("Not able to delete metric profile for metric profile {} due to {}", metricProfileName, e.getMessage()); + } + return validationOutputData; + } + @Override public List loadAllExperiments() throws Exception { //todo load only experimentStatus=inprogress , playback may not require completed experiments diff --git a/src/main/java/com/autotune/database/helper/DBConstants.java b/src/main/java/com/autotune/database/helper/DBConstants.java index cf5b89f2e..8771dcf51 100644 --- a/src/main/java/com/autotune/database/helper/DBConstants.java +++ b/src/main/java/com/autotune/database/helper/DBConstants.java @@ -63,6 +63,7 @@ public static final class SQLQUERY { public static final String DELETE_FROM_RESULTS_BY_EXP_NAME = "DELETE FROM KruizeResultsEntry k WHERE k.experiment_name = :experimentName"; public static final String DELETE_FROM_RECOMMENDATIONS_BY_EXP_NAME = "DELETE FROM KruizeRecommendationEntry k WHERE k.experiment_name = :experimentName"; public static final String DELETE_FROM_METADATA_BY_DATASOURCE_NAME = "DELETE FROM KruizeDSMetadataEntry km WHERE km.datasource_name = :dataSourceName"; + public static final String DELETE_FROM_METRIC_PROFILE_BY_PROFILE_NAME = "DELETE FROM KruizeMetricProfileEntry km WHERE km.name = :metricProfileName"; public static final String DB_PARTITION_DATERANGE = "CREATE TABLE IF NOT EXISTS %s_%s%s%s PARTITION OF %s FOR VALUES FROM ('%s-%s-%s 00:00:00.000') TO ('%s-%s-%s 23:59:59');"; public static final String SELECT_ALL_KRUIZE_TABLES = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' " + "and (table_name like 'kruize_results_%' or table_name like 'kruize_recommendations_%') "; diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 9c28c9428..4fa4a7b95 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -71,6 +71,8 @@ public static class MetricProfileAPIMessages { public static final String VIEW_METRIC_PROFILES_MSG = " View Metric Profiles at /listMetricProfiles"; public static final String LOAD_METRIC_PROFILE_FAILURE = "Failed to load saved metric profile data: {}"; public static final String ADD_METRIC_PROFILE_TO_DB_WITH_VERSION = "Added Metric Profile : {} into the DB with version: {}"; + public static final String DELETE_METRIC_PROFILE_SUCCESS_MSG = "Metric profile: %s deleted successfully."; + public static final String DELETE_METRIC_PROFILE_FROM_DB_SUCCESS_MSG = "Metric profile deleted successfully from the DB."; } public static class MetricProfileConstants { diff --git a/src/main/java/com/autotune/utils/ServerContext.java b/src/main/java/com/autotune/utils/ServerContext.java index 6d407d55b..2c95d3efe 100644 --- a/src/main/java/com/autotune/utils/ServerContext.java +++ b/src/main/java/com/autotune/utils/ServerContext.java @@ -45,6 +45,7 @@ public class ServerContext { public static final String LIST_PERF_PROFILES = ROOT_CONTEXT + "listPerformanceProfiles"; public static final String CREATE_METRIC_PROFILE = ROOT_CONTEXT + "createMetricProfile"; public static final String LIST_METRIC_PROFILES = ROOT_CONTEXT + "listMetricProfiles"; + public static final String DELETE_METRIC_PROFILE = ROOT_CONTEXT + "deleteMetricProfile"; public static final String KRUIZE_SERVER_URL = "http://localhost:" + KRUIZE_SERVER_PORT; public static final String SEARCH_SPACE_END_POINT = KRUIZE_SERVER_URL + SEARCH_SPACE; From 382bd4ac79c3009182afdee1b067237ff0dca8cf Mon Sep 17 00:00:00 2001 From: Shreya Date: Fri, 16 Aug 2024 11:56:00 +0530 Subject: [PATCH 41/77] Include string constants --- .../com/autotune/analyzer/utils/AnalyzerErrorConstants.java | 3 +++ .../java/com/autotune/database/dao/ExperimentDAOImpl.java | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java index a365fb74e..03878893e 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerErrorConstants.java @@ -18,6 +18,7 @@ import com.autotune.operator.KruizeDeploymentInfo; import com.autotune.utils.KruizeConstants; import com.autotune.utils.KruizeSupportedTypes; +import software.amazon.awssdk.services.cloudwatchlogs.endpoints.internal.Value; import java.util.Arrays; @@ -244,6 +245,8 @@ public DeleteMetricProfileAPI() { public static final String MISSING_METRIC_PROFILE_NAME_MSG = "Missing metric profile 'name' parameter"; public static final String DELETE_METRIC_PROFILE_FROM_DB_FAILURE_MSG = "Failed to delete metric profile from DB: %s"; public static final String DELETE_METRIC_PROFILE_FAILURE_MSG = "Failed to delete the specified metric profile data: %s"; + public static final String DELETE_METRIC_PROFILE_ENTRY_NOT_FOUND_WITH_NAME = "KruizeMetricProfileEntry not found with metric profile name: "; + public static final String DELETE_METRIC_PROFILE_ENTRY_ERROR_MSG = "Not able to delete metric profile for metric profile {} due to {}"; } } diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java index 7ec7e7d82..79fe0b17f 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java @@ -589,13 +589,13 @@ public ValidationOutputData deleteKruizeMetricProfileEntryByName(String metricPr if (deletedCount == 0) { validationOutputData.setSuccess(false); - validationOutputData.setMessage("KruizeMetricProfileEntry not found with metric profile name: " + metricProfileName); + validationOutputData.setMessage(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.DELETE_METRIC_PROFILE_ENTRY_NOT_FOUND_WITH_NAME + metricProfileName); } else { validationOutputData.setSuccess(true); } tx.commit(); } catch (HibernateException e) { - LOGGER.error("Not able to delete metric profile for metric profile {} due to {}", metricProfileName, e.getMessage()); + LOGGER.error(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.DELETE_METRIC_PROFILE_ENTRY_ERROR_MSG, metricProfileName, e.getMessage()); if (tx != null) tx.rollback(); e.printStackTrace(); validationOutputData.setSuccess(false); @@ -603,7 +603,7 @@ public ValidationOutputData deleteKruizeMetricProfileEntryByName(String metricPr //todo save error to API_ERROR_LOG } } catch (Exception e) { - LOGGER.error("Not able to delete metric profile for metric profile {} due to {}", metricProfileName, e.getMessage()); + LOGGER.error(AnalyzerErrorConstants.APIErrors.DeleteMetricProfileAPI.DELETE_METRIC_PROFILE_ENTRY_ERROR_MSG, metricProfileName, e.getMessage()); } return validationOutputData; } From 00ee31bd2d4d61b6a0b0ae6bb462b6e6d5821d3a Mon Sep 17 00:00:00 2001 From: Shreya Date: Fri, 16 Aug 2024 12:30:47 +0530 Subject: [PATCH 42/77] Remove hardcoded cpu and memory query constants --- .../engine/RecommendationEngine.java | 350 +++++++++--------- .../dataSourceQueries/DataSourceQueries.java | 11 +- .../PromQLDataSourceQueries.java | 9 - 3 files changed, 171 insertions(+), 199 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index f55ce0fd3..754fe1250 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -104,14 +104,6 @@ private static int getNumPods(Map filteredResultsMap * @param promQls The map to be populated with PromQL queries. */ private static void getPromQls(Map promQls) { - promQls.put(AnalyzerConstants.MetricName.cpuUsage, PromQLDataSourceQueries.CPU_USAGE); - promQls.put(AnalyzerConstants.MetricName.cpuThrottle, PromQLDataSourceQueries.CPU_THROTTLE); - promQls.put(AnalyzerConstants.MetricName.cpuLimit, PromQLDataSourceQueries.CPU_LIMIT); - promQls.put(AnalyzerConstants.MetricName.cpuRequest, PromQLDataSourceQueries.CPU_REQUEST); - promQls.put(AnalyzerConstants.MetricName.memoryUsage, PromQLDataSourceQueries.MEMORY_USAGE); - promQls.put(AnalyzerConstants.MetricName.memoryRSS, PromQLDataSourceQueries.MEMORY_RSS); - promQls.put(AnalyzerConstants.MetricName.memoryLimit, PromQLDataSourceQueries.MEMORY_LIMIT); - promQls.put(AnalyzerConstants.MetricName.memoryRequest, PromQLDataSourceQueries.MEMORY_REQUEST); } private void init() { @@ -1443,175 +1435,175 @@ private String getResults(Map mainKruizeExperimentMAP, Kru * @throws Exception if an error occurs during the fetching process. * TODO: Need to add right abstractions for this */ - public void fetchMetricsBasedOnDatasource(KruizeObject kruizeObject, Timestamp interval_end_time, Timestamp interval_start_time, DataSourceInfo dataSourceInfo) throws Exception { - try { - long interval_end_time_epoc = 0; - long interval_start_time_epoc = 0; - SimpleDateFormat sdf = new SimpleDateFormat(KruizeConstants.DateFormats.STANDARD_JSON_DATE_FORMAT, Locale.ROOT); - - // Get MetricsProfile name and list of promQL to fetch - Map promQls = new HashMap<>(); - getPromQls(promQls); - List aggregationMethods = Arrays.asList(KruizeConstants.JSONKeys.SUM, KruizeConstants.JSONKeys.AVG, - KruizeConstants.JSONKeys.MAX, KruizeConstants.JSONKeys.MIN); - Double measurementDurationMinutesInDouble = kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble(); - List kubernetes_objects = kruizeObject.getKubernetes_objects(); - - // Iterate over Kubernetes objects - for (K8sObject k8sObject : kubernetes_objects) { - String namespace = k8sObject.getNamespace(); - HashMap containerDataMap = k8sObject.getContainerDataMap(); - // Iterate over containers - for (Map.Entry entry : containerDataMap.entrySet()) { - ContainerData containerData = entry.getValue(); - String containerName = containerData.getContainer_name(); - if (null == interval_end_time) { - LOGGER.info(KruizeConstants.APIMessages.CONTAINER_USAGE_INFO); - String dateMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATE_ENDPOINT_WITH_QUERY, - dataSourceInfo.getUrl(), - URLEncoder.encode(String.format(PromQLDataSourceQueries.MAX_DATE, containerName, namespace), CHARACTER_ENCODING) - ); - LOGGER.info(dateMetricsUrl); - JSONObject genericJsonObject = new GenericRestApiClient(dateMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); - JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); - JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); - // Process fetched metrics - if (null != resultArray && !resultArray.isEmpty()) { - resultArray = resultArray.get(0) - .getAsJsonObject().getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.VALUE); - long epochTime = resultArray.get(0).getAsLong(); - String timestamp = sdf.format(new Date(epochTime * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC)); - Date date = sdf.parse(timestamp); - Timestamp dateTS = new Timestamp(date.getTime()); - interval_end_time_epoc = dateTS.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC - - ((long) dateTS.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); - int maxDay = Terms.getMaxDays(kruizeObject.getTerms()); - LOGGER.info(KruizeConstants.APIMessages.MAX_DAY, maxDay); - Timestamp startDateTS = Timestamp.valueOf(Objects.requireNonNull(dateTS).toLocalDateTime().minusDays(maxDay)); - interval_start_time_epoc = startDateTS.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC - - ((long) startDateTS.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC); - } - } else { - // Convert timestamps to epoch time - interval_end_time_epoc = interval_end_time.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC - - ((long) interval_end_time.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); - interval_start_time_epoc = interval_start_time.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC - - ((long) interval_start_time.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC); - } - HashMap containerDataResults = new HashMap<>(); - IntervalResults intervalResults; - HashMap resMap; - MetricResults metricResults; - MetricAggregationInfoResults metricAggregationInfoResults; - // Iterate over metrics and aggregation methods - for (Map.Entry metricEntry : promQls.entrySet()) { - for (String methodName : aggregationMethods) { - String promQL = null; - String format = null; - // Determine promQL and format based on metric type - if (metricEntry.getKey() == AnalyzerConstants.MetricName.cpuUsage) { - String secondMethodName = methodName; - if (secondMethodName.equals(KruizeConstants.JSONKeys.SUM)) - secondMethodName = KruizeConstants.JSONKeys.AVG; - promQL = String.format(metricEntry.getValue(), methodName, secondMethodName, namespace, containerName, measurementDurationMinutesInDouble.intValue()); - format = KruizeConstants.JSONKeys.CORES; - } else if (metricEntry.getKey() == AnalyzerConstants.MetricName.cpuThrottle) { - promQL = String.format(metricEntry.getValue(), methodName, namespace, containerName, measurementDurationMinutesInDouble.intValue()); - format = KruizeConstants.JSONKeys.CORES; - } else if (metricEntry.getKey() == AnalyzerConstants.MetricName.cpuLimit || metricEntry.getKey() == AnalyzerConstants.MetricName.cpuRequest) { - promQL = String.format(metricEntry.getValue(), methodName, namespace, containerName); - format = KruizeConstants.JSONKeys.CORES; - } else if (metricEntry.getKey() == AnalyzerConstants.MetricName.memoryUsage || metricEntry.getKey() == AnalyzerConstants.MetricName.memoryRSS) { - String secondMethodName = methodName; - if (secondMethodName.equals(KruizeConstants.JSONKeys.SUM)) - secondMethodName = KruizeConstants.JSONKeys.AVG; - promQL = String.format(metricEntry.getValue(), methodName, secondMethodName, namespace, containerName, measurementDurationMinutesInDouble.intValue()); - format = KruizeConstants.JSONKeys.BYTES; - } else if (metricEntry.getKey() == AnalyzerConstants.MetricName.memoryLimit || metricEntry.getKey() == AnalyzerConstants.MetricName.memoryRequest) { - promQL = String.format(metricEntry.getValue(), methodName, namespace, containerName); - format = KruizeConstants.JSONKeys.BYTES; - } - // If promQL is determined, fetch metrics from the datasource - if (promQL != null) { - LOGGER.info(promQL); - String podMetricsUrl; - try { - podMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATASOURCE_ENDPOINT_WITH_QUERY, - dataSourceInfo.getUrl(), - URLEncoder.encode(promQL, CHARACTER_ENCODING), - interval_start_time_epoc, - interval_end_time_epoc, - measurementDurationMinutesInDouble.intValue() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); - LOGGER.info(podMetricsUrl); - JSONObject genericJsonObject = new GenericRestApiClient(podMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); - JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); - JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); - // Process fetched metrics - if (null != resultArray && !resultArray.isEmpty()) { - resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray( - KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT).get(0) - .getAsJsonObject().getAsJsonArray(KruizeConstants.DataSourceConstants - .DataSourceQueryJSONKeys.VALUES); - sdf.setTimeZone(TimeZone.getTimeZone(KruizeConstants.TimeUnitsExt.TimeZones.UTC)); - - // Iterate over fetched metrics - Timestamp sTime = new Timestamp(interval_start_time_epoc); - for (JsonElement element : resultArray) { - JsonArray valueArray = element.getAsJsonArray(); - long epochTime = valueArray.get(0).getAsLong(); - double value = valueArray.get(1).getAsDouble(); - String timestamp = sdf.format(new Date(epochTime * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC)); - Date date = sdf.parse(timestamp); - Timestamp eTime = new Timestamp(date.getTime()); - - // Prepare interval results - if (containerDataResults.containsKey(eTime)) { - intervalResults = containerDataResults.get(eTime); - resMap = intervalResults.getMetricResultsMap(); - } else { - intervalResults = new IntervalResults(); - resMap = new HashMap<>(); - } - if (resMap.containsKey(metricEntry.getKey())) { - metricResults = resMap.get(metricEntry.getKey()); - metricAggregationInfoResults = metricResults.getAggregationInfoResult(); - } else { - metricResults = new MetricResults(); - metricAggregationInfoResults = new MetricAggregationInfoResults(); - } - Method method = MetricAggregationInfoResults.class.getDeclaredMethod(KruizeConstants.APIMessages.SET + methodName.substring(0, 1).toUpperCase() + methodName.substring(1), Double.class); - method.invoke(metricAggregationInfoResults, value); - metricAggregationInfoResults.setFormat(format); - metricResults.setAggregationInfoResult(metricAggregationInfoResults); - metricResults.setName(String.valueOf(metricEntry.getKey())); - metricResults.setFormat(format); - resMap.put(metricEntry.getKey(), metricResults); - intervalResults.setMetricResultsMap(resMap); - intervalResults.setIntervalStartTime(sTime); //Todo this will change - intervalResults.setIntervalEndTime(eTime); - intervalResults.setDurationInMinutes((double) ((eTime.getTime() - sTime.getTime()) - / ((long) KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE - * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC))); - containerDataResults.put(eTime, intervalResults); - sTime = eTime; - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - } - containerData.setResults(containerDataResults); - if (!containerDataResults.isEmpty()) - setInterval_end_time(Collections.max(containerDataResults.keySet())); //TODO Temp fix invalid date is set if experiment having two container with different last seen date - } - } - } catch (Exception e) { - e.printStackTrace(); - throw new Exception(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.METRIC_EXCEPTION + e.getMessage()); - } - } +// public void fetchMetricsBasedOnDatasource(KruizeObject kruizeObject, Timestamp interval_end_time, Timestamp interval_start_time, DataSourceInfo dataSourceInfo) throws Exception { +// try { +// long interval_end_time_epoc = 0; +// long interval_start_time_epoc = 0; +// SimpleDateFormat sdf = new SimpleDateFormat(KruizeConstants.DateFormats.STANDARD_JSON_DATE_FORMAT, Locale.ROOT); +// +// // Get MetricsProfile name and list of promQL to fetch +// Map promQls = new HashMap<>(); +// getPromQls(promQls); +// List aggregationMethods = Arrays.asList(KruizeConstants.JSONKeys.SUM, KruizeConstants.JSONKeys.AVG, +// KruizeConstants.JSONKeys.MAX, KruizeConstants.JSONKeys.MIN); +// Double measurementDurationMinutesInDouble = kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble(); +// List kubernetes_objects = kruizeObject.getKubernetes_objects(); +// +// // Iterate over Kubernetes objects +// for (K8sObject k8sObject : kubernetes_objects) { +// String namespace = k8sObject.getNamespace(); +// HashMap containerDataMap = k8sObject.getContainerDataMap(); +// // Iterate over containers +// for (Map.Entry entry : containerDataMap.entrySet()) { +// ContainerData containerData = entry.getValue(); +// String containerName = containerData.getContainer_name(); +// if (null == interval_end_time) { +// LOGGER.info(KruizeConstants.APIMessages.CONTAINER_USAGE_INFO); +// String dateMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATE_ENDPOINT_WITH_QUERY, +// dataSourceInfo.getUrl(), +// URLEncoder.encode(String.format(PromQLDataSourceQueries.MAX_DATE, containerName, namespace), CHARACTER_ENCODING) +// ); +// LOGGER.info(dateMetricsUrl); +// JSONObject genericJsonObject = new GenericRestApiClient(dateMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); +// JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); +// JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); +// // Process fetched metrics +// if (null != resultArray && !resultArray.isEmpty()) { +// resultArray = resultArray.get(0) +// .getAsJsonObject().getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.VALUE); +// long epochTime = resultArray.get(0).getAsLong(); +// String timestamp = sdf.format(new Date(epochTime * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC)); +// Date date = sdf.parse(timestamp); +// Timestamp dateTS = new Timestamp(date.getTime()); +// interval_end_time_epoc = dateTS.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC +// - ((long) dateTS.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); +// int maxDay = Terms.getMaxDays(kruizeObject.getTerms()); +// LOGGER.info(KruizeConstants.APIMessages.MAX_DAY, maxDay); +// Timestamp startDateTS = Timestamp.valueOf(Objects.requireNonNull(dateTS).toLocalDateTime().minusDays(maxDay)); +// interval_start_time_epoc = startDateTS.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC +// - ((long) startDateTS.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC); +// } +// } else { +// // Convert timestamps to epoch time +// interval_end_time_epoc = interval_end_time.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC +// - ((long) interval_end_time.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); +// interval_start_time_epoc = interval_start_time.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC +// - ((long) interval_start_time.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC); +// } +// HashMap containerDataResults = new HashMap<>(); +// IntervalResults intervalResults; +// HashMap resMap; +// MetricResults metricResults; +// MetricAggregationInfoResults metricAggregationInfoResults; +// // Iterate over metrics and aggregation methods +// for (Map.Entry metricEntry : promQls.entrySet()) { +// for (String methodName : aggregationMethods) { +// String promQL = null; +// String format = null; +// // Determine promQL and format based on metric type +// if (metricEntry.getKey() == AnalyzerConstants.MetricName.cpuUsage) { +// String secondMethodName = methodName; +// if (secondMethodName.equals(KruizeConstants.JSONKeys.SUM)) +// secondMethodName = KruizeConstants.JSONKeys.AVG; +// promQL = String.format(metricEntry.getValue(), methodName, secondMethodName, namespace, containerName, measurementDurationMinutesInDouble.intValue()); +// format = KruizeConstants.JSONKeys.CORES; +// } else if (metricEntry.getKey() == AnalyzerConstants.MetricName.cpuThrottle) { +// promQL = String.format(metricEntry.getValue(), methodName, namespace, containerName, measurementDurationMinutesInDouble.intValue()); +// format = KruizeConstants.JSONKeys.CORES; +// } else if (metricEntry.getKey() == AnalyzerConstants.MetricName.cpuLimit || metricEntry.getKey() == AnalyzerConstants.MetricName.cpuRequest) { +// promQL = String.format(metricEntry.getValue(), methodName, namespace, containerName); +// format = KruizeConstants.JSONKeys.CORES; +// } else if (metricEntry.getKey() == AnalyzerConstants.MetricName.memoryUsage || metricEntry.getKey() == AnalyzerConstants.MetricName.memoryRSS) { +// String secondMethodName = methodName; +// if (secondMethodName.equals(KruizeConstants.JSONKeys.SUM)) +// secondMethodName = KruizeConstants.JSONKeys.AVG; +// promQL = String.format(metricEntry.getValue(), methodName, secondMethodName, namespace, containerName, measurementDurationMinutesInDouble.intValue()); +// format = KruizeConstants.JSONKeys.BYTES; +// } else if (metricEntry.getKey() == AnalyzerConstants.MetricName.memoryLimit || metricEntry.getKey() == AnalyzerConstants.MetricName.memoryRequest) { +// promQL = String.format(metricEntry.getValue(), methodName, namespace, containerName); +// format = KruizeConstants.JSONKeys.BYTES; +// } +// // If promQL is determined, fetch metrics from the datasource +// if (promQL != null) { +// LOGGER.info(promQL); +// String podMetricsUrl; +// try { +// podMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATASOURCE_ENDPOINT_WITH_QUERY, +// dataSourceInfo.getUrl(), +// URLEncoder.encode(promQL, CHARACTER_ENCODING), +// interval_start_time_epoc, +// interval_end_time_epoc, +// measurementDurationMinutesInDouble.intValue() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); +// LOGGER.info(podMetricsUrl); +// JSONObject genericJsonObject = new GenericRestApiClient(podMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); +// JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); +// JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); +// // Process fetched metrics +// if (null != resultArray && !resultArray.isEmpty()) { +// resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray( +// KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT).get(0) +// .getAsJsonObject().getAsJsonArray(KruizeConstants.DataSourceConstants +// .DataSourceQueryJSONKeys.VALUES); +// sdf.setTimeZone(TimeZone.getTimeZone(KruizeConstants.TimeUnitsExt.TimeZones.UTC)); +// +// // Iterate over fetched metrics +// Timestamp sTime = new Timestamp(interval_start_time_epoc); +// for (JsonElement element : resultArray) { +// JsonArray valueArray = element.getAsJsonArray(); +// long epochTime = valueArray.get(0).getAsLong(); +// double value = valueArray.get(1).getAsDouble(); +// String timestamp = sdf.format(new Date(epochTime * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC)); +// Date date = sdf.parse(timestamp); +// Timestamp eTime = new Timestamp(date.getTime()); +// +// // Prepare interval results +// if (containerDataResults.containsKey(eTime)) { +// intervalResults = containerDataResults.get(eTime); +// resMap = intervalResults.getMetricResultsMap(); +// } else { +// intervalResults = new IntervalResults(); +// resMap = new HashMap<>(); +// } +// if (resMap.containsKey(metricEntry.getKey())) { +// metricResults = resMap.get(metricEntry.getKey()); +// metricAggregationInfoResults = metricResults.getAggregationInfoResult(); +// } else { +// metricResults = new MetricResults(); +// metricAggregationInfoResults = new MetricAggregationInfoResults(); +// } +// Method method = MetricAggregationInfoResults.class.getDeclaredMethod(KruizeConstants.APIMessages.SET + methodName.substring(0, 1).toUpperCase() + methodName.substring(1), Double.class); +// method.invoke(metricAggregationInfoResults, value); +// metricAggregationInfoResults.setFormat(format); +// metricResults.setAggregationInfoResult(metricAggregationInfoResults); +// metricResults.setName(String.valueOf(metricEntry.getKey())); +// metricResults.setFormat(format); +// resMap.put(metricEntry.getKey(), metricResults); +// intervalResults.setMetricResultsMap(resMap); +// intervalResults.setIntervalStartTime(sTime); //Todo this will change +// intervalResults.setIntervalEndTime(eTime); +// intervalResults.setDurationInMinutes((double) ((eTime.getTime() - sTime.getTime()) +// / ((long) KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE +// * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC))); +// containerDataResults.put(eTime, intervalResults); +// sTime = eTime; +// } +// } +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// } +// } +// } +// containerData.setResults(containerDataResults); +// if (!containerDataResults.isEmpty()) +// setInterval_end_time(Collections.max(containerDataResults.keySet())); //TODO Temp fix invalid date is set if experiment having two container with different last seen date +// } +// } +// } catch (Exception e) { +// e.printStackTrace(); +// throw new Exception(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.METRIC_EXCEPTION + e.getMessage()); +// } +// } /** * Fetches metrics based on the specified datasource using queries from the metricProfile for the given time interval. @@ -1661,7 +1653,7 @@ public void fetchMetricsBasedOnProfileAndDatasource(KruizeObject kruizeObject, T String containerName = containerData.getContainer_name(); if (null == interval_end_time) { LOGGER.info(KruizeConstants.APIMessages.CONTAINER_USAGE_INFO); - String queryToEncode; + String queryToEncode = null; if (null != maxDateQuery) { LOGGER.info("maxDateQuery: {}", maxDateQuery); queryToEncode = maxDateQuery @@ -1669,8 +1661,6 @@ public void fetchMetricsBasedOnProfileAndDatasource(KruizeObject kruizeObject, T .replace(AnalyzerConstants.CONTAINER_VARIABLE, containerName) .replace(AnalyzerConstants.WORKLOAD_VARIABLE, workload) .replace(AnalyzerConstants.WORKLOAD_TYPE_VARIABLE, workload_type); - } else { - queryToEncode = String.format(PromQLDataSourceQueries.MAX_DATE, containerName, namespace); } String dateMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATE_ENDPOINT_WITH_QUERY, dataSourceInfo.getUrl(), diff --git a/src/main/java/com/autotune/common/data/dataSourceQueries/DataSourceQueries.java b/src/main/java/com/autotune/common/data/dataSourceQueries/DataSourceQueries.java index be8b758ab..4334a6de0 100644 --- a/src/main/java/com/autotune/common/data/dataSourceQueries/DataSourceQueries.java +++ b/src/main/java/com/autotune/common/data/dataSourceQueries/DataSourceQueries.java @@ -9,16 +9,7 @@ public class DataSourceQueries { public enum PromQLQuery { NAMESPACE_QUERY("sum by (namespace) (kube_namespace_status_phase{phase=\"Active\"})"), WORKLOAD_INFO_QUERY("sum by (namespace, workload, workload_type) (namespace_workload_pod:kube_pod_owner:relabel)"), - CONTAINER_INFO_QUERY("sum by (container, image, workload) (kube_pod_container_info * on(pod) group_left(workload, workload_type) (namespace_workload_pod:kube_pod_owner:relabel))"), - CPU_USAGE("%s by(container, namespace)(%s_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"%s\",container=\"%s\" }[%sm]))"), - CPU_THROTTLE("%s by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"%s\",container=\"%s\"}[%sm]))"), - CPU_LIMIT("%s by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"%s\",container=\"%s\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase='Running'}))"), - CPU_REQUEST("%s by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"%s\",container=\"%s\"} * on(pod, namespace) group_left max by (container, pod, namespace) (kube_pod_status_phase{phase='Running'}))"), - MEMORY_USAGE("%s by(container, namespace) (%s_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"%s\",container=\"%s\" }[%sm]))"), - MEMORY_RSS("%s by(container, namespace) (%s_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"%s\",container=\"%s\"}[%sm]))"), - MEMORY_LIMIT("%s by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte', namespace=\"%s\",container=\"%s\" } * on(pod, namespace) group_left max by (container, pod, namespace) (kube_pod_status_phase{phase='Running'}))"), - MEMORY_REQUEST("%s by(container,namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"%s\",container=\"%s\"} * on(pod, namespace) group_left max by (container, pod, namespace) (kube_pod_status_phase{phase='Running'}))"), - MAX_DATE("max(container_cpu_usage_seconds_total{container=\"%s\",namespace=\"%s\"} > 0)"); + CONTAINER_INFO_QUERY("sum by (container, image, workload) (kube_pod_container_info * on(pod) group_left(workload, workload_type) (namespace_workload_pod:kube_pod_owner:relabel))"); private final String query; PromQLQuery(String query) { diff --git a/src/main/java/com/autotune/common/data/dataSourceQueries/PromQLDataSourceQueries.java b/src/main/java/com/autotune/common/data/dataSourceQueries/PromQLDataSourceQueries.java index 8b4c1d58b..b675239ae 100644 --- a/src/main/java/com/autotune/common/data/dataSourceQueries/PromQLDataSourceQueries.java +++ b/src/main/java/com/autotune/common/data/dataSourceQueries/PromQLDataSourceQueries.java @@ -8,13 +8,4 @@ public class PromQLDataSourceQueries { public static final String NAMESPACE_QUERY = DataSourceQueries.PromQLQuery.NAMESPACE_QUERY.getQuery(); public static final String WORKLOAD_QUERY = DataSourceQueries.PromQLQuery.WORKLOAD_INFO_QUERY.getQuery(); public static final String CONTAINER_QUERY = DataSourceQueries.PromQLQuery.CONTAINER_INFO_QUERY.getQuery(); - public static final String CPU_USAGE = DataSourceQueries.PromQLQuery.CPU_USAGE.getQuery(); - public static final String CPU_THROTTLE = DataSourceQueries.PromQLQuery.CPU_THROTTLE.getQuery(); - public static final String CPU_LIMIT = DataSourceQueries.PromQLQuery.CPU_LIMIT.getQuery(); - public static final String CPU_REQUEST = DataSourceQueries.PromQLQuery.CPU_REQUEST.getQuery(); - public static final String MEMORY_USAGE = DataSourceQueries.PromQLQuery.MEMORY_USAGE.getQuery(); - public static final String MEMORY_RSS = DataSourceQueries.PromQLQuery.MEMORY_RSS.getQuery(); - public static final String MEMORY_LIMIT = DataSourceQueries.PromQLQuery.MEMORY_LIMIT.getQuery(); - public static final String MEMORY_REQUEST = DataSourceQueries.PromQLQuery.MEMORY_REQUEST.getQuery(); - public static final String MAX_DATE = DataSourceQueries.PromQLQuery.MAX_DATE.getQuery(); } From e4ca635a6ec01d58e94d50f42763af62f03d30ee Mon Sep 17 00:00:00 2001 From: Shreya Date: Fri, 16 Aug 2024 17:22:01 +0530 Subject: [PATCH 43/77] Add end-to-end local monitoring test --- tests/scripts/helpers/kruize.py | 18 ++ tests/scripts/helpers/utils.py | 59 +++++ .../json_files/create_tfb_db_exp.json | 28 +++ .../json_files/create_tfb_exp.json | 28 +++ .../test_local_monitoring_e2e_workflow.py | 209 ++++++++++++++++++ 5 files changed, 342 insertions(+) create mode 100644 tests/scripts/local_monitoring_tests/json_files/create_tfb_db_exp.json create mode 100644 tests/scripts/local_monitoring_tests/json_files/create_tfb_exp.json create mode 100644 tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py diff --git a/tests/scripts/helpers/kruize.py b/tests/scripts/helpers/kruize.py index 4b633f6a1..6c6383db2 100644 --- a/tests/scripts/helpers/kruize.py +++ b/tests/scripts/helpers/kruize.py @@ -436,3 +436,21 @@ def list_metric_profiles(name=None, verbose=None, logging=True): print(response.text) print("\n************************************************************") return response + + +# Description: This function generates recommendation for the given experiment_name +def generate_recommendations(experiment_name): + print("\n************************************************************") + print("\nGenerating the recommendation \n for %s..." % ( + experiment_name)) + queryString = "?" + if experiment_name: + queryString = queryString + "experiment_name=%s" % (experiment_name) + + url = URL + "/generateRecommendations%s" % (queryString) + print("URL = ", url) + response = requests.post(url, ) + print("Response status code = ", response.status_code) + print(response.text) + print("\n************************************************************") + return response diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 204d6f442..66a71d7b2 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -1036,3 +1036,62 @@ def validate_duration_in_hours_decimal_precision(duration_in_hours): :return: True if the value has at most two decimal places, False otherwise. """ return re.match(r'^\d+\.\d{3,}$', str(duration_in_hours)) is None + +# clone GitHub repository +def clone_repo(repo_url, target_dir=None): + """ + Clone a Git repository without exiting the program. + + Parameters: + - repo_url: The URL of the Git repository to clone. + - target_dir: Optional target directory to clone the repository into. If not specified, defaults to the repo name. + + Returns: + - True if the repository was successfully cloned, False otherwise. + """ + # Construct the git clone command + clone_command = ["git", "clone", repo_url] + + # If target_dir is specified, add it to the command + if target_dir: + clone_command.append(target_dir) + + try: + # Run the git clone command + print(f"Cloning repository from {repo_url}...") + subprocess.run(clone_command, check=True) + print("Repository cloned successfully.") + return True + except subprocess.CalledProcessError as e: + print(f"Failed to clone the repository: {e}") + return False + + +# Install Benchmarks +def benchmarks_install(namespace="default", manifests="default_manifests"): + + # Change to the benchmarks directory + try: + os.chdir("benchmarks") + except Exception as e: + print(f"ERROR: Could not change to 'benchmarks' directory: {e}") + + print("Installing TechEmpower (Quarkus REST EASY) benchmark into cluster") + + # Change to the techempower directory + try: + os.chdir("techempower") + except Exception as e: + print(f"ERROR: Could not change to 'techempower' directory: {e}") + + + # Apply the Kubernetes manifests + kubectl_command = f"kubectl apply -f manifests/{manifests} -n {namespace}" + result = subprocess.run(kubectl_command, shell=True) + + # Check for errors + if subprocess.call("kubectl get pods | grep -iE 'error|fail|crash'", shell=True) == 0: + print("ERROR: TechEmpower app failed to start, exiting") + + # Navigate back to the original directory + os.chdir("../..") diff --git a/tests/scripts/local_monitoring_tests/json_files/create_tfb_db_exp.json b/tests/scripts/local_monitoring_tests/json_files/create_tfb_db_exp.json new file mode 100644 index 000000000..1f74e2e73 --- /dev/null +++ b/tests/scripts/local_monitoring_tests/json_files/create_tfb_db_exp.json @@ -0,0 +1,28 @@ +[{ + "version": "v2.0", + "experiment_name": "monitor_tfb-db_benchmark", + "cluster_name": "default", + "performance_profile": "resource-optimization-openshift", + "mode": "monitor", + "target_cluster": "local", + "datasource": "prometheus-1", + "kubernetes_objects": [ + { + "type": "deployment", + "name": "tfb-database", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-postgres-openshift:latest", + "container_name": "tfb-database" + } + ] + } + ], + "trial_settings": { + "measurement_duration": "15min" + }, + "recommendation_settings": { + "threshold": "0.1" + } +}] diff --git a/tests/scripts/local_monitoring_tests/json_files/create_tfb_exp.json b/tests/scripts/local_monitoring_tests/json_files/create_tfb_exp.json new file mode 100644 index 000000000..235033810 --- /dev/null +++ b/tests/scripts/local_monitoring_tests/json_files/create_tfb_exp.json @@ -0,0 +1,28 @@ +[{ + "version": "v2.0", + "experiment_name": "monitor_tfb_benchmark", + "cluster_name": "default", + "performance_profile": "resource-optimization-openshift", + "mode": "monitor", + "target_cluster": "local", + "datasource": "prometheus-1", + "kubernetes_objects": [ + { + "type": "deployment", + "name": "tfb-qrh-sample", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server" + } + ] + } + ], + "trial_settings": { + "measurement_duration": "15min" + }, + "recommendation_settings": { + "threshold": "0.1" + } +}] diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py new file mode 100644 index 000000000..234eaf51b --- /dev/null +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py @@ -0,0 +1,209 @@ +""" +Copyright (c) 2024, 2024 Red Hat, IBM Corporation and others. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import copy +import json + +import pytest +import sys +import time +sys.path.append("../../") + +from helpers.fixtures import * +from helpers.generate_rm_jsons import * +from helpers.kruize import * +from helpers.short_term_list_reco_json_schema import * +from helpers.list_reco_json_validate import * +from helpers.list_datasources_json_validate import * +from helpers.utils import * +from helpers.utils import benchmarks_install +from helpers.utils import clone_repo +from helpers.list_metadata_json_validate import * +from helpers.list_metadata_json_schema import * +from helpers.list_metadata_json_verbose_true_schema import * +from helpers.list_metadata_json_cluster_name_without_verbose_schema import * +from helpers.list_metric_profiles_validate import * +from helpers.list_metric_profiles_without_parameters_schema import * +from helpers.short_term_list_reco_json_schema import * +from helpers.list_reco_json_validate import * +from helpers.import_metadata_json_validate import * + + +@pytest.mark.test_e2e +def test_list_recommendations_multiple_exps_for_datasource_workloads(cluster_type): + """ + Test Description: This test validates list recommendations for multiple experiments posted using different json files + """ + clone_repo("https://github.com/kruize/benchmarks") + benchmarks_install() + + # list all datasources + form_kruize_url(cluster_type) + + # Get the datasources name + datasource_name = None + response = list_datasources(datasource_name) + + list_datasources_json = response.json() + + assert response.status_code == SUCCESS_200_STATUS_CODE + + # Validate the json against the json schema + errorMsg = validate_list_datasources_json(list_datasources_json, list_datasources_json_schema) + assert errorMsg == "" + + + # Import datasource metadata + input_json_file = "../json_files/import_metadata.json" + + response = delete_metadata(input_json_file) + print("delete metadata = ", response.status_code) + + # Import metadata using the specified json + response = import_metadata(input_json_file) + metadata_json = response.json() + + # Validate the json against the json schema + errorMsg = validate_import_metadata_json(metadata_json, import_metadata_json_schema) + assert errorMsg == "" + + + # Display metadata from prometheus-1 datasource + json_data = json.load(open(input_json_file)) + datasource = json_data['datasource_name'] + + response = list_metadata(datasource) + + list_metadata_json = response.json() + assert response.status_code == SUCCESS_200_STATUS_CODE + + # Validate the json against the json schema + errorMsg = validate_list_metadata_json(list_metadata_json, list_metadata_json_schema) + assert errorMsg == "" + + + # Display metadata for default namespace + # Currently only default cluster is supported by Kruize + cluster_name = "default" + + response = list_metadata(datasource=datasource, cluster_name=cluster_name, verbose="true") + + list_metadata_json = response.json() + assert response.status_code == SUCCESS_200_STATUS_CODE + + # Validate the json against the json schema + errorMsg = validate_list_metadata_json(list_metadata_json, list_metadata_json_verbose_true_schema) + assert errorMsg == "" + + + # delete tfb experiments + tfb_exp_json_file = "../json_files/create_tfb_exp.json" + tfb_db_exp_json_file = "../json_files/create_tfb_db_exp.json" + + response = delete_experiment(tfb_exp_json_file) + print("delete tfb exp = ", response.status_code) + + response = delete_experiment(tfb_db_exp_json_file) + print("delete tfb_db exp = ", response.status_code) + + #Install default metric profile + metric_profile_json_file = "../json_files/resource_optimization_openshift_metric_profile.json" + response = delete_metric_profile(metric_profile_json_file) + print("delete metric profile = ", response.status_code) + + # Create metric profile using the specified json + response = create_metric_profile(metric_profile_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + + json_file = open(metric_profile_json_file, "r") + input_json = json.loads(json_file.read()) + metric_profile_name = input_json['metadata']['name'] + assert data['message'] == CREATE_METRIC_PROFILE_SUCCESS_MSG % metric_profile_name + + response = list_metric_profiles(name=metric_profile_name, logging=False) + metric_profile_json = response.json() + + assert response.status_code == SUCCESS_200_STATUS_CODE + + # Validate the json against the json schema + errorMsg = validate_list_metric_profiles_json(metric_profile_json, list_metric_profiles_schema) + assert errorMsg == "" + + + # Create tfb experiments using the specified json + response = create_experiment(tfb_exp_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + assert data['message'] == CREATE_EXP_SUCCESS_MSG + + response = create_experiment(tfb_db_exp_json_file) + + data = response.json() + print(data['message']) + + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + assert data['message'] == CREATE_EXP_SUCCESS_MSG + + # Sleep for 3 minutes (180 seconds) + time.sleep(180) + + # generate recommendations + json_file = open(tfb_exp_json_file, "r") + input_json = json.loads(json_file.read()) + tfb_exp_name = input_json[0]['experiment_name'] + + json_file = open(tfb_db_exp_json_file, "r") + input_json = json.loads(json_file.read()) + tfb_db_exp_name = input_json[0]['experiment_name'] + + + response = generate_recommendations(tfb_exp_name) + data = response.json() + print(data) + assert response.status_code == SUCCESS_STATUS_CODE + + # Invoke list recommendations for the specified experiment + response = list_recommendations(tfb_exp_name) + assert response.status_code == SUCCESS_200_STATUS_CODE + list_reco_json = response.json() + + # Validate the json against the json schema + errorMsg = validate_list_reco_json(list_reco_json, list_reco_json_schema) + assert errorMsg == "" + + + response = generate_recommendations(tfb_db_exp_name) + data = response.json() + print(data) + assert response.status_code == SUCCESS_STATUS_CODE + + # Invoke list recommendations for the specified experiment + response = list_recommendations(tfb_db_exp_name) + assert response.status_code == SUCCESS_200_STATUS_CODE + list_reco_json = response.json() + + # Validate the json against the json schema + errorMsg = validate_list_reco_json(list_reco_json, list_reco_json_schema) + assert errorMsg == "" From c4011b70ce519cf62c3473a5f6f93a4103c85c9c Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 19 Aug 2024 16:34:22 +0530 Subject: [PATCH 44/77] Add functions for applying load on workloads --- tests/scripts/helpers/utils.py | 63 ++++++++++++++++++- .../local_monitoring_tests.sh | 2 +- .../local_monitoring_tests/requirements.txt | 1 + .../test_local_monitoring_e2e_workflow.py | 2 + 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 66a71d7b2..4871a63fe 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -20,6 +20,7 @@ import subprocess import time import math +import docker from datetime import datetime, timedelta from kubernetes import client, config @@ -62,7 +63,7 @@ METRIC_PROFILE_EXISTS_MSG = "Validation failed: Metric Profile already exists: %s" METRIC_PROFILE_NOT_FOUND_MSG = "No metric profiles found!" INVALID_LIST_METRIC_PROFILE_INPUT_QUERY = "The query param(s) - [%s] is/are invalid" -LIST_METRIC_PROFILES_INVALID_NAME = "Given metric profile name - %s is not valid" +LIST_METRIC_PROFILES_INVALID_NAME = "Given metric profile name - %s either does not exist or is not valid" CREATE_METRIC_PROFILE_MISSING_MANDATORY_FIELD_MSG = "Validation failed: JSONObject[\"%s\"] not found." CREATE_METRIC_PROFILE_MISSING_MANDATORY_PARAMETERS_MSG = "Validation failed: Missing mandatory parameters: [%s] " @@ -1095,3 +1096,63 @@ def benchmarks_install(namespace="default", manifests="default_manifests"): # Navigate back to the original directory os.chdir("../..") + + +def get_urls(namespace, cluster_type): + kubectl_cmd = f"kubectl -n {namespace}" + + # Get the Techempower port using kubectl + techempower_port_cmd = f"{kubectl_cmd} get svc tfb-qrh-service --no-headers -o=custom-columns=PORT:.spec.ports[*].nodePort" + techempower_port = subprocess.check_output(techempower_port_cmd, shell=True).decode('utf-8').strip() + + # Get the Techempower IP using kubectl + techempower_ip_cmd = f"{kubectl_cmd} get pods -l=app=tfb-qrh-deployment -o wide -o=custom-columns=NODE:.spec.nodeName --no-headers" + techempower_ip = subprocess.check_output(techempower_ip_cmd, shell=True).decode('utf-8').strip() + + + if cluster_type == "minikube": + # Get the minikube IP using the `minikube ip` command + minikube_ip = subprocess.check_output("minikube ip", shell=True).decode('utf-8').strip() + techempower_url = f"http://{minikube_ip}:{techempower_port}" + elif cluster_type == "openshift": + os.environ["TECHEMPOWER_URL"] = f"{techempower_ip}:{techempower_port}" + techempower_url = f"http://{techempower_ip}:{techempower_port}" + else: + raise ValueError("Unsupported CLUSTER_TYPE. Expected 'minikube' or 'openshift'.") + + return techempower_url + + + +def apply_tfb_load(app_namespace, cluster_type): + + print("\n###################################################################") + print(" Starting 20 min background load against the techempower benchmark ") + print("###################################################################\n") + + techempower_load_image = "quay.io/kruizehub/tfb_hyperfoil_load:0.25.2" + load_duration = 1200 # 20 minutes in seconds + + techempower_url = get_urls(app_namespace, cluster_type) + + if cluster_type == "minikube": + techempower_route = techempower_url + elif cluster_type == "openshift": + # Run the `oc status` command and parse the output to get the route + status_cmd = ["oc", "status", "-n", app_namespace] + status_output = subprocess.check_output(status_cmd).decode("utf-8") + for line in status_output.splitlines(): + if "tfb" in line and "port" in line: + techempower_route = line.split(" ")[0].split("/")[2] + break + + + # Run the docker command with subprocess + docker_cmd = [ + "docker", "run", "-d", "--rm", "--network=host", + techempower_load_image, + "/opt/run_hyperfoil_load.sh", techempower_route, + "queries?queries=20", str(load_duration), "1024", "8096" + ] + + subprocess.run(docker_cmd) diff --git a/tests/scripts/local_monitoring_tests/local_monitoring_tests.sh b/tests/scripts/local_monitoring_tests/local_monitoring_tests.sh index a76a2dd3d..3c0dd99b5 100644 --- a/tests/scripts/local_monitoring_tests/local_monitoring_tests.sh +++ b/tests/scripts/local_monitoring_tests/local_monitoring_tests.sh @@ -42,7 +42,7 @@ function local_monitoring_tests() { target="crc" perf_profile_json="${LOCAL_MONITORING_TEST_DIR}/json_files/resource_optimization_openshift.json" - local_monitoring_tests=("sanity" "extended" "negative") + local_monitoring_tests=("sanity" "extended" "negative" "test_e2e") # check if the test case is supported if [ ! -z "${testcase}" ]; then diff --git a/tests/scripts/local_monitoring_tests/requirements.txt b/tests/scripts/local_monitoring_tests/requirements.txt index f3a073a07..0ee4468ac 100644 --- a/tests/scripts/local_monitoring_tests/requirements.txt +++ b/tests/scripts/local_monitoring_tests/requirements.txt @@ -3,3 +3,4 @@ requests jinja2 pytest-html==3.2.0 kubernetes +docker \ No newline at end of file diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py index 234eaf51b..1185ca309 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py @@ -30,6 +30,7 @@ from helpers.utils import * from helpers.utils import benchmarks_install from helpers.utils import clone_repo +from helpers.utils import apply_tfb_load from helpers.list_metadata_json_validate import * from helpers.list_metadata_json_schema import * from helpers.list_metadata_json_verbose_true_schema import * @@ -48,6 +49,7 @@ def test_list_recommendations_multiple_exps_for_datasource_workloads(cluster_typ """ clone_repo("https://github.com/kruize/benchmarks") benchmarks_install() + apply_tfb_load("default", cluster_type) # list all datasources form_kruize_url(cluster_type) From 43f8443bf6648d67c531cda113d9d03c7bbd3463 Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 19 Aug 2024 16:35:06 +0530 Subject: [PATCH 45/77] Update cpu and memory metricProfile queries --- ...optimization_openshift_metric_profile.json | 102 +++++++++++------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json b/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json index fda38b4f3..cd865a65e 100644 --- a/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json +++ b/tests/scripts/local_monitoring_tests/json_files/resource_optimization_openshift_metric_profile.json @@ -21,11 +21,19 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_requests{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"cpu\", unit=\"core\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD ', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" }, { "function": "sum", - "query": "sum by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_requests{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"cpu\", unit=\"core\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='cpu', unit='core' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" } ] }, @@ -37,11 +45,19 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_limits{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"cpu\", unit=\"core\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" }, { "function": "sum", - "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_limits{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"cpu\", unit=\"core\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='cpu', unit='core',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" } ] }, @@ -53,42 +69,42 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time(((irate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[5m])) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\", workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "query": "avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!=\"POD\", pod!=\"\",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))", "version": "<=4.8" }, { "function": "avg", - "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time(((node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "query": "avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))", "version": ">4.9" }, { "function": "min", - "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time(((irate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[5m])) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\", workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "query": "min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!=\"POD\", pod!=\"\",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))", "version": "<=4.8" }, { "function": "min", - "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time(((node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "query": "min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))", "version": ">4.9" }, { "function": "max", - "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time(((irate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[5m])) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\", workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "query": "max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!=\"POD\", pod!=\"\",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))", "version": "<=4.8" }, { "function": "max", - "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time(((node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "query": "max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))", "version": ">4.9" }, { "function": "sum", - "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time(((irate(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[5m])) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\", workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "query": "sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!=\"POD\", pod!=\"\",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))", "version": "<=4.8" }, { "function": "sum", - "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time(((node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))", + "query": "sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))", "version": ">4.9" } ] @@ -101,20 +117,19 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((rate(container_cpu_cfs_throttled_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[15m]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + "query": "avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "max", - "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time((rate(container_cpu_cfs_throttled_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[15m]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "min", - "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time((rate(container_cpu_cfs_throttled_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[15m]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + "query": "min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "sum", - "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((rate(container_cpu_cfs_throttled_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\",container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"}[15m]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" + "query": "sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" } ] }, @@ -126,13 +141,19 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_requests{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"memory\", unit=\"byte\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" - + "query": "avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" }, { "function": "sum", - "query": "sum by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_requests{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"memory\", unit=\"byte\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" - + "query": "sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!='POD', pod!='', resource='memory', unit='byte' ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" } ] }, @@ -144,12 +165,19 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_limits{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"memory\", unit=\"byte\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" + "query": "avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" }, { "function": "sum", - "query": "sum by(container,namespace,workload,workload_type,owner_kind) ((kube_pod_container_resource_limits{container!=\"\", container!=\"POD\", pod!=\"\", resource=\"memory\", unit=\"byte\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod, namespace) group_left max by (container,pod, namespace) (kube_pod_status_phase{phase=\"Running\"}) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m]))))" - + "query": "sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "max", + "query": "max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" + }, + { + "function": "min", + "query": "min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!='POD', pod!='', resource='memory', unit='byte',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})" } ] }, @@ -161,23 +189,19 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((container_memory_working_set_bytes{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "min", - "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time((container_memory_working_set_bytes{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "max", - "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time((container_memory_working_set_bytes{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "sum", - "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((container_memory_working_set_bytes{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" } ] }, @@ -189,23 +213,19 @@ "aggregation_functions": [ { "function": "avg", - "query": "avg by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((container_memory_rss{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "min", - "query": "min by(namespace,container,workload,workload_type,owner_kind) (min_over_time((container_memory_rss{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "max", - "query": "max by(namespace,container,workload,workload_type,owner_kind) (max_over_time((container_memory_rss{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" }, { "function": "sum", - "query": "sum by(namespace,container,workload,workload_type,owner_kind) (avg_over_time((container_memory_rss{container!=\"\", container!=\"POD\", pod!=\"\", container=\"$CONTAINER_NAME$\", namespace=\"$NAMESPACE$\"} * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!=\"\",workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15m])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15m])))[15m:]))" - + "query": "sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!='POD', pod!='',namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))" } ] }, @@ -217,7 +237,7 @@ "aggregation_functions": [ { "function": "max", - "query": "max by(namespace,container,workload,workload_type,owner_kind) (last_over_time((timestamp(container_cpu_usage_seconds_total{container!=\"\", container!=\"POD\", pod!=\"\", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]) * on(pod) group_left(workload, workload_type) max by (pod, workload, workload_type) (max_over_time(namespace_workload_pod:kube_pod_owner:relabel{pod!='',workload=\"$WORKLOAD$\", workload_type=\"$WORKLOAD_TYPE$\"}[15d])) * on(pod) group_left(owner_kind) max by (pod, owner_kind) (max_over_time(kube_pod_owner{pod!=\"\"}[15d])) )" + "query": "max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))" } ] }, From e36b7021fa8b040ccc6bacc8d5a0b92400da356a Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 20 Aug 2024 14:53:30 +0530 Subject: [PATCH 46/77] Add NullPointerException to handle null or empty maxDate query --- .../recommendations/engine/RecommendationEngine.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index 754fe1250..a0da23370 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -1654,14 +1654,18 @@ public void fetchMetricsBasedOnProfileAndDatasource(KruizeObject kruizeObject, T if (null == interval_end_time) { LOGGER.info(KruizeConstants.APIMessages.CONTAINER_USAGE_INFO); String queryToEncode = null; - if (null != maxDateQuery) { + if (null == maxDateQuery || maxDateQuery.isEmpty()) { + throw new NullPointerException("maxDate query cannot be empty or null"); + } + + LOGGER.info("maxDateQuery: {}", maxDateQuery); queryToEncode = maxDateQuery .replace(AnalyzerConstants.NAMESPACE_VARIABLE, namespace) .replace(AnalyzerConstants.CONTAINER_VARIABLE, containerName) .replace(AnalyzerConstants.WORKLOAD_VARIABLE, workload) .replace(AnalyzerConstants.WORKLOAD_TYPE_VARIABLE, workload_type); - } + String dateMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATE_ENDPOINT_WITH_QUERY, dataSourceInfo.getUrl(), URLEncoder.encode(queryToEncode, CHARACTER_ENCODING) From 31fa9751f2cb1a37e5859e7398680f23d43533f0 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 12:05:08 +0530 Subject: [PATCH 47/77] Add missing EOF --- .../analyzer/performanceProfiles/MetricProfileCollection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java b/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java index 75dd92ada..fc0521513 100644 --- a/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java +++ b/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java @@ -72,4 +72,4 @@ public void addMetricProfile(PerformanceProfile metricProfile) { metricProfileCollection.put(metricProfileName, metricProfile); } } -} \ No newline at end of file +} From 4badcae14385c4756f9df1a7fda6de1adc7d50c6 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 12:21:56 +0530 Subject: [PATCH 48/77] Update readme with delete MetricProfile API details --- design/KruizeLocalAPI.md | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/design/KruizeLocalAPI.md b/design/KruizeLocalAPI.md index 6e75a3547..69ceb02b3 100644 --- a/design/KruizeLocalAPI.md +++ b/design/KruizeLocalAPI.md @@ -40,6 +40,11 @@ Documentation still in progress stay tuned. - Example Request and Response - Invalid Scenarios +- [Delete Metric Profile API](#delete-metric-profile-api) + - Introduction + - Example Request and Response + - Invalid Scenarios + - [Create Experiment API](#create-experiment-api) - Introduction - Example Request and Response @@ -2053,6 +2058,46 @@ Returns list of all the metric profile created with all the metric queries
+ + + +### Delete Metric Profile API + +This is quick guide instructions to delete metric profile created as follows. + +**Request Parameters** + +| Parameter | Type | Required | Description | +|-----------|--------|----------|-----------------------------------------| +| name | string | required | The name of the metric profile | + + +**Request with name query parameter** + +`DELETE /deleteMetricProfile` + +`curl -H 'Accept: application/json' http://:/deleteMetricProfile?name=resource-optimization-local-monitoring` + +Deletes the specified metric profile name, provided metric profile already is created + +
+Example Response + +### Example Response + +```json +{ + "message": "Metric profile: resource-optimization-local-monitoring deleted successfully. View Metric Profiles at /listMetricProfiles", + "httpcode": 201, + "documentationLink": "", + "status": "SUCCESS" +} +``` + +
+ +
+ ### Create Experiment API From bb3790c986f727c47ede0bf22cd27e5098c27606 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 14:42:30 +0530 Subject: [PATCH 49/77] Add metric profile in local experiment codeflow --- .../experiment/ExperimentValidation.java | 16 +++++++-- .../analyzer/utils/AnalyzerConstants.java | 4 +++ .../autotune/database/dao/ExperimentDAO.java | 2 ++ .../database/dao/ExperimentDAOImpl.java | 19 ++++++++++ .../database/service/ExperimentDBService.java | 21 +++++++++++ .../com/autotune/operator/KruizeOperator.java | 35 +++++++++++++++++++ 6 files changed, 94 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java b/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java index a3ad10ea5..86420e6d1 100644 --- a/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java +++ b/src/main/java/com/autotune/analyzer/experiment/ExperimentValidation.java @@ -26,6 +26,7 @@ import com.autotune.common.data.result.ContainerData; import com.autotune.common.k8sObjects.K8sObject; import com.autotune.database.service.ExperimentDBService; +import com.autotune.operator.KruizeDeploymentInfo; import com.autotune.operator.KruizeOperator; import com.autotune.utils.KruizeConstants; import org.slf4j.Logger; @@ -105,9 +106,13 @@ public void validate(List kruizeExptList) { errorMsg = AnalyzerErrorConstants.AutotuneObjectErrors.SLO_REDUNDANCY_ERROR; validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); } else { - // fetch the Performance Profile from the DB + // fetch the Performance / Metric Profile from the DB try { - new ExperimentDBService().loadPerformanceProfileFromDBByName(performanceProfilesMap, kruizeObject.getPerformanceProfile()); + if (!KruizeDeploymentInfo.local) { + new ExperimentDBService().loadPerformanceProfileFromDBByName(performanceProfilesMap, kruizeObject.getPerformanceProfile()); + } else { + new ExperimentDBService().loadMetricProfileFromDBByName(performanceProfilesMap, kruizeObject.getPerformanceProfile()); + } } catch (Exception e) { LOGGER.error("Loading saved Performance Profile {} failed: {} ", expName, e.getMessage()); } @@ -122,7 +127,12 @@ public void validate(List kruizeExptList) { errorMsg = AnalyzerErrorConstants.AutotuneObjectErrors.MISSING_SLO_DATA; validationOutputData.setErrorCode(HttpServletResponse.SC_BAD_REQUEST); } else { - String perfProfileName = KruizeOperator.setDefaultPerformanceProfile(kruizeObject.getSloInfo(), mode, target_cluster); + String perfProfileName; + if (!KruizeDeploymentInfo.local) { + perfProfileName = KruizeOperator.setDefaultPerformanceProfile(kruizeObject.getSloInfo(), mode, target_cluster); + } else { + perfProfileName = KruizeOperator.setDefaultMetricProfile(kruizeObject.getSloInfo(), mode, target_cluster); + } kruizeObject.setPerformanceProfile(perfProfileName); proceed = true; } diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index c91f600ea..74d826d8e 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -465,6 +465,10 @@ public static final class PerformanceProfileConstants { public static final String RESOURCE_OPT_OPENSHIFT_PROFILE = "resource-optimization-openshift"; public static final String RESOURCE_OPT_LOCAL_MON_PROFILE = "resource-optimization-local-monitoring"; + //Metric profile constants + public static final String DEFAULT_API_VERSION = "recommender.com/v1"; + public static final String DEFAULT_KIND = "KruizePerformanceProfile"; + public static final Map PerfProfileNames = Map.of( RESOURCE_OPT_OPENSHIFT_PROFILE, "ResourceOptimizationOpenshiftImpl", RESOURCE_OPT_LOCAL_MON_PROFILE, "ResourceOptimizationOpenshiftImpl" diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAO.java b/src/main/java/com/autotune/database/dao/ExperimentDAO.java index bc6dc6055..923a87c60 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAO.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAO.java @@ -63,6 +63,8 @@ public interface ExperimentDAO { // Load a single Performance Profile based on name List loadPerformanceProfileByName(String performanceProfileName) throws Exception; + // Load a single Metric Profile based on name + List loadMetricProfileByName(String metricProfileName) throws Exception; // Load all recommendations of a particular experiment and interval end Time KruizeRecommendationEntry loadRecommendationsByExperimentNameAndDate(String experimentName, String cluster_name, Timestamp interval_end_time) throws Exception; diff --git a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java index 7ffa026af..f10c28a73 100644 --- a/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java +++ b/src/main/java/com/autotune/database/dao/ExperimentDAOImpl.java @@ -798,6 +798,25 @@ public List loadPerformanceProfileByName(String p return entries; } + /** + * Fetches Metric Profile by name from KruizeMetricProfileEntry database table + * @param metricProfileName Metric profile name + * @return List of KruizeMetricProfileEntry objects + * @throws Exception + */ + public List loadMetricProfileByName(String metricProfileName) throws Exception { + String statusValue = "failure"; + Timer.Sample timerLoadMetricProfileName = Timer.start(MetricsConfig.meterRegistry()); + List entries = null; + try (Session session = KruizeHibernateUtil.getSessionFactory().openSession()) { + entries = session.createQuery(DBConstants.SQLQUERY.SELECT_FROM_METRIC_PROFILE_BY_NAME, KruizeMetricProfileEntry.class) + .setParameter("name", metricProfileName).list(); + } catch (Exception e) { + LOGGER.error("Not able to load Metric Profile {} due to {}", metricProfileName, e.getMessage()); + throw new Exception("Error while loading existing metric profile from database due to : " + e.getMessage()); + } + return entries; + } @Override public List getKruizeResultsEntry(String experiment_name, String cluster_name, Timestamp interval_start_time, Timestamp interval_end_time) throws Exception { diff --git a/src/main/java/com/autotune/database/service/ExperimentDBService.java b/src/main/java/com/autotune/database/service/ExperimentDBService.java index 005107ba6..fde6f45cf 100644 --- a/src/main/java/com/autotune/database/service/ExperimentDBService.java +++ b/src/main/java/com/autotune/database/service/ExperimentDBService.java @@ -361,6 +361,27 @@ public void loadPerformanceProfileFromDBByName(Map p } } + /** + * Fetches Metric Profile by name from kruizeMetricProfileEntry + * @param metricProfileMap Map to store metric profile loaded from the database + * @param metricProfileName Metric profile name to be fetched + * @return ValidationOutputData object + */ + public void loadMetricProfileFromDBByName(Map metricProfileMap, String metricProfileName) throws Exception { + List entries = experimentDAO.loadMetricProfileByName(metricProfileName); + if (null != entries && !entries.isEmpty()) { + List metricProfiles = DBHelpers.Converters.KruizeObjectConverters + .convertMetricProfileEntryToMetricProfileObject(entries); + if (!metricProfiles.isEmpty()) { + for (PerformanceProfile performanceProfile : metricProfiles) { + if (null != performanceProfile) { + PerformanceProfileUtil.addMetricProfile(metricProfileMap, performanceProfile); + } + } + } + } + } + public void loadAllExperimentsAndRecommendations(Map mainKruizeExperimentMap) throws Exception { loadAllExperiments(mainKruizeExperimentMap); diff --git a/src/main/java/com/autotune/operator/KruizeOperator.java b/src/main/java/com/autotune/operator/KruizeOperator.java index 61f77da25..9baeb14a9 100644 --- a/src/main/java/com/autotune/operator/KruizeOperator.java +++ b/src/main/java/com/autotune/operator/KruizeOperator.java @@ -40,6 +40,8 @@ import com.autotune.common.variables.Variables; import com.autotune.utils.EventLogger; import com.autotune.utils.KubeEventLogger; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.gson.Gson; import io.fabric8.kubernetes.api.model.Container; import io.fabric8.kubernetes.api.model.ObjectMeta; @@ -451,6 +453,39 @@ public static String setDefaultPerformanceProfile(SloInfo sloInfo, String mode, return performanceProfile.getName(); } + public static String setDefaultMetricProfile(SloInfo sloInfo, String mode, String targetCluster) { + PerformanceProfile metricProfile = null; + try { + String apiVersion = AnalyzerConstants.PerformanceProfileConstants.DEFAULT_API_VERSION; + String kind = AnalyzerConstants.PerformanceProfileConstants.DEFAULT_KIND; + String name = AnalyzerConstants.PerformanceProfileConstants.DEFAULT_PROFILE; + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode metadataNode = objectMapper.createObjectNode(); + metadataNode.put("name",name); + + double profile_version = AnalyzerConstants.DEFAULT_PROFILE_VERSION; + String k8s_type = AnalyzerConstants.DEFAULT_K8S_TYPE; + metricProfile = new PerformanceProfile(apiVersion, kind, metadataNode, profile_version, k8s_type, sloInfo); + + if (null != metricProfile) { + ValidationOutputData validationOutputData = PerformanceProfileUtil.validateAndAddMetricProfile(PerformanceProfilesDeployment.performanceProfilesMap, metricProfile); + if (validationOutputData.isSuccess()) { + LOGGER.info("Added metric Profile : {} into the map with version: {}", + metricProfile.getName(), metricProfile.getProfile_version()); + } else { + new KubeEventLogger(Clock.systemUTC()).log("Failed", validationOutputData.getMessage(), EventLogger.Type.Warning, null, null, null, null); + } + } else { + new KubeEventLogger(Clock.systemUTC()).log("Failed", "Unable to create metric profile ", EventLogger.Type.Warning, null, null, null, null); + } + } catch (Exception e) { + LOGGER.error("Exception while adding Metric profile with message: {} ", e.getMessage()); + new KubeEventLogger(Clock.systemUTC()).log("Failed", e.getMessage(), EventLogger.Type.Warning, null, null, null, null); + return null; + } + return metricProfile.getName(); + } + /** * Parse KruizeLayer JSON and create matching KruizeLayer object * From 3d5c9de586a7c3ed8295fed30eaa5341364388f3 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 15:04:01 +0530 Subject: [PATCH 50/77] Add metric query label constants --- .../com/autotune/analyzer/utils/AnalyzerConstants.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index c91f600ea..dd63a11be 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -63,6 +63,10 @@ public class AnalyzerConstants { public static final String NONE = "none"; public static final String POD_VARIABLE = "$POD$"; public static final String NAMESPACE_VARIABLE = "$NAMESPACE$"; + public static final String CONTAINER_VARIABLE = "$CONTAINER_NAME$"; + public static final String MEASUREMENT_DURATION_IN_MIN_VARAIBLE = "$MEASUREMENT_DURATION_IN_MIN$"; + public static final String WORKLOAD_VARIABLE = "$WORKLOAD$"; + public static final String WORKLOAD_TYPE_VARIABLE = "$WORKLOAD_TYPE$"; public static final String API_VERSION = "apiVersion"; public static final String KIND = "kind"; public static final String RESOURCE_VERSION = "resourceVersion"; @@ -159,7 +163,8 @@ public enum MetricName { memoryRequest, memoryLimit, memoryUsage, - memoryRSS + memoryRSS, + maxDate } public enum K8S_OBJECT_TYPES { From 630771860c87fe844d64b4a9654d0aa20e9417df Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 15:23:13 +0530 Subject: [PATCH 51/77] Add fetchMetricsBasedOnProfileAndDatasource to fetch metric data using MetricProfile --- .../engine/RecommendationEngine.java | 218 +++++++++++++++++- 1 file changed, 216 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index ad06a3d69..b6da95d29 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -2,6 +2,7 @@ import com.autotune.analyzer.kruizeObject.KruizeObject; import com.autotune.analyzer.kruizeObject.RecommendationSettings; +import com.autotune.analyzer.performanceProfiles.PerformanceProfile; import com.autotune.analyzer.plots.PlotManager; import com.autotune.analyzer.recommendations.ContainerRecommendations; import com.autotune.analyzer.recommendations.RecommendationConfigItem; @@ -19,6 +20,8 @@ import com.autotune.analyzer.utils.AnalyzerErrorConstants; import com.autotune.common.data.ValidationOutputData; import com.autotune.common.data.dataSourceQueries.PromQLDataSourceQueries; +import com.autotune.common.data.metrics.AggregationFunctions; +import com.autotune.common.data.metrics.Metric; import com.autotune.common.data.metrics.MetricAggregationInfoResults; import com.autotune.common.data.metrics.MetricResults; import com.autotune.common.data.result.ContainerData; @@ -1423,8 +1426,8 @@ private String getResults(Map mainKruizeExperimentMAP, Kru if (dataSourceInfo == null) { throw new DataSourceNotExist(KruizeConstants.DataSourceConstants.DataSourceErrorMsgs.MISSING_DATASOURCE_INFO); } - // Fetch metrics based on the datasource - fetchMetricsBasedOnDatasource(kruizeObject, interval_end_time, intervalStartTime, dataSourceInfo); + // Fetch metrics dynamically from Metric Profile based on the datasource + fetchMetricsBasedOnProfileAndDatasource(kruizeObject, interval_end_time, intervalStartTime, dataSourceInfo); } return errorMsg; } @@ -1608,4 +1611,215 @@ public void fetchMetricsBasedOnDatasource(KruizeObject kruizeObject, Timestamp i throw new Exception(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.METRIC_EXCEPTION + e.getMessage()); } } + + /** + * Fetches metrics based on the specified datasource using queries from the metricProfile for the given time interval. + * + * @param kruizeObject KruizeObject + * @param interval_end_time The end time of the interval in the format yyyy-MM-ddTHH:mm:sssZ + * @param interval_start_time The start time of the interval in the format yyyy-MM-ddTHH:mm:sssZ. + * @param dataSourceInfo DataSource object + * @throws Exception + */ + public void fetchMetricsBasedOnProfileAndDatasource(KruizeObject kruizeObject, Timestamp interval_end_time, Timestamp interval_start_time, DataSourceInfo dataSourceInfo) throws Exception { + try { + long interval_end_time_epoc = 0; + long interval_start_time_epoc = 0; + SimpleDateFormat sdf = new SimpleDateFormat(KruizeConstants.DateFormats.STANDARD_JSON_DATE_FORMAT, Locale.ROOT); + + String metricProfileName = kruizeObject.getPerformanceProfile(); + PerformanceProfile metricProfile = MetricProfileCollection.getInstance().getMetricProfileCollection().get(metricProfileName); + if (null == metricProfile) { + LOGGER.error("MetricProfile does not exist or is not valid: {}", metricProfileName); + return; + } + + String maxDateQuery = null; + Listmetrics = metricProfile.getSloInfo().getFunctionVariables(); + for (Metric metric: metrics) { + String name = metric.getName(); + if(name.equals("maxDate")){ + String query = metric.getAggregationFunctionsMap().get("max").getQuery(); + maxDateQuery = query; + break; + } + } + + Double measurementDurationMinutesInDouble = kruizeObject.getTrial_settings().getMeasurement_durationMinutes_inDouble(); + List kubernetes_objects = kruizeObject.getKubernetes_objects(); + + // Iterate over Kubernetes objects + for (K8sObject k8sObject : kubernetes_objects) { + String namespace = k8sObject.getNamespace(); + String workload = k8sObject.getName(); + String workload_type = k8sObject.getType(); + HashMap containerDataMap = k8sObject.getContainerDataMap(); + // Iterate over containers + for (Map.Entry entry : containerDataMap.entrySet()) { + ContainerData containerData = entry.getValue(); + String containerName = containerData.getContainer_name(); + if (null == interval_end_time) { + LOGGER.info(KruizeConstants.APIMessages.CONTAINER_USAGE_INFO); + String queryToEncode; + if (null != maxDateQuery) { + LOGGER.info("maxDateQuery: {}", maxDateQuery); + queryToEncode = maxDateQuery + .replace(AnalyzerConstants.NAMESPACE_VARIABLE, namespace) + .replace(AnalyzerConstants.CONTAINER_VARIABLE, containerName) + .replace(AnalyzerConstants.WORKLOAD_VARIABLE, workload) + .replace(AnalyzerConstants.WORKLOAD_TYPE_VARIABLE, workload_type); + } else { + queryToEncode = String.format(PromQLDataSourceQueries.MAX_DATE, containerName, namespace); + } + String dateMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATE_ENDPOINT_WITH_QUERY, + dataSourceInfo.getUrl(), + URLEncoder.encode(queryToEncode, CHARACTER_ENCODING) + ); + LOGGER.info(dateMetricsUrl); + JSONObject genericJsonObject = new GenericRestApiClient(dateMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); + JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); + JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); + // Process fetched metrics + if (null != resultArray && !resultArray.isEmpty()) { + resultArray = resultArray.get(0) + .getAsJsonObject().getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.VALUE); + long epochTime = resultArray.get(0).getAsLong(); + String timestamp = sdf.format(new Date(epochTime * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC)); + Date date = sdf.parse(timestamp); + Timestamp dateTS = new Timestamp(date.getTime()); + interval_end_time_epoc = dateTS.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC + - ((long) dateTS.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); + int maxDay = Terms.getMaxDays(kruizeObject.getTerms()); + LOGGER.info(KruizeConstants.APIMessages.MAX_DAY, maxDay); + Timestamp startDateTS = Timestamp.valueOf(Objects.requireNonNull(dateTS).toLocalDateTime().minusDays(maxDay)); + interval_start_time_epoc = startDateTS.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC + - ((long) startDateTS.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC); + } + } else { + // Convert timestamps to epoch time + interval_end_time_epoc = interval_end_time.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC + - ((long) interval_end_time.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); + interval_start_time_epoc = interval_start_time.getTime() / KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC + - ((long) interval_start_time.getTimezoneOffset() * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC); + } + HashMap containerDataResults = new HashMap<>(); + IntervalResults intervalResults; + HashMap resMap; + HashMap resultMap; + MetricResults metricResults; + MetricAggregationInfoResults metricAggregationInfoResults; + + List metricList = metricProfile.getSloInfo().getFunctionVariables(); + + // Iterate over metrics and aggregation functions + for (Metric metricEntry : metricList) { + HashMap aggregationFunctions = metricEntry.getAggregationFunctionsMap(); + for (Map.Entry aggregationFunctionsEntry: aggregationFunctions.entrySet()) { + // Determine promQL query on metric type + String metricQuery = aggregationFunctionsEntry.getValue().getQuery(); + String promQL = metricQuery; + String format = null; + + + // Determine format based on metric type - Todo move this metric profile + List cpuFunction = Arrays.asList(AnalyzerConstants.MetricName.cpuUsage.toString(), AnalyzerConstants.MetricName.cpuThrottle.toString(), AnalyzerConstants.MetricName.cpuLimit.toString(), AnalyzerConstants.MetricName.cpuRequest.toString()); + List memFunction = Arrays.asList(AnalyzerConstants.MetricName.memoryLimit.toString(), AnalyzerConstants.MetricName.memoryRequest.toString(), AnalyzerConstants.MetricName.memoryRSS.toString(), AnalyzerConstants.MetricName.memoryUsage.toString()); + if (cpuFunction.contains(metricEntry.getName())) { + format = KruizeConstants.JSONKeys.CORES; + } else if (memFunction.contains(metricEntry.getName())) { + format = KruizeConstants.JSONKeys.BYTES; + } + + promQL = promQL + .replace(AnalyzerConstants.NAMESPACE_VARIABLE, namespace) + .replace(AnalyzerConstants.CONTAINER_VARIABLE, containerName) + .replace(AnalyzerConstants.MEASUREMENT_DURATION_IN_MIN_VARAIBLE, Integer.toString(measurementDurationMinutesInDouble.intValue())) + .replace(AnalyzerConstants.WORKLOAD_VARIABLE, workload) + .replace(AnalyzerConstants.WORKLOAD_TYPE_VARIABLE, workload_type); + + // If promQL is determined, fetch metrics from the datasource + if (promQL != null) { + LOGGER.info(promQL); + String podMetricsUrl; + try { + podMetricsUrl = String.format(KruizeConstants.DataSourceConstants.DATASOURCE_ENDPOINT_WITH_QUERY, + dataSourceInfo.getUrl(), + URLEncoder.encode(promQL, CHARACTER_ENCODING), + interval_start_time_epoc, + interval_end_time_epoc, + measurementDurationMinutesInDouble.intValue() * KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE); + LOGGER.info(podMetricsUrl); + JSONObject genericJsonObject = new GenericRestApiClient(podMetricsUrl).fetchMetricsJson(KruizeConstants.APIMessages.GET, ""); + JsonObject jsonObject = new Gson().fromJson(genericJsonObject.toString(), JsonObject.class); + JsonArray resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray(KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT); + // Process fetched metrics + if (null != resultArray && !resultArray.isEmpty()) { + resultArray = jsonObject.getAsJsonObject(KruizeConstants.JSONKeys.DATA).getAsJsonArray( + KruizeConstants.DataSourceConstants.DataSourceQueryJSONKeys.RESULT).get(0) + .getAsJsonObject().getAsJsonArray(KruizeConstants.DataSourceConstants + .DataSourceQueryJSONKeys.VALUES); + sdf.setTimeZone(TimeZone.getTimeZone(KruizeConstants.TimeUnitsExt.TimeZones.UTC)); + + // Iterate over fetched metrics + Timestamp sTime = new Timestamp(interval_start_time_epoc); + for (JsonElement element : resultArray) { + JsonArray valueArray = element.getAsJsonArray(); + long epochTime = valueArray.get(0).getAsLong(); + double value = valueArray.get(1).getAsDouble(); + String timestamp = sdf.format(new Date(epochTime * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC)); + Date date = sdf.parse(timestamp); + Timestamp eTime = new Timestamp(date.getTime()); + + // Prepare interval results + if (containerDataResults.containsKey(eTime)) { + intervalResults = containerDataResults.get(eTime); + resMap = intervalResults.getMetricResultsMap(); + } else { + intervalResults = new IntervalResults(); + resMap = new HashMap<>(); + } + AnalyzerConstants.MetricName metricName = AnalyzerConstants.MetricName.valueOf(metricEntry.getName()); + if (resMap.containsKey(metricName)) { + metricResults = resMap.get(metricName); + metricAggregationInfoResults = metricResults.getAggregationInfoResult(); + } else { + metricResults = new MetricResults(); + metricAggregationInfoResults = new MetricAggregationInfoResults(); + } + + Method method = MetricAggregationInfoResults.class.getDeclaredMethod(KruizeConstants.APIMessages.SET + aggregationFunctionsEntry.getKey().substring(0, 1).toUpperCase() + aggregationFunctionsEntry.getKey().substring(1), Double.class); + method.invoke(metricAggregationInfoResults, value); + metricAggregationInfoResults.setFormat(format); + metricResults.setAggregationInfoResult(metricAggregationInfoResults); + metricResults.setName(metricEntry.getName()); + metricResults.setFormat(format); + resMap.put(metricName, metricResults); + intervalResults.setMetricResultsMap(resMap); + intervalResults.setIntervalStartTime(sTime); //Todo this will change + intervalResults.setIntervalEndTime(eTime); + intervalResults.setDurationInMinutes((double) ((eTime.getTime() - sTime.getTime()) + / ((long) KruizeConstants.TimeConv.NO_OF_SECONDS_PER_MINUTE + * KruizeConstants.TimeConv.NO_OF_MSECS_IN_SEC))); + containerDataResults.put(eTime, intervalResults); + sTime = eTime; + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + } + + containerData.setResults(containerDataResults); + if (!containerDataResults.isEmpty()) + setInterval_end_time(Collections.max(containerDataResults.keySet())); //TODO Temp fix invalid date is set if experiment having two container with different last seen date + + } + } + } catch (Exception e) { + e.printStackTrace(); + throw new Exception(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.METRIC_EXCEPTION + e.getMessage()); + } + } } From 06ba1ffbe2a08b63b5599c07aa0afcb0a622e768 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 15:34:25 +0530 Subject: [PATCH 52/77] Add namespace and GPU metric name constants --- .../autotune/analyzer/utils/AnalyzerConstants.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java index dd63a11be..31fc6f628 100644 --- a/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java +++ b/src/main/java/com/autotune/analyzer/utils/AnalyzerConstants.java @@ -164,7 +164,19 @@ public enum MetricName { memoryLimit, memoryUsage, memoryRSS, - maxDate + maxDate, + namespaceCpuRequest, + namespaceCpuLimit, + namespaceCpuUsage, + namespaceCpuThrottle, + namespaceMemoryRequest, + namespaceMemoryLimit, + namespaceMemoryUsage, + namespaceMemoryRSS, + namespaceTotalPods, + namespaceRunningPods, + gpuCoreUsage, + gpuMemoryUsage } public enum K8S_OBJECT_TYPES { From 499a252423fc857333a78da64b59c990bc4f7d07 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 15:42:27 +0530 Subject: [PATCH 53/77] Update CPU and memory queries in local monitoring manifest --- ...esource_optimization_local_monitoring.yaml | 91 +++++++++++++------ 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/manifests/autotune/performance-profiles/resource_optimization_local_monitoring.yaml b/manifests/autotune/performance-profiles/resource_optimization_local_monitoring.yaml index 1e233720b..fc48f70b7 100644 --- a/manifests/autotune/performance-profiles/resource_optimization_local_monitoring.yaml +++ b/manifests/autotune/performance-profiles/resource_optimization_local_monitoring.yaml @@ -23,12 +23,17 @@ slo: aggregation_functions: - function: 'avg' - query: 'avg(kube_pod_container_resource_requests{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE", resource="cpu", unit="core"})' + query: 'avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core" ,namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' # Show sum of cpu requests in bytes for a container in a deployment - function: 'sum' - query: 'sum(kube_pod_container_resource_requests{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE", resource="cpu", unit="core"})' + query: 'sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core" ,namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' + - function: 'min' + query: 'min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core" ,namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' + + - function: 'max' + query: 'max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core" ,namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' # CPU Limit # Show cpu limits in bytes for a container in a deployment @@ -39,11 +44,17 @@ slo: aggregation_functions: - function: avg - query: 'avg(kube_pod_container_resource_limits{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE", resource="cpu", unit="core"})' + query: 'avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core",namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' # Show sum of cpu limits in bytes for a container in a deployment - function: sum - query: 'sum(kube_pod_container_resource_limits{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE$", resource="cpu", unit="core"})' + query: 'sum by(container,namespace) (kube_pod_container_resource_limits{container!='',container!="", container!="POD", pod!="", resource="cpu", unit="core",namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' + + - function: 'max' + query: 'max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core",namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' + + - function: 'max' + query: 'min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="", container!="POD", pod!="", resource="cpu", unit="core",namespace="$NAMESPACE$",container="$CONTAINER_NAME$"})' # CPU Usage @@ -65,45 +76,45 @@ slo: # For openshift versions <=4.8 aggregation_functions: - function: avg - query: 'avg(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!="POD", pod!="",namespace="$NAMESPACE$",container="$CONTAINER_NAME$" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: "<=4.8" # For openshift versions >=4.9 - function: avg - query: 'avg(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!="POD", pod!="",namespace="$NAMESPACE$",container="$CONTAINER_NAME$" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: ">4.9" # Approx minimum CPU per container in a deployment # For openshift versions <=4.8 - function: min - query: 'min(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: "<=4.8" # For openshift versions >=4.9 - function: min - query: 'min(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'min by(container, namespace)(min_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: ">4.9" # Approx maximum CPU per container in a deployment # For openshift versions <=4.8 - function: max - query: 'max(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: "<=4.8" # For openshift versions >=4.9 - function: max - query: 'max(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'max by(container, namespace)(max_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: ">4.9" # Sum of CPU usage for a container in all pods of a deployment # For openshift versions <=4.8 - function: sum - query: 'sum(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: "<=4.8" # For openshift versions >=4.9 - function: sum - query: 'sum(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container="$CONTAINER_NAME$"}[15m]))' + query: 'sum by(container, namespace)(avg_over_time(node_namespace_pod_container:container_cpu_usage_seconds_total:sum_irate{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m]))' versions: ">4.9" @@ -116,15 +127,19 @@ slo: aggregation_functions: # Average CPU throttling per container in a deployment - function: avg - query: 'avg(rate(container_cpu_cfs_throttled_seconds_total{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Maximum CPU throttling per container in a deployment - function: max - query: 'max(rate(container_cpu_cfs_throttled_seconds_total{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'max by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m])))' + + # Min of CPU throttling for a container in all pods of a deployment + - function: min + query: 'min by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m])' # Sum of CPU throttling for a container in all pods of a deployment - function: sum - query: 'sum(rate(container_cpu_cfs_throttled_seconds_total{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace="$NAMESPACE$", container=”$CONTAINER_NAME$”}[15m]))' + query: 'sum by(container,namespace) (rate(container_cpu_cfs_throttled_seconds_total{container!='', container!="POD", pod!="",namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' @@ -139,11 +154,17 @@ slo: aggregation_functions: - function: avg - query: 'avg(kube_pod_container_resource_requests{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource="memory", unit="byte"})' + query: 'avg by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' # Show sum of memory requests in bytes for a container in a deployment - function: sum - query: 'sum(kube_pod_container_resource_requests{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource="memory", unit="byte"})' + query: 'sum by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' + + - function: max + query: 'max by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' + + - function: min + query: 'min by(container, namespace) (kube_pod_container_resource_requests{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' # Memory Limit @@ -155,12 +176,17 @@ slo: aggregation_functions: - function: avg - query: 'avg(kube_pod_container_resource_limits{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container="$CONTAINER_NAME$", namespace="$NAMESPACE", resource="memory", unit="byte"})' + query: 'avg by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' # Show sum of memory limits in bytes for a container in a deployment - function: sum - query: 'sum(kube_pod_container_resource_limits{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", container=”$CONTAINER_NAME$”, namespace=”$NAMESPACE”, resource="memory", unit="byte"})' + query: 'sum by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' + + - function: max + query: 'max by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' + - function: min + query: 'min by(container,namespace) (kube_pod_container_resource_limits{container!='', container!="POD", pod!="", resource="memory", unit="byte" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"})' # Memory Usage # Average memory per container in a deployment @@ -171,19 +197,19 @@ slo: aggregation_functions: - function: avg - query: 'avg(avg_over_time(container_memory_working_set_bytes{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!="POD", pod!="", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Approx minimum memory per container in a deployment - function: min - query: 'min(min_over_time(container_memory_working_set_bytes{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'min by(container, namespace) (min_over_time(container_memory_working_set_bytes{container!='', container!="POD", pod!="", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\" }[$MEASUREMENT_DURATION_IN_MIN$m])' # Approx maximum memory per container in a deployment - function: max - query: 'max(max_over_time(container_memory_working_set_bytes{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'max by(container, namespace) (max_over_time(container_memory_working_set_bytes{container!='', container!="POD", pod!="", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Sum of memory usage for a contianer in all pods of a deployment - function: sum - query: 'sum(avg_over_time(container_memory_working_set_bytes{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'sum by(container, namespace) (avg_over_time(container_memory_working_set_bytes{container!='', container!="POD", pod!="", namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # 2.4 Memory RSS @@ -195,17 +221,28 @@ slo: aggregation_functions: # Average memory RSS per container in a deployment - function: avg - query: 'avg(avg_over_time(container_memory_rss{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))' + query: 'avg by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!="POD", pod!="" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Approx minimum memory RSS per container in a deployment - function: min - query: 'min(min_over_time(container_memory_rss{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'min by(container, namespace) (min_over_time(container_memory_rss{container!='', container!="POD", pod!="" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m])' # Approx maximum memory RSS per container in a deployment - function: max - query: 'max(max_over_time(container_memory_rss{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container="$CONTAINER_NAME$"}[15m]))' + query: 'max by(container, namespace) (max_over_time(container_memory_rss{container!='', container!="POD", pod!="" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' # Sum of memory RSS for a contianer in all pods of a deployment - function: sum - query: 'sum(avg_over_time(container_memory_rss{pod=~"$DEPLOYMENT_NAME$-[^-]*-[^-]*$", namespace=$NAMESPACE$, container=”$CONTAINER_NAME$”}[15m]))' + query: 'sum by(container, namespace) (avg_over_time(container_memory_rss{container!='', container!="POD", pod!="" ,namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"}[$MEASUREMENT_DURATION_IN_MIN$m]))' + + + # Container Last Active Timestamp + - name: maxDate + datasource: prometheus + value_type: "double" + kubernetes_object: "container" + + aggregation_functions: + - function: max + query: 'max by(namespace,container) (last_over_time((timestamp(container_cpu_usage_seconds_total{namespace=\"$NAMESPACE$\",container=\"$CONTAINER_NAME$\"} > 0))[15d:]))' \ No newline at end of file From ca66fce41bcf33d3bf3d639856d57b1ae11cd5b8 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 17:47:43 +0530 Subject: [PATCH 54/77] Add docker module for remote monitoring tests --- tests/scripts/remote_monitoring_tests/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/scripts/remote_monitoring_tests/requirements.txt b/tests/scripts/remote_monitoring_tests/requirements.txt index f3a073a07..520276e87 100644 --- a/tests/scripts/remote_monitoring_tests/requirements.txt +++ b/tests/scripts/remote_monitoring_tests/requirements.txt @@ -3,3 +3,4 @@ requests jinja2 pytest-html==3.2.0 kubernetes +docker From eccad476354e446066bae3b0eced19038f01f745 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 15:27:24 +0530 Subject: [PATCH 55/77] Add metric profile in-memory collection --- .../MetricProfileCollection.java | 75 +++++++++++++++++++ .../services/MetricProfileService.java | 5 ++ .../com/autotune/utils/KruizeConstants.java | 9 +++ 3 files changed, 89 insertions(+) create mode 100644 src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java diff --git a/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java b/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java new file mode 100644 index 000000000..75dd92ada --- /dev/null +++ b/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2024, 2024 Red Hat, IBM Corporation and others. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package com.autotune.analyzer.performanceProfiles; + +import com.autotune.database.service.ExperimentDBService; +import com.autotune.utils.KruizeConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +public class MetricProfileCollection { + private static final Logger LOGGER = LoggerFactory.getLogger(MetricProfileCollection.class); + private static MetricProfileCollection metricProfileCollectionInstance = new MetricProfileCollection(); + private HashMap metricProfileCollection; + + private MetricProfileCollection() { + this.metricProfileCollection = new HashMap<>(); + } + + public static MetricProfileCollection getInstance() { + return metricProfileCollectionInstance; + } + + public HashMap getMetricProfileCollection() { + return metricProfileCollection; + } + + public void loadMetricProfilesFromDB() { + try { + LOGGER.info(KruizeConstants.MetricProfileConstants.CHECKING_AVAILABLE_METRIC_PROFILE_FROM_DB); + Map availableMetricProfiles = new HashMap<>(); + new ExperimentDBService().loadAllMetricProfiles(availableMetricProfiles); + if (availableMetricProfiles.isEmpty()) { + LOGGER.info(KruizeConstants.MetricProfileConstants.NO_METRIC_PROFILE_FOUND_IN_DB); + }else { + for (Map.Entry metricProfile : availableMetricProfiles.entrySet()) { + LOGGER.info(KruizeConstants.MetricProfileConstants.METRIC_PROFILE_FOUND, metricProfile.getKey()); + metricProfileCollection.put(metricProfile.getKey(), metricProfile.getValue()); + } + } + + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + } + + + public void addMetricProfile(PerformanceProfile metricProfile) { + String metricProfileName = metricProfile.getMetadata().get("name").asText(); + + LOGGER.info(KruizeConstants.MetricProfileConstants.ADDING_METRIC_PROFILE + "{}", metricProfileName); + + if(metricProfileCollection.containsKey(metricProfileName)) { + LOGGER.error(KruizeConstants.MetricProfileConstants.METRIC_PROFILE_ALREADY_EXISTS + "{}", metricProfileName); + } else { + LOGGER.info(KruizeConstants.MetricProfileConstants.METRIC_PROFILE_ADDED + "{}", metricProfileName); + metricProfileCollection.put(metricProfileName, metricProfile); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java index af66bf6f3..217c21f79 100644 --- a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java +++ b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java @@ -18,6 +18,7 @@ import com.autotune.analyzer.exceptions.InvalidValueException; import com.autotune.analyzer.exceptions.PerformanceProfileResponse; +import com.autotune.analyzer.performanceProfiles.MetricProfileCollection; import com.autotune.analyzer.performanceProfiles.PerformanceProfile; import com.autotune.analyzer.performanceProfiles.utils.PerformanceProfileUtil; import com.autotune.analyzer.serviceObjects.Converters; @@ -91,6 +92,10 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) getServletContext().setAttribute(AnalyzerConstants.PerformanceProfileConstants.METRIC_PROFILE_MAP, metricProfilesMap); LOGGER.debug(KruizeConstants.MetricProfileAPIMessages.ADD_METRIC_PROFILE_TO_DB_WITH_VERSION, metricProfile.getMetadata().get("name").asText(), metricProfile.getProfile_version()); + // Store metric profile in-memory collection + MetricProfileCollection metricProfileCollection = MetricProfileCollection.getInstance(); + metricProfileCollection.addMetricProfile(metricProfile); + sendSuccessResponse(response, String.format(KruizeConstants.MetricProfileAPIMessages.CREATE_METRIC_PROFILE_SUCCESS_MSG, metricProfile.getMetadata().get("name").asText())); } else { sendErrorResponse(response, null, HttpServletResponse.SC_BAD_REQUEST, addedToDB.getMessage()); diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index fad1f73ca..9c28c9428 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -73,6 +73,15 @@ public static class MetricProfileAPIMessages { public static final String ADD_METRIC_PROFILE_TO_DB_WITH_VERSION = "Added Metric Profile : {} into the DB with version: {}"; } + public static class MetricProfileConstants { + public static final String CHECKING_AVAILABLE_METRIC_PROFILE_FROM_DB = "Checking available metric profiles from database: "; + public static final String NO_METRIC_PROFILE_FOUND_IN_DB = "No metric profile found in database."; + public static final String METRIC_PROFILE_FOUND = "MetricProfile found: "; + public static final String ADDING_METRIC_PROFILE = "Trying to add the metric profile to collection: "; + public static final String METRIC_PROFILE_ALREADY_EXISTS = "MetricProfile already exists: "; + public static final String METRIC_PROFILE_ADDED = "MetricProfile added to the collection successfully: "; + } + /** * Holds the constants of env vars and values to start Autotune in different Modes */ From 50edaba1b74c07d4f37e961ec956ed609119fdf3 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 13 Aug 2024 15:33:06 +0530 Subject: [PATCH 56/77] Load available metric profiles during autotune initialization --- src/main/java/com/autotune/Autotune.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/autotune/Autotune.java b/src/main/java/com/autotune/Autotune.java index b6247c035..ad6ad9834 100644 --- a/src/main/java/com/autotune/Autotune.java +++ b/src/main/java/com/autotune/Autotune.java @@ -20,6 +20,7 @@ import com.autotune.analyzer.exceptions.KruizeErrorHandler; import com.autotune.analyzer.exceptions.MonitoringAgentNotFoundException; import com.autotune.analyzer.exceptions.MonitoringAgentNotSupportedException; +import com.autotune.analyzer.performanceProfiles.MetricProfileCollection; import com.autotune.analyzer.utils.AnalyzerConstants; import com.autotune.common.datasource.DataSourceCollection; import com.autotune.common.datasource.DataSourceInfo; @@ -114,6 +115,8 @@ public static void main(String[] args) { setUpDataSources(); // checking available DataSources checkAvailableDataSources(); + // load available metric profiles from db + loadMetricProfilesFromDB(); } // close the existing session factory before recreating @@ -195,6 +198,14 @@ private static void checkAvailableDataSources() { } } + /** + * loads metric profiles from database + */ + private static void loadMetricProfilesFromDB() { + MetricProfileCollection metricProfileCollection = MetricProfileCollection.getInstance(); + metricProfileCollection.loadMetricProfilesFromDB(); + } + private static void addAutotuneServlets(ServletContextHandler context) { context.addServlet(HealthService.class, HEALTH_SERVICE); // Start the Prometheus end point (/metrics) for Autotune From 8d8d4564d140f993b3eb65cbeedbe00820953d14 Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 11:51:50 +0530 Subject: [PATCH 57/77] Add missing EOF --- .../analyzer/performanceProfiles/MetricProfileCollection.java | 2 +- .../com/autotune/analyzer/services/MetricProfileService.java | 2 +- .../com/autotune/database/table/KruizeMetricProfileEntry.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java b/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java index 75dd92ada..fc0521513 100644 --- a/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java +++ b/src/main/java/com/autotune/analyzer/performanceProfiles/MetricProfileCollection.java @@ -72,4 +72,4 @@ public void addMetricProfile(PerformanceProfile metricProfile) { metricProfileCollection.put(metricProfileName, metricProfile); } } -} \ No newline at end of file +} diff --git a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java index 217c21f79..7701cca17 100644 --- a/src/main/java/com/autotune/analyzer/services/MetricProfileService.java +++ b/src/main/java/com/autotune/analyzer/services/MetricProfileService.java @@ -245,4 +245,4 @@ public void sendErrorResponse(HttpServletResponse response, Exception e, int htt } response.sendError(httpStatusCode, errorMsg); } -} \ No newline at end of file +} diff --git a/src/main/java/com/autotune/database/table/KruizeMetricProfileEntry.java b/src/main/java/com/autotune/database/table/KruizeMetricProfileEntry.java index ef6dc2953..2b0f539be 100644 --- a/src/main/java/com/autotune/database/table/KruizeMetricProfileEntry.java +++ b/src/main/java/com/autotune/database/table/KruizeMetricProfileEntry.java @@ -104,4 +104,4 @@ public JsonNode getSlo() { public void setSlo(JsonNode slo) { this.slo = slo; } -} \ No newline at end of file +} From 30b3ba7f4664a652c6c11da8e7b3f29fc597249d Mon Sep 17 00:00:00 2001 From: Shreya Date: Thu, 22 Aug 2024 20:45:02 +0530 Subject: [PATCH 58/77] Add blocking wait for load to complete --- tests/scripts/helpers/utils.py | 37 +++++++++++++++++-- .../test_local_monitoring_e2e_workflow.py | 8 ++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 4871a63fe..27304bcd9 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -1127,11 +1127,11 @@ def get_urls(namespace, cluster_type): def apply_tfb_load(app_namespace, cluster_type): print("\n###################################################################") - print(" Starting 20 min background load against the techempower benchmark ") + print(" Starting 10 min background load against the techempower benchmark ") print("###################################################################\n") techempower_load_image = "quay.io/kruizehub/tfb_hyperfoil_load:0.25.2" - load_duration = 1200 # 20 minutes in seconds + load_duration = 600 # 10 minutes in seconds techempower_url = get_urls(app_namespace, cluster_type) @@ -1155,4 +1155,35 @@ def apply_tfb_load(app_namespace, cluster_type): "queries?queries=20", str(load_duration), "1024", "8096" ] - subprocess.run(docker_cmd) + # Run the Docker command and get the container ID + process = subprocess.Popen(docker_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + container_id = process.stdout.read().decode().strip() + + if not container_id: + raise RuntimeError(f"Failed to start Docker container. Error: {process.stderr.read().decode().strip()}") + + return container_id + +# Retrieve the status of the Docker container. +def get_container_status(container_id): + result = subprocess.run( + ["docker", "inspect", "--format", "{{.State.Status}}", container_id], + capture_output=True, + text=True + ) + status = result.stdout.strip() + return status + +# Wait until the Docker container completes and get its exit code. +def wait_for_container_to_complete(container_id): + + print("\n########################################################################################################") + print(f"Waiting for container {container_id} to complete... before generating recommendations") + print("##########################################################################################################\n") + result = subprocess.run( + ["docker", "wait", container_id], + capture_output=True, + text=True + ) + exit_code = result.stdout.strip() + print(f"Container {container_id} has completed with exit code {exit_code}.") diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py index 1185ca309..d97141cb3 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py @@ -31,6 +31,7 @@ from helpers.utils import benchmarks_install from helpers.utils import clone_repo from helpers.utils import apply_tfb_load +from helpers.utils import wait_for_container_to_complete from helpers.list_metadata_json_validate import * from helpers.list_metadata_json_schema import * from helpers.list_metadata_json_verbose_true_schema import * @@ -49,7 +50,8 @@ def test_list_recommendations_multiple_exps_for_datasource_workloads(cluster_typ """ clone_repo("https://github.com/kruize/benchmarks") benchmarks_install() - apply_tfb_load("default", cluster_type) + container_id = apply_tfb_load("default", cluster_type) + print(container_id) # list all datasources form_kruize_url(cluster_type) @@ -168,8 +170,8 @@ def test_list_recommendations_multiple_exps_for_datasource_workloads(cluster_typ assert data['status'] == SUCCESS_STATUS assert data['message'] == CREATE_EXP_SUCCESS_MSG - # Sleep for 3 minutes (180 seconds) - time.sleep(180) + # Wait for the container to complete + wait_for_container_to_complete(container_id) # generate recommendations json_file = open(tfb_exp_json_file, "r") From 6689766a06ba3c80fa1efac1050c75a973922f84 Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 26 Aug 2024 11:04:30 +0530 Subject: [PATCH 59/77] Cleanup experiments and metric profile after validatiion --- .../test_local_monitoring_e2e_workflow.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py index d97141cb3..de96edba6 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py @@ -211,3 +211,18 @@ def test_list_recommendations_multiple_exps_for_datasource_workloads(cluster_typ # Validate the json against the json schema errorMsg = validate_list_reco_json(list_reco_json, list_reco_json_schema) assert errorMsg == "" + + # Delete tfb experiment + response = delete_experiment(tfb_exp_json_file) + print("delete exp = ", response.status_code) + assert response.status_code == SUCCESS_STATUS_CODE + + # Delete tfb_db experiment + response = delete_experiment(tfb_db_exp_json_file) + print("delete exp = ", response.status_code) + assert response.status_code == SUCCESS_STATUS_CODE + + # Delete Metric Profile + response = delete_metric_profile(metric_profile_json_file) + print("delete metric profile = ", response.status_code) + assert response.status_code == SUCCESS_STATUS_CODE From 705b2b52cc1120677ef1599b94aa4d806583fd22 Mon Sep 17 00:00:00 2001 From: Chandrakala Subramanyam Date: Mon, 26 Aug 2024 12:20:36 +0530 Subject: [PATCH 60/77] Bump mvp release to 0.0.24_mvp Signed-off-by: Chandrakala Subramanyam --- .../BYODB-installation/minikube/kruize-crc-minikube.yaml | 4 ++-- .../openshift/kruize-crc-openshift.yaml | 6 +++--- .../minikube/kruize-crc-minikube.yaml | 8 ++++---- .../openshift/kruize-crc-openshift.yaml | 8 ++++---- pom.xml | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifests/crc/BYODB-installation/minikube/kruize-crc-minikube.yaml b/manifests/crc/BYODB-installation/minikube/kruize-crc-minikube.yaml index 9b4d8c165..ff5c09140 100644 --- a/manifests/crc/BYODB-installation/minikube/kruize-crc-minikube.yaml +++ b/manifests/crc/BYODB-installation/minikube/kruize-crc-minikube.yaml @@ -90,7 +90,7 @@ spec: done containers: - name: kruize - image: kruize/autotune_operator:0.0.23_rm + image: kruize/autotune_operator:0.0.24_rm imagePullPolicy: Always volumeMounts: - name: config-volume @@ -213,7 +213,7 @@ metadata: spec: containers: - name: kruize-ui-nginx-container - image: quay.io/kruize/kruize-ui:0.0.4 + image: quay.io/kruize/kruize-ui:0.0.5 imagePullPolicy: Always env: - name: KRUIZE_UI_ENV diff --git a/manifests/crc/BYODB-installation/openshift/kruize-crc-openshift.yaml b/manifests/crc/BYODB-installation/openshift/kruize-crc-openshift.yaml index 34a890a8d..565c98815 100644 --- a/manifests/crc/BYODB-installation/openshift/kruize-crc-openshift.yaml +++ b/manifests/crc/BYODB-installation/openshift/kruize-crc-openshift.yaml @@ -90,7 +90,7 @@ spec: done containers: - name: kruize - image: kruize/autotune_operator:0.0.23_rm + image: kruize/autotune_operator:0.0.24_rm imagePullPolicy: Always volumeMounts: - name: config-volume @@ -220,7 +220,7 @@ metadata: spec: containers: - name: kruize-ui-nginx-container - image: quay.io/kruize/kruize-ui:0.0.4 + image: quay.io/kruize/kruize-ui:0.0.5 imagePullPolicy: Always env: - name: KRUIZE_UI_ENV @@ -245,4 +245,4 @@ subjects: roleRef: kind: ClusterRole name: cluster-monitoring-view - apiGroup: rbac.authorization.k8s.io \ No newline at end of file + apiGroup: rbac.authorization.k8s.io diff --git a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml index 572edd19c..086d7e1d8 100644 --- a/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml +++ b/manifests/crc/default-db-included-installation/minikube/kruize-crc-minikube.yaml @@ -177,7 +177,7 @@ spec: done containers: - name: kruize - image: quay.io/kruize/autotune_operator:0.0.23_rm + image: quay.io/kruize/autotune_operator:0.0.24_rm imagePullPolicy: Always volumeMounts: - name: config-volume @@ -242,7 +242,7 @@ spec: spec: containers: - name: kruizecronjob - image: kruize/autotune_operator:0.0.23_rm + image: kruize/autotune_operator:0.0.24_rm imagePullPolicy: Always volumeMounts: - name: config-volume @@ -341,7 +341,7 @@ metadata: spec: containers: - name: kruize-ui-nginx-container - image: quay.io/kruize/kruize-ui:0.0.4 + image: quay.io/kruize/kruize-ui:0.0.5 imagePullPolicy: Always env: - name: KRUIZE_UI_ENV @@ -368,7 +368,7 @@ spec: spec: containers: - name: kruizedeletejob - image: kruize/autotune_operator:0.0.23_rm + image: kruize/autotune_operator:0.0.24_rm imagePullPolicy: Always volumeMounts: - name: config-volume diff --git a/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml b/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml index f97571933..6b034964c 100644 --- a/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml +++ b/manifests/crc/default-db-included-installation/openshift/kruize-crc-openshift.yaml @@ -223,7 +223,7 @@ spec: done containers: - name: kruize - image: kruize/autotune_operator:0.0.23_rm + image: kruize/autotune_operator:0.0.24_rm imagePullPolicy: Always volumeMounts: - name: config-volume @@ -295,7 +295,7 @@ spec: spec: containers: - name: kruizecronjob - image: kruize/autotune_operator:0.0.23_rm + image: kruize/autotune_operator:0.0.24_rm imagePullPolicy: Always volumeMounts: - name: config-volume @@ -336,7 +336,7 @@ spec: spec: containers: - name: kruizedeletejob - image: kruize/autotune_operator:0.0.23_rm + image: kruize/autotune_operator:0.0.24_rm imagePullPolicy: Always volumeMounts: - name: config-volume @@ -437,7 +437,7 @@ metadata: spec: containers: - name: kruize-ui-nginx-container - image: quay.io/kruize/kruize-ui:0.0.4 + image: quay.io/kruize/kruize-ui:0.0.5 imagePullPolicy: Always env: - name: KRUIZE_UI_ENV diff --git a/pom.xml b/pom.xml index d22b8c669..e3feae103 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.autotune autotune - 0.0.23_mvp + 0.0.24_mvp 4.13.2 20240303 From 813a2c23cd4c559136f83a8bb287e2611fb59841 Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 26 Aug 2024 17:41:16 +0530 Subject: [PATCH 61/77] Update the load time to 20mins --- tests/scripts/helpers/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 27304bcd9..fcc954d30 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -1127,11 +1127,11 @@ def get_urls(namespace, cluster_type): def apply_tfb_load(app_namespace, cluster_type): print("\n###################################################################") - print(" Starting 10 min background load against the techempower benchmark ") + print(" Starting 20 min background load against the techempower benchmark ") print("###################################################################\n") techempower_load_image = "quay.io/kruizehub/tfb_hyperfoil_load:0.25.2" - load_duration = 600 # 10 minutes in seconds + load_duration = 1200 # 20 minutes in seconds techempower_url = get_urls(app_namespace, cluster_type) From e95b4211a919b116108d905675eddb68e5bea6a4 Mon Sep 17 00:00:00 2001 From: Shreya Date: Mon, 26 Aug 2024 17:48:57 +0530 Subject: [PATCH 62/77] Add missing EOF --- tests/scripts/local_monitoring_tests/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/local_monitoring_tests/requirements.txt b/tests/scripts/local_monitoring_tests/requirements.txt index 0ee4468ac..520276e87 100644 --- a/tests/scripts/local_monitoring_tests/requirements.txt +++ b/tests/scripts/local_monitoring_tests/requirements.txt @@ -3,4 +3,4 @@ requests jinja2 pytest-html==3.2.0 kubernetes -docker \ No newline at end of file +docker From 2441167af66daa0f89856e70b852e28a9ea79af8 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 27 Aug 2024 15:49:57 +0530 Subject: [PATCH 63/77] Expose tfb svc to access techempower_url --- tests/scripts/helpers/utils.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index fcc954d30..b8f970169 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -1115,8 +1115,21 @@ def get_urls(namespace, cluster_type): minikube_ip = subprocess.check_output("minikube ip", shell=True).decode('utf-8').strip() techempower_url = f"http://{minikube_ip}:{techempower_port}" elif cluster_type == "openshift": - os.environ["TECHEMPOWER_URL"] = f"{techempower_ip}:{techempower_port}" - techempower_url = f"http://{techempower_ip}:{techempower_port}" + # expose service kruize + subprocess.run(['oc -n openshift-tuning expose service kruize'], shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, text=True) + + # annotate kruize route + subprocess.run(['oc -n openshift-tuning annotate route kruize --overwrite haproxy.router.openshift.io/timeout=60s'], + shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + + # expose service tfb-qrh-service + subprocess.run(['oc -n default expose service tfb-qrh-service'], shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, text=True) + + # get tfb-qrh-service route + techempower_url = subprocess.run([f'oc -n {namespace} get route tfb-qrh-service --no-headers -o custom-columns=NODE:.spec.host'], + shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) else: raise ValueError("Unsupported CLUSTER_TYPE. Expected 'minikube' or 'openshift'.") @@ -1138,13 +1151,8 @@ def apply_tfb_load(app_namespace, cluster_type): if cluster_type == "minikube": techempower_route = techempower_url elif cluster_type == "openshift": - # Run the `oc status` command and parse the output to get the route - status_cmd = ["oc", "status", "-n", app_namespace] - status_output = subprocess.check_output(status_cmd).decode("utf-8") - for line in status_output.splitlines(): - if "tfb" in line and "port" in line: - techempower_route = line.split(" ")[0].split("/")[2] - break + techempower_route_cmd = ["oc", "get", "route", "-n", app_namespace, "--template={{range .items}}{{.spec.host}}{{\"\\n\"}}{{end}}"] + techempower_route = subprocess.check_output(techempower_route_cmd).decode("utf-8").strip() # Run the docker command with subprocess From 68baf97b38ba03ce2c8e368d06281e8a07bffcd0 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 27 Aug 2024 16:04:00 +0530 Subject: [PATCH 64/77] Replace 'default' with input namespace variable --- tests/scripts/helpers/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index b8f970169..9488a1066 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -1124,7 +1124,7 @@ def get_urls(namespace, cluster_type): shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # expose service tfb-qrh-service - subprocess.run(['oc -n default expose service tfb-qrh-service'], shell=True, stdout=subprocess.PIPE, + subprocess.run([f'oc -n {namespace} expose service tfb-qrh-service'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # get tfb-qrh-service route From e15209ac8b858be2b6535d38255fa9941ca5e7ee Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 27 Aug 2024 16:18:54 +0530 Subject: [PATCH 65/77] Cleanup installed benchmarks --- .../rest_apis/test_local_monitoring_e2e_workflow.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py index de96edba6..d720a24e5 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py @@ -19,6 +19,7 @@ import pytest import sys import time +import shutil sys.path.append("../../") from helpers.fixtures import * @@ -226,3 +227,6 @@ def test_list_recommendations_multiple_exps_for_datasource_workloads(cluster_typ response = delete_metric_profile(metric_profile_json_file) print("delete metric profile = ", response.status_code) assert response.status_code == SUCCESS_STATUS_CODE + + # Remove benchmarks directory + shutil.rmtree("benchmarks") From e9eb40c229513c02713bcac2c6c1b8a1cba82a5f Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 27 Aug 2024 17:42:32 +0530 Subject: [PATCH 66/77] Remove unsupported arguments to run the subprocess --- tests/scripts/helpers/utils.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 9488a1066..009b01a31 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -1117,19 +1117,19 @@ def get_urls(namespace, cluster_type): elif cluster_type == "openshift": # expose service kruize subprocess.run(['oc -n openshift-tuning expose service kruize'], shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, text=True) + stderr=subprocess.PIPE) # annotate kruize route subprocess.run(['oc -n openshift-tuning annotate route kruize --overwrite haproxy.router.openshift.io/timeout=60s'], - shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # expose service tfb-qrh-service subprocess.run([f'oc -n {namespace} expose service tfb-qrh-service'], shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, text=True) + stderr=subprocess.PIPE) # get tfb-qrh-service route techempower_url = subprocess.run([f'oc -n {namespace} get route tfb-qrh-service --no-headers -o custom-columns=NODE:.spec.host'], - shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: raise ValueError("Unsupported CLUSTER_TYPE. Expected 'minikube' or 'openshift'.") @@ -1190,8 +1190,9 @@ def wait_for_container_to_complete(container_id): print("##########################################################################################################\n") result = subprocess.run( ["docker", "wait", container_id], - capture_output=True, - text=True + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, ) exit_code = result.stdout.strip() print(f"Container {container_id} has completed with exit code {exit_code}.") From ae6003a6ac1cf9aeae0995e9423f8f1bdd47da5a Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 27 Aug 2024 18:14:44 +0530 Subject: [PATCH 67/77] Remove shell=True to docker wait cmd --- tests/scripts/helpers/utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/scripts/helpers/utils.py b/tests/scripts/helpers/utils.py index 009b01a31..f66505ff7 100644 --- a/tests/scripts/helpers/utils.py +++ b/tests/scripts/helpers/utils.py @@ -1190,7 +1190,6 @@ def wait_for_container_to_complete(container_id): print("##########################################################################################################\n") result = subprocess.run( ["docker", "wait", container_id], - shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) From 21b7357b1221669f16cac829b2e58400d241b494 Mon Sep 17 00:00:00 2001 From: Shreya Date: Tue, 27 Aug 2024 18:15:20 +0530 Subject: [PATCH 68/77] Remove extra logs --- .../rest_apis/test_local_monitoring_e2e_workflow.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py index d720a24e5..edb1203c1 100644 --- a/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py +++ b/tests/scripts/local_monitoring_tests/rest_apis/test_local_monitoring_e2e_workflow.py @@ -185,8 +185,6 @@ def test_list_recommendations_multiple_exps_for_datasource_workloads(cluster_typ response = generate_recommendations(tfb_exp_name) - data = response.json() - print(data) assert response.status_code == SUCCESS_STATUS_CODE # Invoke list recommendations for the specified experiment @@ -200,8 +198,6 @@ def test_list_recommendations_multiple_exps_for_datasource_workloads(cluster_typ response = generate_recommendations(tfb_db_exp_name) - data = response.json() - print(data) assert response.status_code == SUCCESS_STATUS_CODE # Invoke list recommendations for the specified experiment From 632e6cbdf8a051ef23393141e47b9cf6bf520fb0 Mon Sep 17 00:00:00 2001 From: Krishna Harsha Voora Date: Wed, 28 Aug 2024 18:11:14 +0530 Subject: [PATCH 69/77] Updated the Copyright year Signed-off-by: Krishna Harsha Voora --- scripts/aks-helpers.sh | 2 +- scripts/prometheus_on_aks.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/aks-helpers.sh b/scripts/aks-helpers.sh index e04850f3b..1fc08b032 100755 --- a/scripts/aks-helpers.sh +++ b/scripts/aks-helpers.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. +# Copyright (c) 2024, 2025 Red Hat, IBM Corporation and others. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/scripts/prometheus_on_aks.sh b/scripts/prometheus_on_aks.sh index f0a3ed96c..1e843f456 100755 --- a/scripts/prometheus_on_aks.sh +++ b/scripts/prometheus_on_aks.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2020, 2021 Red Hat, IBM Corporation and others. +# Copyright (c) 2024, 2025 Red Hat, IBM Corporation and others. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 6b3ee7c71694414a1554ddecf59d37ba3fb690f1 Mon Sep 17 00:00:00 2001 From: Krishna Harsha Voora Date: Wed, 28 Aug 2024 18:12:38 +0530 Subject: [PATCH 70/77] Removes minor nits Signed-off-by: Krishna Harsha Voora --- scripts/aks-helpers.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/aks-helpers.sh b/scripts/aks-helpers.sh index 1fc08b032..822e41abc 100755 --- a/scripts/aks-helpers.sh +++ b/scripts/aks-helpers.sh @@ -73,7 +73,6 @@ function aks_deploy() { # Replace autotune docker image in deployment yaml sed -e "s|{{ AUTOTUNE_IMAGE }}|${AUTOTUNE_DOCKER_IMAGE}|" ${AUTOTUNE_DEPLOY_MANIFEST_TEMPLATE} > ${AUTOTUNE_DEPLOY_MANIFEST} - #sed -i "s|{{ HPO_IMAGE }}|${HPO_DOCKER_IMAGE}|" ${AUTOTUNE_DEPLOY_MANIFEST} sed -i'' -e "s|{{ HPO_IMAGE }}|${HPO_DOCKER_IMAGE}|" "${AUTOTUNE_DEPLOY_MANIFEST}" ${kubectl_cmd} apply -f ${AUTOTUNE_DEPLOY_MANIFEST} From e2f7ac80bb3542b75c60d17392bb12fec9be6049 Mon Sep 17 00:00:00 2001 From: Saad Khan Date: Fri, 30 Aug 2024 10:23:37 +0530 Subject: [PATCH 71/77] add 'job' as a supported workload Signed-off-by: Saad Khan --- .../recommendations/RecommendationConstants.java | 12 +----------- .../RecommendationNotification.java | 2 -- .../engine/RecommendationEngine.java | 16 +++------------- .../analyzer/recommendations/term/Terms.java | 10 ---------- .../java/com/autotune/utils/KruizeConstants.java | 7 ------- 5 files changed, 4 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/autotune/analyzer/recommendations/RecommendationConstants.java b/src/main/java/com/autotune/analyzer/recommendations/RecommendationConstants.java index 4d2eb4285..4cc4be488 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/RecommendationConstants.java +++ b/src/main/java/com/autotune/analyzer/recommendations/RecommendationConstants.java @@ -52,9 +52,7 @@ public enum RecommendationTerms { .LONG_TERM_TOTAL_DURATION_UPPER_BOUND_MINS, KruizeConstants.RecommendationEngineConstants .DurationBasedEngine.RecommendationDurationRanges - .LONG_TERM_TOTAL_DURATION_LOWER_BOUND_MINS), - FIXED_TERM(KruizeConstants.JSONKeys.FIXED_TERM, FIXED_TERM_HOURS, FIXED_TERM_TOTAL_DURATION_UPPER_BOUND_MINS, - FIXED_TERM_TOTAL_DURATION_LOWER_BOUND_MINS); + .LONG_TERM_TOTAL_DURATION_LOWER_BOUND_MINS); private String value; private double durationInHrs; @@ -95,7 +93,6 @@ public static double getMaxDuration(RecommendationTerms termValue) { case SHORT_TERM -> SHORT_TERM_HOURS; case MEDIUM_TERM -> MEDIUM_TERM_HOURS; case LONG_TERM -> LONG_TERM_HOURS; - case FIXED_TERM -> FIXED_TERM_HOURS; }; } } @@ -121,11 +118,6 @@ public enum RecommendationNotification { RecommendationConstants.RecommendationNotificationMsgConstant.LONG_TERM_RECOMMENDATIONS_AVAILABLE, RecommendationConstants.RecommendationNotificationTypes.INFO ), - INFO_FIXED_TERM_RECOMMENDATIONS_AVAILABLE( - NotificationCodes.INFO_FIXED_TERM_RECOMMENDATIONS_AVAILABLE, - RecommendationNotificationMsgConstant.FIXED_TERM_RECOMMENDATIONS_AVAILABLE, - RecommendationConstants.RecommendationNotificationTypes.INFO - ), INFO_COST_RECOMMENDATIONS_AVAILABLE( RecommendationConstants.NotificationCodes.INFO_COST_RECOMMENDATIONS_AVAILABLE, RecommendationConstants.RecommendationNotificationMsgConstant.COST_RECOMMENDATIONS_AVAILABLE, @@ -324,7 +316,6 @@ public static final class NotificationCodes { public static final int INFO_SHORT_TERM_RECOMMENDATIONS_AVAILABLE = 111101; // TODO: need to discuss the code public static final int INFO_MEDIUM_TERM_RECOMMENDATIONS_AVAILABLE = 111102; // TODO: need to discuss the code public static final int INFO_LONG_TERM_RECOMMENDATIONS_AVAILABLE = 111103; // TODO: need to discuss the code; - public static final int INFO_FIXED_TERM_RECOMMENDATIONS_AVAILABLE = 111104; // TODO: need to discuss the code; public static final int INFO_COST_RECOMMENDATIONS_AVAILABLE = 112101; public static final int INFO_PERFORMANCE_RECOMMENDATIONS_AVAILABLE = 112102; public static final int COST_ENGINE_END = 112199; @@ -654,7 +645,6 @@ public static final class RecommendationNotificationMsgConstant { public static final String SHORT_TERM_RECOMMENDATIONS_AVAILABLE = "Short Term Recommendations Available"; public static final String MEDIUM_TERM_RECOMMENDATIONS_AVAILABLE = "Medium Term Recommendations Available"; public static final String LONG_TERM_RECOMMENDATIONS_AVAILABLE = "Long Term Recommendations Available"; - public static final String FIXED_TERM_RECOMMENDATIONS_AVAILABLE = "Fixed Term Recommendations Available"; public static final String CPU_RECORDS_ARE_IDLE = "CPU Usage is less than a millicore, No CPU Recommendations can be generated"; public static final String CPU_RECORDS_ARE_ZERO = "CPU usage is zero, No CPU Recommendations can be generated"; public static final String MEMORY_RECORDS_ARE_ZERO = "Memory Usage is zero, No Memory Recommendations can be generated"; diff --git a/src/main/java/com/autotune/analyzer/recommendations/RecommendationNotification.java b/src/main/java/com/autotune/analyzer/recommendations/RecommendationNotification.java index df5ab61b6..06ec0475a 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/RecommendationNotification.java +++ b/src/main/java/com/autotune/analyzer/recommendations/RecommendationNotification.java @@ -59,8 +59,6 @@ public static RecommendationNotification getNotificationForTermAvailability(Stri recommendationNotification = new RecommendationNotification(RecommendationConstants.RecommendationNotification.INFO_MEDIUM_TERM_RECOMMENDATIONS_AVAILABLE); } else if (recommendationTerm.equalsIgnoreCase(RecommendationConstants.RecommendationTerms.LONG_TERM.getValue())) { recommendationNotification = new RecommendationNotification(RecommendationConstants.RecommendationNotification.INFO_LONG_TERM_RECOMMENDATIONS_AVAILABLE); - } else if (recommendationTerm.equalsIgnoreCase(RecommendationConstants.RecommendationTerms.FIXED_TERM.getValue())) { - recommendationNotification = new RecommendationNotification(RecommendationConstants.RecommendationNotification.INFO_FIXED_TERM_RECOMMENDATIONS_AVAILABLE); } return recommendationNotification; } diff --git a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java index b4a1ead64..3a6a404b6 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java +++ b/src/main/java/com/autotune/analyzer/recommendations/engine/RecommendationEngine.java @@ -260,17 +260,8 @@ public KruizeObject prepareRecommendations(int calCount) { // continue to generate recommendation when kruizeObject is successfully created try { // set the default terms if the terms aren't provided by the user - if (kruizeObject.getTerms() == null) { - if (kruizeObject.getKubernetes_objects().get(0).getType().equals(AnalyzerConstants.K8sObjectConstants.Types.JOB)) { - // set fixed term for 'jobs' - terms.put(KruizeConstants.JSONKeys.FIXED_TERM, new Terms(KruizeConstants.JSONKeys.FIXED_TERM, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.FIXED_TERM_DURATION_DAYS, KruizeConstants - .RecommendationEngineConstants.DurationBasedEngine.DurationAmount.FIXED_TERM_DURATION_DAYS_THRESHOLD, 15, 1)); // TODO: plots_datapoints, plots_datapoints_delta_in_days needs to be updated after POC - kruizeObject.setTerms(terms); - } else { - KruizeObject.setDefaultTerms(terms, kruizeObject); - } - } + if (kruizeObject.getTerms() == null) + KruizeObject.setDefaultTerms(terms, kruizeObject); // set the performance profile setPerformanceProfile(kruizeObject.getPerformanceProfile()); // get the datasource @@ -784,8 +775,7 @@ private boolean populateRecommendation(Map.Entry termEntry, ( !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.SHORT_TERM) && !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.MEDIUM_TERM) && - !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.LONG_TERM) && - !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.FIXED_TERM) + !recommendationTerm.equalsIgnoreCase(KruizeConstants.JSONKeys.LONG_TERM) ) ) { LOGGER.error(String.format(AnalyzerErrorConstants.APIErrors.UpdateRecommendationsAPI.INVALID_RECOMMENDATION_TERM, recommendationTerm)); diff --git a/src/main/java/com/autotune/analyzer/recommendations/term/Terms.java b/src/main/java/com/autotune/analyzer/recommendations/term/Terms.java index 305ef2ec4..16eadcea3 100644 --- a/src/main/java/com/autotune/analyzer/recommendations/term/Terms.java +++ b/src/main/java/com/autotune/analyzer/recommendations/term/Terms.java @@ -154,7 +154,6 @@ public static double getMaxDuration(String termValue) { case SHORT_TERM -> SHORT_TERM_HOURS; case MEDIUM_TERM -> MEDIUM_TERM_HOURS; case LONG_TERM -> LONG_TERM_HOURS; - case FIXED_TERM -> FIXED_TERM_HOURS; default -> throw new IllegalStateException("Unexpected value: " + termValue); }; } @@ -191,13 +190,4 @@ public double getPlots_datapoints_delta_in_days() { public void setPlots_datapoints_delta_in_days(double plots_datapoints_delta_in_days) { this.plots_datapoints_delta_in_days = plots_datapoints_delta_in_days; } - - @Override - public String toString() { - return "Terms{" + - "days=" + days + - ", threshold_in_days=" + threshold_in_days + - ", name='" + name + '\'' + - '}'; - } } diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 3178d773c..4fa4a7b95 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -246,7 +246,6 @@ public static final class JSONKeys { public static final String SHORT_TERM = "short_term"; public static final String MEDIUM_TERM = "medium_term"; public static final String LONG_TERM = "long_term"; - public static final String FIXED_TERM = "fixed_term"; public static final String RECOMMENDATIONS = "recommendations"; public static final String VARIATION = "variation"; public static final String NOTIFICATIONS = "notifications"; @@ -676,8 +675,6 @@ public static final class DurationAmount { public static final int MEDIUM_TERM_DURATION_DAYS_THRESHOLD = 2; public static final int LONG_TERM_DURATION_DAYS = 15; public static final int LONG_TERM_DURATION_DAYS_THRESHOLD = 8; - public static final int FIXED_TERM_DURATION_DAYS = 1; // TODO: temporarily set as 1 day, need to update this after the POC - public static final double FIXED_TERM_DURATION_DAYS_THRESHOLD = ((double) 1 / (24 * 60)); // TODO: temporarily set as 1 min, need to update this after the POC private DurationAmount() { @@ -689,7 +686,6 @@ public static final class RecommendationDurationRanges { public static final double SHORT_TERM_MIN_DATA_THRESHOLD_MINS = 30; public static final double MEDIUM_TERM_MIN_DATA_THRESHOLD_MINS = 2 * TimeConv.NO_OF_HOURS_PER_DAY * TimeConv.NO_OF_MINUTES_PER_HOUR; public static final double LONG_TERM_MIN_DATA_THRESHOLD_MINS = 8 * TimeConv.NO_OF_HOURS_PER_DAY * TimeConv.NO_OF_MINUTES_PER_HOUR; - public static final double FIXED_TERM_MIN_DATA_THRESHOLD_MINS = 1; /* LONG TERM */ public static final double LONG_TERM_TOTAL_DURATION_UPPER_BOUND_MINS = LONG_TERM_MIN_DATA_THRESHOLD_MINS + MEASUREMENT_DURATION_BUFFER_IN_MINS; public static final double LONG_TERM_TOTAL_DURATION_LOWER_BOUND_MINS = @@ -700,11 +696,8 @@ public static final class RecommendationDurationRanges { public static final double SHORT_TERM_HOURS = DurationAmount.SHORT_TERM_DURATION_DAYS * KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY; public static final double MEDIUM_TERM_HOURS = DurationAmount.MEDIUM_TERM_DURATION_DAYS * KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY; public static final double LONG_TERM_HOURS = DurationAmount.LONG_TERM_DURATION_DAYS * KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY; - public static final double FIXED_TERM_HOURS = DurationAmount.FIXED_TERM_DURATION_DAYS * KruizeConstants.TimeConv.NO_OF_HOURS_PER_DAY; public static final double SHORT_TERM_TOTAL_DURATION_UPPER_BOUND_MINS = SHORT_TERM_MIN_DATA_THRESHOLD_MINS + MEASUREMENT_DURATION_BUFFER_IN_MINS; public static final double SHORT_TERM_TOTAL_DURATION_LOWER_BOUND_MINS = SHORT_TERM_MIN_DATA_THRESHOLD_MINS - MEASUREMENT_DURATION_BUFFER_IN_MINS; - public static final double FIXED_TERM_TOTAL_DURATION_UPPER_BOUND_MINS = FIXED_TERM_MIN_DATA_THRESHOLD_MINS - MEASUREMENT_DURATION_BUFFER_IN_MINS; - public static final double FIXED_TERM_TOTAL_DURATION_LOWER_BOUND_MINS = FIXED_TERM_MIN_DATA_THRESHOLD_MINS - MEASUREMENT_DURATION_BUFFER_IN_MINS; private RecommendationDurationRanges() { From 206a02c726caa24bef71f29ca1ee58cd0caf912a Mon Sep 17 00:00:00 2001 From: msvinaykumar Date: Fri, 30 Aug 2024 13:16:36 +0530 Subject: [PATCH 72/77] A metric entry with only three tags, which are unlikely to have many unique values, will therefore help reduce cardinality. Signed-off-by: msvinaykumar --- .../metrics/KruizeNotificationCollectionRegistry.java | 9 ++++++++- src/main/java/com/autotune/utils/KruizeConstants.java | 5 +++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java b/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java index f03b6242a..7b3be444d 100644 --- a/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java +++ b/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java @@ -5,11 +5,14 @@ import com.autotune.analyzer.recommendations.objects.MappedRecommendationForTimestamp; import com.autotune.analyzer.recommendations.objects.TermRecommendations; import com.autotune.common.data.result.ContainerData; +import com.autotune.operator.InitializeDeployment; import com.autotune.operator.KruizeDeploymentInfo; import com.autotune.utils.KruizeConstants; import com.autotune.utils.MetricsConfig; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Tags; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.sql.Timestamp; import java.util.Collection; @@ -24,6 +27,7 @@ public class KruizeNotificationCollectionRegistry { private String experiment_name; private Timestamp interval_end_time; private String container_name; + private static final Logger LOGGER = LoggerFactory.getLogger(KruizeNotificationCollectionRegistry.class); /** * Constructor to initialize KruizeNotificationCollectionRegistry with experiment name, interval end time, and container name. @@ -78,7 +82,10 @@ public void createCounterTag(String level, String term, String model, Collection for (RecommendationNotification recommendationNotification : recommendationNotificationList) { Tags additionalTags = Tags.empty(); if (("|" + KruizeDeploymentInfo.log_recommendation_metrics_level + "|").contains("|" + recommendationNotification.getType() + "|") == true) { - additionalTags = additionalTags.and(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.TAG_NAME, String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format, this.experiment_name, this.container_name, KruizeConstants.DateFormats.simpleDateFormatForUTC.format(this.interval_end_time), level, term, model, String.valueOf(recommendationNotification.getCode()), recommendationNotification.getType(), recommendationNotification.getMessage())); + String kibanaLog = String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format_for_KIBANA, this.experiment_name, this.container_name, KruizeConstants.DateFormats.simpleDateFormatForUTC.format(this.interval_end_time), level, term, model, String.valueOf(recommendationNotification.getCode()), recommendationNotification.getType(), recommendationNotification.getMessage()); + String metricEntry = String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format_for_METRICS, term, model, recommendationNotification.getType()); + LOGGER.info(kibanaLog); + additionalTags = additionalTags.and(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.TAG_NAME,metricEntry); // A metric entry with only three tags, which are unlikely to have many unique values, will therefore help reduce cardinality. Counter counterNotifications = MetricsConfig.meterRegistry().find(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.METRIC_NAME).tags(additionalTags).counter(); if (counterNotifications == null) { counterNotifications = MetricsConfig.timerBKruizeNotifications.tags(additionalTags).register(MetricsConfig.meterRegistry); diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 27c468210..8aa126aca 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -697,8 +697,9 @@ public static final class KRUIZE_CONFIG_DEFAULT_VALUE { public static final class KRUIZE_RECOMMENDATION_METRICS { public static final String METRIC_NAME = "KruizeRecommendationsNotification"; - public static final String TAG_NAME = "experiment_details"; - public static final String notification_format = "%s|%s|%s|%s|%s|%s|%s|%s|%s"; //experiment_name,container_name,endtime,level,termname,modelname,code,type,message + public static final String TAG_NAME = "recommendations_notifications"; + public static final String notification_format_for_KIBANA = "%s|%s|%s|%s|%s|%s|%s|%s|%s"; //experiment_name,container_name,endtime,level,termname,modelname,code,type,message + public static final String notification_format_for_METRICS = "%s|%s|%s"; //termname,modelname,type } } From d602c1d5d147be1aa41fc99a4ead68845ea36e0b Mon Sep 17 00:00:00 2001 From: Saad Khan Date: Fri, 30 Aug 2024 16:36:07 +0530 Subject: [PATCH 73/77] add test to support job Signed-off-by: Saad Khan --- .../helpers/list_reco_json_validate.py | 2 +- .../json_files/create_exp_job_type.json | 31 ++ .../multiple_results_single_job_type_exp.json | 404 ++++++++++++++++++ .../rest_apis/test_create_experiment.py | 2 +- .../rest_apis/test_list_recommendations.py | 63 +++ 5 files changed, 500 insertions(+), 2 deletions(-) create mode 100644 tests/scripts/remote_monitoring_tests/json_files/create_exp_job_type.json create mode 100644 tests/scripts/remote_monitoring_tests/json_files/multiple_results_single_job_type_exp.json diff --git a/tests/scripts/helpers/list_reco_json_validate.py b/tests/scripts/helpers/list_reco_json_validate.py index 7e1fc2f4c..22b7ef2a8 100644 --- a/tests/scripts/helpers/list_reco_json_validate.py +++ b/tests/scripts/helpers/list_reco_json_validate.py @@ -19,7 +19,7 @@ from jsonschema.exceptions import ValidationError from helpers.list_reco_json_schema import list_reco_json_schema -KUBERNETES_OBJECTS_TYPE_SUPPORTED = ("deployment", "replicaset", "deploymentConfig", "statefulset", "daemonset", "replicationController") +KUBERNETES_OBJECTS_TYPE_SUPPORTED = ("deployment", "replicaset", "deploymentConfig", "statefulset", "daemonset", "replicationController", "job") KUBERNETES_OBJECTS_TYPE_NOT_SUPPORTED = "Kubernetes objects type not supported!" JSON_NULL_VALUES = ("is not of type 'string'", "is not of type 'integer'", "is not of type 'number'") diff --git a/tests/scripts/remote_monitoring_tests/json_files/create_exp_job_type.json b/tests/scripts/remote_monitoring_tests/json_files/create_exp_job_type.json new file mode 100644 index 000000000..7c8f1bb47 --- /dev/null +++ b/tests/scripts/remote_monitoring_tests/json_files/create_exp_job_type.json @@ -0,0 +1,31 @@ +[{ + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "cluster_name": "cluster-one-division-bell", + "performance_profile": "resource-optimization-openshift", + "mode": "monitor", + "target_cluster": "remote", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0" + }, + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1" + } + ] + } + ], + "trial_settings": { + "measurement_duration": "15min" + }, + "recommendation_settings": { + "threshold": "0.1" + } +}] diff --git a/tests/scripts/remote_monitoring_tests/json_files/multiple_results_single_job_type_exp.json b/tests/scripts/remote_monitoring_tests/json_files/multiple_results_single_job_type_exp.json new file mode 100644 index 000000000..f6152673e --- /dev/null +++ b/tests/scripts/remote_monitoring_tests/json_files/multiple_results_single_job_type_exp.json @@ -0,0 +1,404 @@ +[ + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-13T22:59:20.982Z", + "interval_end_time": "2023-04-13T23:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 0.008612013913388, + "min": 0.000361107147235, + "max": 0.003050324185815, + "avg": 0.001435335652231, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 0.0, + "max": 1330.0234375, + "sum": 3606.66143465909, + "avg": 601.110239109849, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 0.0, + "max": 1320.109375, + "sum": 3502.236328125, + "avg": 583.7060546875, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 0.008612013913388, + "min": 0.000361107147235, + "max": 0.003050324185815, + "avg": 0.001435335652231, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 0.0, + "max": 1330.0234375, + "sum": 3606.66143465909, + "avg": 601.110239109849, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 0.0, + "max": 1320.109375, + "sum": 3502.236328125, + "avg": 583.7060546875, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-13T23:14:20.982Z", + "interval_end_time": "2023-04-13T23:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.00125369576092, + "max": 0.00125369576092, + "avg": 0.000417898586973, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.23642774156611, + "min": 0.122641301400588, + "max": 4.05884393815185, + "avg": 3.0788092471887, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 194.62890625, + "max": 290.046875, + "sum": 730.8758820564518, + "avg": 243.62529401881696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 187.2265625, + "max": 281.9921875, + "sum": 701.5254536290321, + "avg": 233.84181787634373, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.00125369576092, + "max": 0.00125369576092, + "avg": 0.000417898586973, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.23642774156611, + "min": 0.122641301400588, + "max": 4.05884393815185, + "avg": 3.0788092471887, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 194.62890625, + "max": 290.046875, + "sum": 730.8758820564518, + "avg": 243.62529401881696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 187.2265625, + "max": 281.9921875, + "sum": 701.5254536290321, + "avg": 233.84181787634373, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + } +] diff --git a/tests/scripts/remote_monitoring_tests/rest_apis/test_create_experiment.py b/tests/scripts/remote_monitoring_tests/rest_apis/test_create_experiment.py index a0825f02c..6475fecd1 100644 --- a/tests/scripts/remote_monitoring_tests/rest_apis/test_create_experiment.py +++ b/tests/scripts/remote_monitoring_tests/rest_apis/test_create_experiment.py @@ -141,7 +141,7 @@ def test_create_exp(cluster_type): @pytest.mark.sanity @pytest.mark.parametrize("k8s_obj_type", ["deployment", "deploymentConfig", "statefulset", "daemonset", "replicaset", - "replicationController"]) + "replicationController", "job"]) def test_create_exp_for_supported_k8s_obj_type(k8s_obj_type, cluster_type): """ Test Description: This test validates the response status code of createExperiment API by passing a diff --git a/tests/scripts/remote_monitoring_tests/rest_apis/test_list_recommendations.py b/tests/scripts/remote_monitoring_tests/rest_apis/test_list_recommendations.py index ba767c9af..9e2dd8c17 100644 --- a/tests/scripts/remote_monitoring_tests/rest_apis/test_list_recommendations.py +++ b/tests/scripts/remote_monitoring_tests/rest_apis/test_list_recommendations.py @@ -2934,3 +2934,66 @@ def validate_recommendations_notifications(experiment_name,end_time,code,message assert short_term_recommendation['recommendation_engines']['cost']['notifications'][code]['message'] == message assert short_term_recommendation['recommendation_engines']['performance']['notifications'][code]['message'] == message + +@pytest.mark.sanity +def test_list_recommendations_job_type_exp(cluster_type): + """ + Test Description: This test validates listRecommendations by updating multiple results for a single experiment + """ + input_json_file = "../json_files/create_exp_job_type.json" + + form_kruize_url(cluster_type) + response = delete_experiment(input_json_file) + print("delete exp = ", response.status_code) + + # Create experiment using the specified json + response = create_experiment(input_json_file) + + data = response.json() + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + assert data['message'] == CREATE_EXP_SUCCESS_MSG + + # Update results for the experiment + result_json_file = "../json_files/multiple_results_single_job_type_exp.json" + response = update_results(result_json_file, False) + + # Get the experiment name + json_data = json.load(open(input_json_file)) + experiment_name = json_data[0]['experiment_name'] + end_time = "2023-04-14T23:59:20.982Z" + + data = response.json() + assert response.status_code == SUCCESS_STATUS_CODE + assert data['status'] == SUCCESS_STATUS + assert data['message'] == UPDATE_RESULTS_SUCCESS_MSG + + response = update_recommendations(experiment_name, None, end_time) + data = response.json() + assert response.status_code == SUCCESS_STATUS_CODE + assert data[0]['experiment_name'] == experiment_name + assert data[0]['kubernetes_objects'][0]['containers'][0]['recommendations']['notifications'][ + NOTIFICATION_CODE_FOR_RECOMMENDATIONS_AVAILABLE]['message'] == RECOMMENDATIONS_AVAILABLE + + response = list_recommendations(experiment_name) + + list_reco_json = response.json() + assert response.status_code == SUCCESS_200_STATUS_CODE + + # Validate the json against the json schema + errorMsg = validate_list_reco_json(list_reco_json, list_reco_json_schema) + assert errorMsg == "" + + # Validate the json values + create_exp_json = read_json_data_from_file(input_json_file) + + expected_duration_in_hours = SHORT_TERM_DURATION_IN_HRS_MAX + + update_results_json = [] + result_json_arr = read_json_data_from_file(result_json_file) + update_results_json.append(result_json_arr[len(result_json_arr) - 1]) + validate_reco_json(create_exp_json[0], update_results_json, list_reco_json[0], expected_duration_in_hours) + + # Delete the experiment + response = delete_experiment(input_json_file) + print("delete exp = ", response.status_code) From 506903920fba81623d185cbb2f20d72f2c924ce6 Mon Sep 17 00:00:00 2001 From: msvinaykumar Date: Sat, 31 Aug 2024 13:05:58 +0530 Subject: [PATCH 74/77] incorporated review comments Signed-off-by: msvinaykumar --- .../metrics/KruizeNotificationCollectionRegistry.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java b/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java index 7b3be444d..2b37e6ed3 100644 --- a/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java +++ b/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java @@ -82,9 +82,9 @@ public void createCounterTag(String level, String term, String model, Collection for (RecommendationNotification recommendationNotification : recommendationNotificationList) { Tags additionalTags = Tags.empty(); if (("|" + KruizeDeploymentInfo.log_recommendation_metrics_level + "|").contains("|" + recommendationNotification.getType() + "|") == true) { - String kibanaLog = String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format_for_KIBANA, this.experiment_name, this.container_name, KruizeConstants.DateFormats.simpleDateFormatForUTC.format(this.interval_end_time), level, term, model, String.valueOf(recommendationNotification.getCode()), recommendationNotification.getType(), recommendationNotification.getMessage()); + String notificationLog = String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format_for_KIBANA, this.experiment_name, this.container_name, KruizeConstants.DateFormats.simpleDateFormatForUTC.format(this.interval_end_time), level, term, model, String.valueOf(recommendationNotification.getCode()), recommendationNotification.getType(), recommendationNotification.getMessage()); String metricEntry = String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format_for_METRICS, term, model, recommendationNotification.getType()); - LOGGER.info(kibanaLog); + LOGGER.info(notificationLog); additionalTags = additionalTags.and(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.TAG_NAME,metricEntry); // A metric entry with only three tags, which are unlikely to have many unique values, will therefore help reduce cardinality. Counter counterNotifications = MetricsConfig.meterRegistry().find(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.METRIC_NAME).tags(additionalTags).counter(); if (counterNotifications == null) { From 89d4cc99e1eb834ede2265dd203825370e7d5b24 Mon Sep 17 00:00:00 2001 From: msvinaykumar Date: Sat, 31 Aug 2024 17:22:05 +0530 Subject: [PATCH 75/77] incorporated review comments Signed-off-by: msvinaykumar --- src/main/java/com/autotune/utils/KruizeConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/autotune/utils/KruizeConstants.java b/src/main/java/com/autotune/utils/KruizeConstants.java index 8aa126aca..2309f7b0a 100644 --- a/src/main/java/com/autotune/utils/KruizeConstants.java +++ b/src/main/java/com/autotune/utils/KruizeConstants.java @@ -698,7 +698,7 @@ public static final class KRUIZE_CONFIG_DEFAULT_VALUE { public static final class KRUIZE_RECOMMENDATION_METRICS { public static final String METRIC_NAME = "KruizeRecommendationsNotification"; public static final String TAG_NAME = "recommendations_notifications"; - public static final String notification_format_for_KIBANA = "%s|%s|%s|%s|%s|%s|%s|%s|%s"; //experiment_name,container_name,endtime,level,termname,modelname,code,type,message + public static final String notification_format_for_LOG = "%s|%s|%s|%s|%s|%s|%s|%s|%s"; //experiment_name,container_name,endtime,level,termname,modelname,code,type,message public static final String notification_format_for_METRICS = "%s|%s|%s"; //termname,modelname,type } From 03c2bcf53681751d56a246bd9c8b907fcd9c302f Mon Sep 17 00:00:00 2001 From: Saad Khan Date: Mon, 2 Sep 2024 13:17:55 +0530 Subject: [PATCH 76/77] update test json file for job Signed-off-by: Saad Khan --- .../multiple_results_single_job_type_exp.json | 19698 ++++++++++++++++ 1 file changed, 19698 insertions(+) diff --git a/tests/scripts/remote_monitoring_tests/json_files/multiple_results_single_job_type_exp.json b/tests/scripts/remote_monitoring_tests/json_files/multiple_results_single_job_type_exp.json index f6152673e..f5f226232 100644 --- a/tests/scripts/remote_monitoring_tests/json_files/multiple_results_single_job_type_exp.json +++ b/tests/scripts/remote_monitoring_tests/json_files/multiple_results_single_job_type_exp.json @@ -400,5 +400,19703 @@ ] } ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-13T23:29:20.982Z", + "interval_end_time": "2023-04-13T23:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.04609118991037, + "min": 2.34309635937407, + "max": 3.88964089192222, + "avg": 3.01536372997012, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 229.984375, + "max": 314.703125, + "sum": 828.3160282258062, + "avg": 276.1053427419357, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 225.0703125, + "max": 307.4921875, + "sum": 799.6636844758062, + "avg": 266.5545614919357, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.04609118991037, + "min": 2.34309635937407, + "max": 3.88964089192222, + "avg": 3.01536372997012, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 229.984375, + "max": 314.703125, + "sum": 828.3160282258062, + "avg": 276.1053427419357, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 225.0703125, + "max": 307.4921875, + "sum": 799.6636844758062, + "avg": 266.5545614919357, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-13T23:44:20.982Z", + "interval_end_time": "2023-04-13T23:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.112328922496552, + "max": 0.085147492862069, + "avg": 0.037442974165517, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.46914730046654, + "min": 2.30112868885926, + "max": 4.58010182155185, + "avg": 2.82304910015551, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 251.234375, + "max": 346.984375, + "sum": 890.1745211693544, + "avg": 296.7248403897848, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 246.47265625, + "max": 335.62109375, + "sum": 859.1034526209679, + "avg": 286.3678175403223, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.112328922496552, + "max": 0.085147492862069, + "avg": 0.037442974165517, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.46914730046654, + "min": 2.30112868885926, + "max": 4.58010182155185, + "avg": 2.82304910015551, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 251.234375, + "max": 346.984375, + "sum": 890.1745211693544, + "avg": 296.7248403897848, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 246.47265625, + "max": 335.62109375, + "sum": 859.1034526209679, + "avg": 286.3678175403223, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-13T23:59:20.982Z", + "interval_end_time": "2023-04-14T00:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 13.2376485156556, + "min": 3.91502781582593, + "max": 4.85605234033704, + "avg": 4.41254950521852, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 271.42578125, + "max": 347.83984375, + "sum": 952.2685231854839, + "avg": 317.4228410618277, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 265.5390625, + "max": 338.46875, + "sum": 918.4469506048393, + "avg": 306.14898353494647, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 13.2376485156556, + "min": 3.91502781582593, + "max": 4.85605234033704, + "avg": 4.41254950521852, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 271.42578125, + "max": 347.83984375, + "sum": 952.2685231854839, + "avg": 317.4228410618277, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 265.5390625, + "max": 338.46875, + "sum": 918.4469506048393, + "avg": 306.14898353494647, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T00:14:20.982Z", + "interval_end_time": "2023-04-14T00:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.3112178759358, + "min": 3.33503295274444, + "max": 4.81386723182222, + "avg": 3.77040595864527, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 271.59375, + "max": 356.5390625, + "sum": 989.438004032259, + "avg": 329.8126680107527, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 265.66796875, + "max": 348.39453125, + "sum": 956.612777217741, + "avg": 318.8709257392473, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.3112178759358, + "min": 3.33503295274444, + "max": 4.81386723182222, + "avg": 3.77040595864527, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 271.59375, + "max": 356.5390625, + "sum": 989.438004032259, + "avg": 329.8126680107527, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 265.66796875, + "max": 348.39453125, + "sum": 956.612777217741, + "avg": 318.8709257392473, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T00:29:20.982Z", + "interval_end_time": "2023-04-14T00:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.23973705240321, + "min": 2.23026164174074, + "max": 3.92129674667037, + "avg": 3.07991235080107, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 290.625, + "max": 359.1015625, + "sum": 1001.7091733870983, + "avg": 333.9030577956991, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 286.27734375, + "max": 350.00390625, + "sum": 970.1455393145179, + "avg": 323.3818464381723, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.23973705240321, + "min": 2.23026164174074, + "max": 3.92129674667037, + "avg": 3.07991235080107, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 290.625, + "max": 359.1015625, + "sum": 1001.7091733870983, + "avg": 333.9030577956991, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 286.27734375, + "max": 350.00390625, + "sum": 970.1455393145179, + "avg": 323.3818464381723, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T00:44:20.982Z", + "interval_end_time": "2023-04-14T00:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.004116689491954, + "max": 0.002598697606897, + "avg": 0.001372229830651, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.87229159665284, + "min": 2.21689067767037, + "max": 3.59979932507037, + "avg": 2.62409719888428, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 295.34765625, + "max": 398.4921875, + "sum": 1034.1706149193574, + "avg": 344.7235383064518, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 291.51953125, + "max": 380.515625, + "sum": 1001.016129032259, + "avg": 333.6720430107527, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.004116689491954, + "max": 0.002598697606897, + "avg": 0.001372229830651, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.87229159665284, + "min": 2.21689067767037, + "max": 3.59979932507037, + "avg": 2.62409719888428, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 295.34765625, + "max": 398.4921875, + "sum": 1034.1706149193574, + "avg": 344.7235383064518, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 291.51953125, + "max": 380.515625, + "sum": 1001.016129032259, + "avg": 333.6720430107527, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T00:59:20.982Z", + "interval_end_time": "2023-04-14T01:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.6005743048741, + "min": 3.21516195458148, + "max": 3.92478116602223, + "avg": 3.53352476829136, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 329.65625, + "max": 390.6953125, + "sum": 1104.1881300403213, + "avg": 368.06271001344106, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 322.6484375, + "max": 382.08203125, + "sum": 1068.776839717741, + "avg": 356.2589465725803, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.6005743048741, + "min": 3.21516195458148, + "max": 3.92478116602223, + "avg": 3.53352476829136, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 329.65625, + "max": 390.6953125, + "sum": 1104.1881300403213, + "avg": 368.06271001344106, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 322.6484375, + "max": 382.08203125, + "sum": 1068.776839717741, + "avg": 356.2589465725803, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T01:14:20.982Z", + "interval_end_time": "2023-04-14T01:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.9410424960665, + "min": 3.18957297767777, + "max": 4.02861094841482, + "avg": 3.64701416535551, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 329.8359375, + "max": 446.5625, + "sum": 1225.6387348790358, + "avg": 408.5462449596777, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 323.28125, + "max": 431.42578125, + "sum": 1183.387726814518, + "avg": 394.4625756048384, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.9410424960665, + "min": 3.18957297767777, + "max": 4.02861094841482, + "avg": 3.64701416535551, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 329.8359375, + "max": 446.5625, + "sum": 1225.6387348790358, + "avg": 408.5462449596777, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 323.28125, + "max": 431.42578125, + "sum": 1183.387726814518, + "avg": 394.4625756048384, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T01:29:20.982Z", + "interval_end_time": "2023-04-14T01:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.18851521172901, + "min": 2.23911712425925, + "max": 3.99740168404445, + "avg": 2.72950507057634, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 417.515625, + "max": 472.35546875, + "sum": 1332.7711693548392, + "avg": 444.25705645161344, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 410.34765625, + "max": 461.05078125, + "sum": 1294.0414566532231, + "avg": 431.34715221774195, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.18851521172901, + "min": 2.23911712425925, + "max": 3.99740168404445, + "avg": 2.72950507057634, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 417.515625, + "max": 472.35546875, + "sum": 1332.7711693548392, + "avg": 444.25705645161344, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 410.34765625, + "max": 461.05078125, + "sum": 1294.0414566532231, + "avg": 431.34715221774195, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T01:44:20.982Z", + "interval_end_time": "2023-04-14T01:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.5538705072991, + "min": 2.32747479522221, + "max": 5.24432858166296, + "avg": 4.18462350243305, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 447.375, + "max": 521.5546875, + "sum": 1467.8884828629016, + "avg": 489.2961609543009, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 438.125, + "max": 510.3046875, + "sum": 1426.0090725806426, + "avg": 475.3363575268822, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.5538705072991, + "min": 2.32747479522221, + "max": 5.24432858166296, + "avg": 4.18462350243305, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 447.375, + "max": 521.5546875, + "sum": 1467.8884828629016, + "avg": 489.2961609543009, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 438.125, + "max": 510.3046875, + "sum": 1426.0090725806426, + "avg": 475.3363575268822, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T01:59:20.982Z", + "interval_end_time": "2023-04-14T02:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 13.0997042618841, + "min": 3.50427849813703, + "max": 5.33515178196666, + "avg": 4.36656808729469, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 481.91796875, + "max": 559.76953125, + "sum": 1563.6571320564556, + "avg": 521.2190440188169, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 475.24609375, + "max": 540.44140625, + "sum": 1520.0132308467769, + "avg": 506.671076948925, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 13.0997042618841, + "min": 3.50427849813703, + "max": 5.33515178196666, + "avg": 4.36656808729469, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 481.91796875, + "max": 559.76953125, + "sum": 1563.6571320564556, + "avg": 521.2190440188169, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 475.24609375, + "max": 540.44140625, + "sum": 1520.0132308467769, + "avg": 506.671076948925, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T02:14:20.982Z", + "interval_end_time": "2023-04-14T02:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.0524067195789, + "min": 2.66358841466294, + "max": 4.19660716037036, + "avg": 3.68413557319296, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 483.8046875, + "max": 557.84765625, + "sum": 1591.0030241935444, + "avg": 530.3343413978491, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 478.68359375, + "max": 540.7109375, + "sum": 1553.057207661295, + "avg": 517.6857358870964, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.0524067195789, + "min": 2.66358841466294, + "max": 4.19660716037036, + "avg": 3.68413557319296, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 483.8046875, + "max": 557.84765625, + "sum": 1591.0030241935444, + "avg": 530.3343413978491, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 478.68359375, + "max": 540.7109375, + "sum": 1553.057207661295, + "avg": 517.6857358870964, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T02:29:20.982Z", + "interval_end_time": "2023-04-14T02:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.11427328335358, + "min": 2.13855924275925, + "max": 2.74692213271852, + "avg": 2.37142442778453, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 483.82421875, + "max": 546.765625, + "sum": 1567.1585181451608, + "avg": 522.3861727150536, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 477.94140625, + "max": 533.4296875, + "sum": 1537.9644657258034, + "avg": 512.6548219086018, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.11427328335358, + "min": 2.13855924275925, + "max": 2.74692213271852, + "avg": 2.37142442778453, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 483.82421875, + "max": 546.765625, + "sum": 1567.1585181451608, + "avg": 522.3861727150536, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 477.94140625, + "max": 533.4296875, + "sum": 1537.9644657258034, + "avg": 512.6548219086018, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T02:44:20.982Z", + "interval_end_time": "2023-04-14T02:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.40207558177333, + "min": 2.17771477021481, + "max": 3.22089857927408, + "avg": 2.46735852725778, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 484.3359375, + "max": 630.69140625, + "sum": 1610.2723034274197, + "avg": 536.7574344758062, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 478.125, + "max": 615.4375, + "sum": 1576.3912550403213, + "avg": 525.4637516801071, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.40207558177333, + "min": 2.17771477021481, + "max": 3.22089857927408, + "avg": 2.46735852725778, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 484.3359375, + "max": 630.69140625, + "sum": 1610.2723034274197, + "avg": 536.7574344758062, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 478.125, + "max": 615.4375, + "sum": 1576.3912550403213, + "avg": 525.4637516801071, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T02:59:20.982Z", + "interval_end_time": "2023-04-14T03:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.8811287533044, + "min": 3.06415491851111, + "max": 3.97339506212593, + "avg": 3.62704291776815, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 501.6328125, + "max": 630.84765625, + "sum": 1724.2982610887145, + "avg": 574.7660870295696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 492.3828125, + "max": 616.39453125, + "sum": 1684.5724546370984, + "avg": 561.5241515456992, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.8811287533044, + "min": 3.06415491851111, + "max": 3.97339506212593, + "avg": 3.62704291776815, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 501.6328125, + "max": 630.84765625, + "sum": 1724.2982610887145, + "avg": 574.7660870295696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 492.3828125, + "max": 616.39453125, + "sum": 1684.5724546370984, + "avg": 561.5241515456992, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T03:14:20.982Z", + "interval_end_time": "2023-04-14T03:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.4764962408307, + "min": 3.01007331396298, + "max": 3.90357787986297, + "avg": 3.49216541361025, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 486.8984375, + "max": 627.91015625, + "sum": 1686.097152217741, + "avg": 562.0323840725804, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 481.13671875, + "max": 615.5625, + "sum": 1656.9078881048392, + "avg": 552.3026293682794, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.4764962408307, + "min": 3.01007331396298, + "max": 3.90357787986297, + "avg": 3.49216541361025, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 486.8984375, + "max": 627.91015625, + "sum": 1686.097152217741, + "avg": 562.0323840725804, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 481.13671875, + "max": 615.5625, + "sum": 1656.9078881048392, + "avg": 552.3026293682794, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T03:29:20.982Z", + "interval_end_time": "2023-04-14T03:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.21048489802543, + "min": 2.1600138799926, + "max": 3.76924492766295, + "avg": 3.07016163267514, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 486.4453125, + "max": 614.93359375, + "sum": 1675.7011088709642, + "avg": 558.5670362903223, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 481.06640625, + "max": 605.23046875, + "sum": 1647.626386088705, + "avg": 549.2087953629036, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.21048489802543, + "min": 2.1600138799926, + "max": 3.76924492766295, + "avg": 3.07016163267514, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 486.4453125, + "max": 614.93359375, + "sum": 1675.7011088709642, + "avg": 558.5670362903223, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 481.06640625, + "max": 605.23046875, + "sum": 1647.626386088705, + "avg": 549.2087953629036, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T03:44:20.982Z", + "interval_end_time": "2023-04-14T03:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.74138200375716, + "min": 2.16799914465185, + "max": 3.54586913627777, + "avg": 2.58046066791905, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 486.5078125, + "max": 637.21484375, + "sum": 1694.0756048387145, + "avg": 564.6918682795696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 480.9765625, + "max": 626.53125, + "sum": 1664.540070564518, + "avg": 554.8466901881724, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.74138200375716, + "min": 2.16799914465185, + "max": 3.54586913627777, + "avg": 2.58046066791905, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 486.5078125, + "max": 637.21484375, + "sum": 1694.0756048387145, + "avg": 564.6918682795696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 480.9765625, + "max": 626.53125, + "sum": 1664.540070564518, + "avg": 554.8466901881724, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T03:59:20.982Z", + "interval_end_time": "2023-04-14T04:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.8251170955222, + "min": 3.23395848808149, + "max": 4.77055224205558, + "avg": 4.27503903184074, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 494.55078125, + "max": 650.2578125, + "sum": 1736.034652217741, + "avg": 578.6782174059143, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 488.2265625, + "max": 640.46875, + "sum": 1704.3125, + "avg": 568.104166666667, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.8251170955222, + "min": 3.23395848808149, + "max": 4.77055224205558, + "avg": 4.27503903184074, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 494.55078125, + "max": 650.2578125, + "sum": 1736.034652217741, + "avg": 578.6782174059143, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 488.2265625, + "max": 640.46875, + "sum": 1704.3125, + "avg": 568.104166666667, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T04:14:20.982Z", + "interval_end_time": "2023-04-14T04:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.3903337685619, + "min": 3.16656801385557, + "max": 4.66166533206296, + "avg": 3.79677792285395, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 494.70703125, + "max": 659.1328125, + "sum": 1749.0136088709642, + "avg": 583.0045362903223, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 488.70703125, + "max": 649.44921875, + "sum": 1718.802167338705, + "avg": 572.9340557795696, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.3903337685619, + "min": 3.16656801385557, + "max": 4.66166533206296, + "avg": 3.79677792285395, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 494.70703125, + "max": 659.1328125, + "sum": 1749.0136088709642, + "avg": 583.0045362903223, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 488.70703125, + "max": 649.44921875, + "sum": 1718.802167338705, + "avg": 572.9340557795696, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T04:29:20.982Z", + "interval_end_time": "2023-04-14T04:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.5014342027542, + "min": 2.23111050125557, + "max": 3.90711991666672, + "avg": 3.1671447342514, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 493.90234375, + "max": 664.98046875, + "sum": 1755.2971270161247, + "avg": 585.0990423387099, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 488.5078125, + "max": 655.546875, + "sum": 1726.4992439516163, + "avg": 575.4997479838714, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.5014342027542, + "min": 2.23111050125557, + "max": 3.90711991666672, + "avg": 3.1671447342514, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 493.90234375, + "max": 664.98046875, + "sum": 1755.2971270161247, + "avg": 585.0990423387099, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 488.5078125, + "max": 655.546875, + "sum": 1726.4992439516163, + "avg": 575.4997479838714, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T04:44:20.982Z", + "interval_end_time": "2023-04-14T04:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.43306912187407, + "min": 2.07185424824816, + "max": 3.06512188040366, + "avg": 2.47768970729136, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 494.13671875, + "max": 676.08203125, + "sum": 1764.3756300403213, + "avg": 588.1252100134411, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 488.59765625, + "max": 665.80859375, + "sum": 1735.278351814518, + "avg": 578.4261172715054, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.43306912187407, + "min": 2.07185424824816, + "max": 3.06512188040366, + "avg": 2.47768970729136, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 494.13671875, + "max": 676.08203125, + "sum": 1764.3756300403213, + "avg": 588.1252100134411, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 488.59765625, + "max": 665.80859375, + "sum": 1735.278351814518, + "avg": 578.4261172715054, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T04:59:20.982Z", + "interval_end_time": "2023-04-14T05:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.1357935901567, + "min": 2.66977707079261, + "max": 3.78942297675185, + "avg": 3.37859786338556, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 503.1796875, + "max": 676.015625, + "sum": 1782.6373487903213, + "avg": 594.2124495967741, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 496.76171875, + "max": 666.15234375, + "sum": 1752.6008064516163, + "avg": 584.2002688172045, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.1357935901567, + "min": 2.66977707079261, + "max": 3.78942297675185, + "avg": 3.37859786338556, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 503.1796875, + "max": 676.015625, + "sum": 1782.6373487903213, + "avg": 594.2124495967741, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 496.76171875, + "max": 666.15234375, + "sum": 1752.6008064516163, + "avg": 584.2002688172045, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T05:14:20.982Z", + "interval_end_time": "2023-04-14T05:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.55468554314938, + "min": 2.74066107575183, + "max": 3.66097612442962, + "avg": 3.18489518104979, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 510.5390625, + "max": 676.0078125, + "sum": 1790.8097278225803, + "avg": 596.9365759408598, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 504.8125, + "max": 666.078125, + "sum": 1760.911542338705, + "avg": 586.9705141129036, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.55468554314938, + "min": 2.74066107575183, + "max": 3.66097612442962, + "avg": 3.18489518104979, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 510.5390625, + "max": 676.0078125, + "sum": 1790.8097278225803, + "avg": 596.9365759408598, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 504.8125, + "max": 666.078125, + "sum": 1760.911542338705, + "avg": 586.9705141129036, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T05:29:20.982Z", + "interval_end_time": "2023-04-14T05:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.07138111892988, + "min": 2.23248651319257, + "max": 3.29872863727775, + "avg": 2.69046037297663, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 516.2109375, + "max": 675.546875, + "sum": 1792.684097782259, + "avg": 597.5613659274196, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 510.23828125, + "max": 665.9296875, + "sum": 1763.5529233870984, + "avg": 587.8509744623651, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.07138111892988, + "min": 2.23248651319257, + "max": 3.29872863727775, + "avg": 2.69046037297663, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 516.2109375, + "max": 675.546875, + "sum": 1792.684097782259, + "avg": 597.5613659274196, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 510.23828125, + "max": 665.9296875, + "sum": 1763.5529233870984, + "avg": 587.8509744623651, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T05:44:20.982Z", + "interval_end_time": "2023-04-14T05:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.4579040636927, + "min": 2.27507910785185, + "max": 5.21721080437036, + "avg": 3.81930135456424, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 516.3515625, + "max": 680.54296875, + "sum": 1805.8592489919376, + "avg": 601.9530829973116, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 510.53125, + "max": 668.9296875, + "sum": 1772.4647177419376, + "avg": 590.8215725806446, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.4579040636927, + "min": 2.27507910785185, + "max": 5.21721080437036, + "avg": 3.81930135456424, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 516.3515625, + "max": 680.54296875, + "sum": 1805.8592489919376, + "avg": 601.9530829973116, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 510.53125, + "max": 668.9296875, + "sum": 1772.4647177419376, + "avg": 590.8215725806446, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T05:59:20.982Z", + "interval_end_time": "2023-04-14T06:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.1769354107975, + "min": 3.25358324688886, + "max": 5.20446525337778, + "avg": 4.05897847026584, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 525.13671875, + "max": 684.7109375, + "sum": 1818.7581905241966, + "avg": 606.2527301747313, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 518.140625, + "max": 671.2890625, + "sum": 1779.1058467741966, + "avg": 593.0352822580643, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.1769354107975, + "min": 3.25358324688886, + "max": 5.20446525337778, + "avg": 4.05897847026584, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 525.13671875, + "max": 684.7109375, + "sum": 1818.7581905241966, + "avg": 606.2527301747313, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 518.140625, + "max": 671.2890625, + "sum": 1779.1058467741966, + "avg": 593.0352822580643, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T06:14:20.982Z", + "interval_end_time": "2023-04-14T06:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.73707889392692, + "min": 2.14165028458147, + "max": 3.99961398575925, + "avg": 2.91235963130897, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 523.6953125, + "max": 684.37890625, + "sum": 1812.4635836693574, + "avg": 604.1545278897848, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 517.6015625, + "max": 671.7265625, + "sum": 1779.0907258064556, + "avg": 593.0302419354839, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.73707889392692, + "min": 2.14165028458147, + "max": 3.99961398575925, + "avg": 2.91235963130897, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 523.6953125, + "max": 684.37890625, + "sum": 1812.4635836693574, + "avg": 604.1545278897848, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 517.6015625, + "max": 671.7265625, + "sum": 1779.0907258064556, + "avg": 593.0302419354839, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T06:29:20.982Z", + "interval_end_time": "2023-04-14T06:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.9635417955321, + "min": 2.21280712303705, + "max": 3.70458764186667, + "avg": 2.98784726517737, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 523.375, + "max": 681.06640625, + "sum": 1809.6016213037585, + "avg": 603.2005404345874, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 517.6015625, + "max": 670.62890625, + "sum": 1778.884551411295, + "avg": 592.9615171370964, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.9635417955321, + "min": 2.21280712303705, + "max": 3.70458764186667, + "avg": 2.98784726517737, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 523.375, + "max": 681.06640625, + "sum": 1809.6016213037585, + "avg": 603.2005404345874, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 517.6015625, + "max": 670.62890625, + "sum": 1778.884551411295, + "avg": 592.9615171370964, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T06:44:20.982Z", + "interval_end_time": "2023-04-14T06:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.22226443660519, + "min": 2.47049967477409, + "max": 3.71793174642592, + "avg": 3.07408814553506, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 522.8359375, + "max": 680.8046875, + "sum": 1807.053301411295, + "avg": 602.3511004704304, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 517.3671875, + "max": 670.48046875, + "sum": 1778.7809979838753, + "avg": 592.9269993279571, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.22226443660519, + "min": 2.47049967477409, + "max": 3.71793174642592, + "avg": 3.07408814553506, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 522.8359375, + "max": 680.8046875, + "sum": 1807.053301411295, + "avg": 602.3511004704304, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 517.3671875, + "max": 670.48046875, + "sum": 1778.7809979838753, + "avg": 592.9269993279571, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T06:59:20.982Z", + "interval_end_time": "2023-04-14T07:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.05406900328592, + "min": 2.46702676600738, + "max": 3.79059665009258, + "avg": 3.01802300109531, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 523.20703125, + "max": 686.9296875, + "sum": 1812.3484122983837, + "avg": 604.1161374327955, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 517.2734375, + "max": 673.3125, + "sum": 1780.4061239919376, + "avg": 593.4687079973116, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.05406900328592, + "min": 2.46702676600738, + "max": 3.79059665009258, + "avg": 3.01802300109531, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 523.20703125, + "max": 686.9296875, + "sum": 1812.3484122983837, + "avg": 604.1161374327955, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 517.2734375, + "max": 673.3125, + "sum": 1780.4061239919376, + "avg": 593.4687079973116, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T07:14:20.982Z", + "interval_end_time": "2023-04-14T07:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.748921211987, + "min": 3.13011860182963, + "max": 3.97355685707039, + "avg": 3.58297373732901, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 529.19921875, + "max": 689.15625, + "sum": 1825.0662802419376, + "avg": 608.3554267473116, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 521.55859375, + "max": 675.6953125, + "sum": 1788.46875, + "avg": 596.15625, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.748921211987, + "min": 3.13011860182963, + "max": 3.97355685707039, + "avg": 3.58297373732901, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 529.19921875, + "max": 689.15625, + "sum": 1825.0662802419376, + "avg": 608.3554267473116, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 521.55859375, + "max": 675.6953125, + "sum": 1788.46875, + "avg": 596.15625, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T07:29:20.982Z", + "interval_end_time": "2023-04-14T07:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.6526740209126, + "min": 3.10204645853336, + "max": 3.9707105071963, + "avg": 3.5508913403042, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 529.12109375, + "max": 691.828125, + "sum": 1828.6769153225803, + "avg": 609.5589717741938, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 521.30078125, + "max": 677.484375, + "sum": 1792.1616683467769, + "avg": 597.387222782258, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.6526740209126, + "min": 3.10204645853336, + "max": 3.9707105071963, + "avg": 3.5508913403042, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 529.12109375, + "max": 691.828125, + "sum": 1828.6769153225803, + "avg": 609.5589717741938, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 521.30078125, + "max": 677.484375, + "sum": 1792.1616683467769, + "avg": 597.387222782258, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T07:44:20.982Z", + "interval_end_time": "2023-04-14T07:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.7631599491053, + "min": 3.18491469815555, + "max": 3.99021273118889, + "avg": 3.5877199830351, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 531.23046875, + "max": 690.40234375, + "sum": 1829.9347278225803, + "avg": 609.9782426075268, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 523.36328125, + "max": 678.2890625, + "sum": 1794.4102822580624, + "avg": 598.1367607526884, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.7631599491053, + "min": 3.18491469815555, + "max": 3.99021273118889, + "avg": 3.5877199830351, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 531.23046875, + "max": 690.40234375, + "sum": 1829.9347278225803, + "avg": 609.9782426075268, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 523.36328125, + "max": 678.2890625, + "sum": 1794.4102822580624, + "avg": 598.1367607526884, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T07:59:20.982Z", + "interval_end_time": "2023-04-14T08:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.7310224917078, + "min": 3.13325848021853, + "max": 3.96387228262223, + "avg": 3.57700749723593, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 531.50390625, + "max": 696.03515625, + "sum": 1838.799395161295, + "avg": 612.9331317204304, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 523.4921875, + "max": 679.8125, + "sum": 1802.1993447580624, + "avg": 600.7331149193554, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.7310224917078, + "min": 3.13325848021853, + "max": 3.96387228262223, + "avg": 3.57700749723593, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 531.50390625, + "max": 696.03515625, + "sum": 1838.799395161295, + "avg": 612.9331317204304, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 523.4921875, + "max": 679.8125, + "sum": 1802.1993447580624, + "avg": 600.7331149193554, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T08:14:20.982Z", + "interval_end_time": "2023-04-14T08:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.62329535628198, + "min": 2.05688880096293, + "max": 3.86548729112595, + "avg": 2.87443178542733, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 540.66015625, + "max": 691.59765625, + "sum": 1844.354964717741, + "avg": 614.7849882392474, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 535.3828125, + "max": 679.9375, + "sum": 1814.6233618951608, + "avg": 604.8744539650536, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.62329535628198, + "min": 2.05688880096293, + "max": 3.86548729112595, + "avg": 2.87443178542733, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 540.66015625, + "max": 691.59765625, + "sum": 1844.354964717741, + "avg": 614.7849882392474, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 535.3828125, + "max": 679.9375, + "sum": 1814.6233618951608, + "avg": 604.8744539650536, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T08:29:20.982Z", + "interval_end_time": "2023-04-14T08:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.15722079557728, + "min": 2.03335331438149, + "max": 4.14853096777041, + "avg": 3.0524069318591, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 540.64453125, + "max": 695.4140625, + "sum": 1876.40625, + "avg": 625.46875, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 535.25390625, + "max": 681.609375, + "sum": 1837.198714717741, + "avg": 612.3995715725804, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.15722079557728, + "min": 2.03335331438149, + "max": 4.14853096777041, + "avg": 3.0524069318591, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 540.64453125, + "max": 695.4140625, + "sum": 1876.40625, + "avg": 625.46875, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 535.25390625, + "max": 681.609375, + "sum": 1837.198714717741, + "avg": 612.3995715725804, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T08:44:20.982Z", + "interval_end_time": "2023-04-14T08:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.16009550522592, + "min": 2.21267326740371, + "max": 4.09413172910001, + "avg": 3.05336516840864, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 544.80859375, + "max": 696.21875, + "sum": 1883.3708417338753, + "avg": 627.7902805779571, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 540.265625, + "max": 682.17578125, + "sum": 1851.9214969758034, + "avg": 617.3071656586018, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.16009550522592, + "min": 2.21267326740371, + "max": 4.09413172910001, + "avg": 3.05336516840864, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 544.80859375, + "max": 696.21875, + "sum": 1883.3708417338753, + "avg": 627.7902805779571, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 540.265625, + "max": 682.17578125, + "sum": 1851.9214969758034, + "avg": 617.3071656586018, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T08:59:20.982Z", + "interval_end_time": "2023-04-14T09:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.05982423239408, + "min": 2.24615530672966, + "max": 3.9812969362333, + "avg": 3.01994141079803, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 544.61328125, + "max": 695.73828125, + "sum": 1886.9499747983837, + "avg": 628.9833249327955, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 539.75390625, + "max": 681.4375, + "sum": 1851.157636088705, + "avg": 617.0525453629026, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.05982423239408, + "min": 2.24615530672966, + "max": 3.9812969362333, + "avg": 3.01994141079803, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 544.61328125, + "max": 695.73828125, + "sum": 1886.9499747983837, + "avg": 628.9833249327955, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 539.75390625, + "max": 681.4375, + "sum": 1851.157636088705, + "avg": 617.0525453629026, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T09:14:20.982Z", + "interval_end_time": "2023-04-14T09:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.9071274727203, + "min": 3.25862739362966, + "max": 4.04602333235186, + "avg": 3.63570915757342, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 556.9765625, + "max": 698.71875, + "sum": 1915.0883316532231, + "avg": 638.362777217742, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 548.3828125, + "max": 684.76953125, + "sum": 1875.245589717741, + "avg": 625.0818632392474, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.9071274727203, + "min": 3.25862739362966, + "max": 4.04602333235186, + "avg": 3.63570915757342, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 556.9765625, + "max": 698.71875, + "sum": 1915.0883316532231, + "avg": 638.362777217742, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 548.3828125, + "max": 684.76953125, + "sum": 1875.245589717741, + "avg": 625.0818632392474, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T09:29:20.982Z", + "interval_end_time": "2023-04-14T09:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.913451177673, + "min": 3.20804799411481, + "max": 4.07098015567414, + "avg": 3.63781705922432, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 583.68359375, + "max": 709.1015625, + "sum": 1937.9122983870984, + "avg": 645.9707661290321, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 574.48046875, + "max": 691.66015625, + "sum": 1897.7899445564556, + "avg": 632.5966481854839, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.913451177673, + "min": 3.20804799411481, + "max": 4.07098015567414, + "avg": 3.63781705922432, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 583.68359375, + "max": 709.1015625, + "sum": 1937.9122983870984, + "avg": 645.9707661290321, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 574.48046875, + "max": 691.66015625, + "sum": 1897.7899445564556, + "avg": 632.5966481854839, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T09:44:20.982Z", + "interval_end_time": "2023-04-14T09:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.5137791759659, + "min": 2.9830304468333, + "max": 4.03336992185192, + "avg": 3.50459305865531, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.28515625, + "max": 714.05859375, + "sum": 1934.5202872983837, + "avg": 644.8400957661295, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.6640625, + "max": 697.23828125, + "sum": 1901.7436995967769, + "avg": 633.914566532258, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.5137791759659, + "min": 2.9830304468333, + "max": 4.03336992185192, + "avg": 3.50459305865531, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.28515625, + "max": 714.05859375, + "sum": 1934.5202872983837, + "avg": 644.8400957661295, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.6640625, + "max": 697.23828125, + "sum": 1901.7436995967769, + "avg": 633.914566532258, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T09:59:20.982Z", + "interval_end_time": "2023-04-14T10:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.334772011927, + "min": 3.01208016822595, + "max": 3.83399587318892, + "avg": 3.44492400397568, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.36328125, + "max": 700.55078125, + "sum": 1927.2738155241966, + "avg": 642.4246051747313, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.53515625, + "max": 691.76171875, + "sum": 1898.2774697580624, + "avg": 632.7591565860214, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.334772011927, + "min": 3.01208016822595, + "max": 3.83399587318892, + "avg": 3.44492400397568, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.36328125, + "max": 700.55078125, + "sum": 1927.2738155241966, + "avg": 642.4246051747313, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.53515625, + "max": 691.76171875, + "sum": 1898.2774697580624, + "avg": 632.7591565860214, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T10:14:20.982Z", + "interval_end_time": "2023-04-14T10:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.2373047261481, + "min": 3.0129144124704, + "max": 3.8386583563074, + "avg": 3.41243490871605, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.45703125, + "max": 699.578125, + "sum": 1926.7009828629016, + "avg": 642.2336609543008, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.43359375, + "max": 690.1796875, + "sum": 1897.559601814518, + "avg": 632.5198672715054, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.2373047261481, + "min": 3.0129144124704, + "max": 3.8386583563074, + "avg": 3.41243490871605, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.45703125, + "max": 699.578125, + "sum": 1926.7009828629016, + "avg": 642.2336609543008, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.43359375, + "max": 690.1796875, + "sum": 1897.559601814518, + "avg": 632.5198672715054, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T10:29:20.982Z", + "interval_end_time": "2023-04-14T10:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.3677284877604, + "min": 2.96829540441853, + "max": 3.84416734849629, + "avg": 3.45590949592013, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.33203125, + "max": 699.671875, + "sum": 1927.2884324596787, + "avg": 642.4294774865589, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.35546875, + "max": 689.9140625, + "sum": 1896.942414314518, + "avg": 632.3141381048383, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.3677284877604, + "min": 2.96829540441853, + "max": 3.84416734849629, + "avg": 3.45590949592013, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.33203125, + "max": 699.671875, + "sum": 1927.2884324596787, + "avg": 642.4294774865589, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.35546875, + "max": 689.9140625, + "sum": 1896.942414314518, + "avg": 632.3141381048383, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T10:44:20.982Z", + "interval_end_time": "2023-04-14T10:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.4170744901365, + "min": 3.07377479822969, + "max": 3.87213772268884, + "avg": 3.47235816337885, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.66015625, + "max": 700.13671875, + "sum": 1929.4209929435444, + "avg": 643.1403309811831, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.45703125, + "max": 689.4296875, + "sum": 1897.0625, + "avg": 632.354166666667, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.4170744901365, + "min": 3.07377479822969, + "max": 3.87213772268884, + "avg": 3.47235816337885, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 581.66015625, + "max": 700.13671875, + "sum": 1929.4209929435444, + "avg": 643.1403309811831, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.45703125, + "max": 689.4296875, + "sum": 1897.0625, + "avg": 632.354166666667, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T10:59:20.982Z", + "interval_end_time": "2023-04-14T11:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.00094267493246, + "min": 2.1490613836407, + "max": 3.84200228375557, + "avg": 2.66698089164415, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 582.34375, + "max": 701.4453125, + "sum": 1929.3668094758034, + "avg": 643.1222698252687, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.66796875, + "max": 689.4453125, + "sum": 1897.686113911295, + "avg": 632.5620379704304, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.00094267493246, + "min": 2.1490613836407, + "max": 3.84200228375557, + "avg": 2.66698089164415, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 582.34375, + "max": 701.4453125, + "sum": 1929.3668094758034, + "avg": 643.1222698252687, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.66796875, + "max": 689.4453125, + "sum": 1897.686113911295, + "avg": 632.5620379704304, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T11:14:20.982Z", + "interval_end_time": "2023-04-14T11:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.0856279078068, + "min": 2.21310629708891, + "max": 5.00496882604817, + "avg": 4.0285426359356, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 583.0078125, + "max": 703.1796875, + "sum": 1940.4615675403213, + "avg": 646.8205225134411, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.81640625, + "max": 690.0546875, + "sum": 1905.545866935482, + "avg": 635.1819556451617, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.0856279078068, + "min": 2.21310629708891, + "max": 5.00496882604817, + "avg": 4.0285426359356, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 583.0078125, + "max": 703.1796875, + "sum": 1940.4615675403213, + "avg": 646.8205225134411, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 575.81640625, + "max": 690.0546875, + "sum": 1905.545866935482, + "avg": 635.1819556451617, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T11:29:20.982Z", + "interval_end_time": "2023-04-14T11:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.1477041407654, + "min": 3.15427694251121, + "max": 4.71658542189258, + "avg": 3.71590138025515, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 584.46875, + "max": 700.734375, + "sum": 1941.6325604838753, + "avg": 647.2108534946242, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 576.7578125, + "max": 690.6171875, + "sum": 1909.1512096774197, + "avg": 636.3837365591402, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.1477041407654, + "min": 3.15427694251121, + "max": 4.71658542189258, + "avg": 3.71590138025515, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 584.46875, + "max": 700.734375, + "sum": 1941.6325604838753, + "avg": 647.2108534946242, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 576.7578125, + "max": 690.6171875, + "sum": 1909.1512096774197, + "avg": 636.3837365591402, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T11:44:20.982Z", + "interval_end_time": "2023-04-14T11:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.08913062436407, + "min": 2.1663344800704, + "max": 3.80971794644806, + "avg": 2.69637687478802, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 583.7109375, + "max": 700.2890625, + "sum": 1940.0672883064556, + "avg": 646.68909610215, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 577.4140625, + "max": 690.5859375, + "sum": 1910.522933467741, + "avg": 636.8409778225804, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.08913062436407, + "min": 2.1663344800704, + "max": 3.80971794644806, + "avg": 2.69637687478802, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 583.7109375, + "max": 700.2890625, + "sum": 1940.0672883064556, + "avg": 646.68909610215, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 577.4140625, + "max": 690.5859375, + "sum": 1910.522933467741, + "avg": 636.8409778225804, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T11:59:20.982Z", + "interval_end_time": "2023-04-14T12:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.4725226309758, + "min": 2.1357842092814, + "max": 3.76223526866665, + "avg": 3.1575075436586, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 583.9921875, + "max": 701.73046875, + "sum": 1944.325226814518, + "avg": 648.1084089381724, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 577.46875, + "max": 691.046875, + "sum": 1911.3967993951608, + "avg": 637.1322664650536, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.4725226309758, + "min": 2.1357842092814, + "max": 3.76223526866665, + "avg": 3.1575075436586, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 583.9921875, + "max": 701.73046875, + "sum": 1944.325226814518, + "avg": 648.1084089381724, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 577.46875, + "max": 691.046875, + "sum": 1911.3967993951608, + "avg": 637.1322664650536, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T12:14:20.982Z", + "interval_end_time": "2023-04-14T12:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.0524877211616, + "min": 2.87703812444449, + "max": 3.7929688102556, + "avg": 3.3508292403872, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 584.29296875, + "max": 701.9296875, + "sum": 1943.7375252016163, + "avg": 647.9125084005375, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.1796875, + "max": 691.27734375, + "sum": 1912.4357358870984, + "avg": 637.4785786290321, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.0524877211616, + "min": 2.87703812444449, + "max": 3.7929688102556, + "avg": 3.3508292403872, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 584.29296875, + "max": 701.9296875, + "sum": 1943.7375252016163, + "avg": 647.9125084005375, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.1796875, + "max": 691.27734375, + "sum": 1912.4357358870984, + "avg": 637.4785786290321, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T12:29:20.982Z", + "interval_end_time": "2023-04-14T12:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.90843343750581, + "min": 2.14200564715181, + "max": 3.52121458107409, + "avg": 2.6361444791686, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 584.1796875, + "max": 701.68359375, + "sum": 1942.852066532259, + "avg": 647.6173555107526, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.23046875, + "max": 691.83203125, + "sum": 1912.8453881048392, + "avg": 637.6151293682794, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.90843343750581, + "min": 2.14200564715181, + "max": 3.52121458107409, + "avg": 2.6361444791686, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 584.1796875, + "max": 701.68359375, + "sum": 1942.852066532259, + "avg": 647.6173555107526, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.23046875, + "max": 691.83203125, + "sum": 1912.8453881048392, + "avg": 637.6151293682794, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T12:44:20.982Z", + "interval_end_time": "2023-04-14T12:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.71381415422864, + "min": 2.15790548954812, + "max": 3.97823024805931, + "avg": 3.23793805140955, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 584.921875, + "max": 703.92578125, + "sum": 1945.9642137096787, + "avg": 648.6547379032259, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.3046875, + "max": 692.7421875, + "sum": 1914.073210685482, + "avg": 638.0244035618276, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.71381415422864, + "min": 2.15790548954812, + "max": 3.97823024805931, + "avg": 3.23793805140955, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 584.921875, + "max": 703.92578125, + "sum": 1945.9642137096787, + "avg": 648.6547379032259, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.3046875, + "max": 692.7421875, + "sum": 1914.073210685482, + "avg": 638.0244035618276, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T12:59:20.982Z", + "interval_end_time": "2023-04-14T13:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.5451647607294, + "min": 3.12512637135558, + "max": 3.86204776687783, + "avg": 3.51505492024313, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 585.3515625, + "max": 703.87890625, + "sum": 1947.2176159274197, + "avg": 649.0725386424732, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.6171875, + "max": 693.7890625, + "sum": 1915.7574344758034, + "avg": 638.5858114919357, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.5451647607294, + "min": 3.12512637135558, + "max": 3.86204776687783, + "avg": 3.51505492024313, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 585.3515625, + "max": 703.87890625, + "sum": 1947.2176159274197, + "avg": 649.0725386424732, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.6171875, + "max": 693.7890625, + "sum": 1915.7574344758034, + "avg": 638.5858114919357, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T13:14:20.982Z", + "interval_end_time": "2023-04-14T13:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.03849701442754, + "min": 2.03413861009262, + "max": 3.90778873488512, + "avg": 2.67949900480918, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 585.10546875, + "max": 705.7734375, + "sum": 1948.2381552419376, + "avg": 649.4127184139786, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.625, + "max": 695.53515625, + "sum": 1917.475176411295, + "avg": 639.1583921370974, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.03849701442754, + "min": 2.03413861009262, + "max": 3.90778873488512, + "avg": 2.67949900480918, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 585.10546875, + "max": 705.7734375, + "sum": 1948.2381552419376, + "avg": 649.4127184139786, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.625, + "max": 695.53515625, + "sum": 1917.475176411295, + "avg": 639.1583921370974, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T13:29:20.982Z", + "interval_end_time": "2023-04-14T13:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.16431375389765, + "min": 2.01623494006667, + "max": 3.70945589486294, + "avg": 3.05477125129922, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 585.0703125, + "max": 706.13671875, + "sum": 1952.1539818548392, + "avg": 650.7179939516125, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.94921875, + "max": 696.1328125, + "sum": 1920.5725806451608, + "avg": 640.1908602150536, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.16431375389765, + "min": 2.01623494006667, + "max": 3.70945589486294, + "avg": 3.05477125129922, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 585.0703125, + "max": 706.13671875, + "sum": 1952.1539818548392, + "avg": 650.7179939516125, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 578.94921875, + "max": 696.1328125, + "sum": 1920.5725806451608, + "avg": 640.1908602150536, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T13:44:20.982Z", + "interval_end_time": "2023-04-14T13:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.458832859871, + "min": 3.0186840297333, + "max": 3.90330548338146, + "avg": 3.486277619957, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 586.48828125, + "max": 706.55859375, + "sum": 1953.346270161295, + "avg": 651.1154233870964, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.7734375, + "max": 696.05859375, + "sum": 1921.781754032259, + "avg": 640.5939180107526, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.458832859871, + "min": 3.0186840297333, + "max": 3.90330548338146, + "avg": 3.486277619957, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 586.48828125, + "max": 706.55859375, + "sum": 1953.346270161295, + "avg": 651.1154233870964, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.7734375, + "max": 696.05859375, + "sum": 1921.781754032259, + "avg": 640.5939180107526, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T13:59:20.982Z", + "interval_end_time": "2023-04-14T14:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.53227033687927, + "min": 2.23295641035182, + "max": 3.90809862530743, + "avg": 2.84409011229309, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 585.78515625, + "max": 705.85546875, + "sum": 1951.542464717741, + "avg": 650.5141549059143, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.4765625, + "max": 695.55859375, + "sum": 1920.9435483870984, + "avg": 640.3145161290321, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.53227033687927, + "min": 2.23295641035182, + "max": 3.90809862530743, + "avg": 2.84409011229309, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 585.78515625, + "max": 705.85546875, + "sum": 1951.542464717741, + "avg": 650.5141549059143, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.4765625, + "max": 695.55859375, + "sum": 1920.9435483870984, + "avg": 640.3145161290321, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T14:14:20.982Z", + "interval_end_time": "2023-04-14T14:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.3105670961746, + "min": 2.28138709989251, + "max": 4.91107536171481, + "avg": 3.77018903205819, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 586.0625, + "max": 706.8671875, + "sum": 1953.272051411295, + "avg": 651.0906838037633, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.4765625, + "max": 695.734375, + "sum": 1920.9940776209642, + "avg": 640.3313592069893, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.3105670961746, + "min": 2.28138709989251, + "max": 4.91107536171481, + "avg": 3.77018903205819, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 586.0625, + "max": 706.8671875, + "sum": 1953.272051411295, + "avg": 651.0906838037633, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.4765625, + "max": 695.734375, + "sum": 1920.9940776209642, + "avg": 640.3313592069893, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T14:29:20.982Z", + "interval_end_time": "2023-04-14T14:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.6351519346616, + "min": 3.29073386108891, + "max": 5.0519409623481, + "avg": 3.87838397822053, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 586.80859375, + "max": 706.3984375, + "sum": 1953.6118951612855, + "avg": 651.2039650537633, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.51171875, + "max": 695.9765625, + "sum": 1921.8780241935444, + "avg": 640.6260080645161, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.6351519346616, + "min": 3.29073386108891, + "max": 5.0519409623481, + "avg": 3.87838397822053, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 586.80859375, + "max": 706.3984375, + "sum": 1953.6118951612855, + "avg": 651.2039650537633, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.51171875, + "max": 695.9765625, + "sum": 1921.8780241935444, + "avg": 640.6260080645161, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T14:44:20.982Z", + "interval_end_time": "2023-04-14T14:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.47149154645631, + "min": 2.11797208714081, + "max": 3.87644002308155, + "avg": 2.82383051548544, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 586.94140625, + "max": 706.625, + "sum": 1953.4712701612855, + "avg": 651.1570900537633, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.8984375, + "max": 696.015625, + "sum": 1922.2391633064556, + "avg": 640.7463877688169, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.47149154645631, + "min": 2.11797208714081, + "max": 3.87644002308155, + "avg": 2.82383051548544, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 586.94140625, + "max": 706.625, + "sum": 1953.4712701612855, + "avg": 651.1570900537633, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 579.8984375, + "max": 696.015625, + "sum": 1922.2391633064556, + "avg": 640.7463877688169, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T14:59:20.982Z", + "interval_end_time": "2023-04-14T15:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.21809724495517, + "min": 2.26505906991111, + "max": 3.68395089868152, + "avg": 3.07269908165172, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 587.91796875, + "max": 712.33203125, + "sum": 1958.6911542338753, + "avg": 652.8970514112901, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 581.1015625, + "max": 699.13671875, + "sum": 1925.9162046370984, + "avg": 641.9720682123661, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.21809724495517, + "min": 2.26505906991111, + "max": 3.68395089868152, + "avg": 3.07269908165172, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 587.91796875, + "max": 712.33203125, + "sum": 1958.6911542338753, + "avg": 652.8970514112901, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 581.1015625, + "max": 699.13671875, + "sum": 1925.9162046370984, + "avg": 641.9720682123661, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T15:14:20.982Z", + "interval_end_time": "2023-04-14T15:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.5926810157483, + "min": 3.15093494377043, + "max": 4.04325676777031, + "avg": 3.53089367191609, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 588.98828125, + "max": 711.62109375, + "sum": 1965.8360635080624, + "avg": 655.2786878360214, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 582.46484375, + "max": 699.5234375, + "sum": 1930.1082409274197, + "avg": 643.3694136424732, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.5926810157483, + "min": 3.15093494377043, + "max": 4.04325676777031, + "avg": 3.53089367191609, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 588.98828125, + "max": 711.62109375, + "sum": 1965.8360635080624, + "avg": 655.2786878360214, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 582.46484375, + "max": 699.5234375, + "sum": 1930.1082409274197, + "avg": 643.3694136424732, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T15:29:20.982Z", + "interval_end_time": "2023-04-14T15:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.64368714286926, + "min": 2.24967557978525, + "max": 3.9592644776112, + "avg": 2.88122904762309, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 589.7578125, + "max": 711.3125, + "sum": 1963.3489163306426, + "avg": 654.4496387768812, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 583.875, + "max": 699.796875, + "sum": 1932.0260836693574, + "avg": 644.0086945564518, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.64368714286926, + "min": 2.24967557978525, + "max": 3.9592644776112, + "avg": 2.88122904762309, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 589.7578125, + "max": 711.3125, + "sum": 1963.3489163306426, + "avg": 654.4496387768812, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 583.875, + "max": 699.796875, + "sum": 1932.0260836693574, + "avg": 644.0086945564518, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T15:44:20.982Z", + "interval_end_time": "2023-04-14T15:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.4050785602907, + "min": 2.22315159918896, + "max": 5.22983893591488, + "avg": 3.80169285343025, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 589.23828125, + "max": 713.2890625, + "sum": 1964.893523185482, + "avg": 654.9645077284946, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 583.0234375, + "max": 700.1640625, + "sum": 1931.3766381048392, + "avg": 643.7922127016134, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.4050785602907, + "min": 2.22315159918896, + "max": 5.22983893591488, + "avg": 3.80169285343025, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 589.23828125, + "max": 713.2890625, + "sum": 1964.893523185482, + "avg": 654.9645077284946, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 583.0234375, + "max": 700.1640625, + "sum": 1931.3766381048392, + "avg": 643.7922127016134, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T15:59:20.982Z", + "interval_end_time": "2023-04-14T16:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.2353137862839, + "min": 3.43897659853694, + "max": 5.12842233671119, + "avg": 4.07843792876132, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 590.56640625, + "max": 712.30078125, + "sum": 1969.35546875, + "avg": 656.451822916667, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 583.15234375, + "max": 700.79296875, + "sum": 1934.6273941532231, + "avg": 644.875798051075, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.2353137862839, + "min": 3.43897659853694, + "max": 5.12842233671119, + "avg": 4.07843792876132, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 590.56640625, + "max": 712.30078125, + "sum": 1969.35546875, + "avg": 656.451822916667, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 583.15234375, + "max": 700.79296875, + "sum": 1934.6273941532231, + "avg": 644.875798051075, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T16:14:20.982Z", + "interval_end_time": "2023-04-14T16:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.7793188497863, + "min": 2.16661255676299, + "max": 3.87875162170741, + "avg": 2.92643961659543, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 591.5859375, + "max": 711.890625, + "sum": 1966.4546370967769, + "avg": 655.484879032258, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 585.54296875, + "max": 700.8203125, + "sum": 1935.6321824596787, + "avg": 645.2107274865589, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.7793188497863, + "min": 2.16661255676299, + "max": 3.87875162170741, + "avg": 2.92643961659543, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 591.5859375, + "max": 711.890625, + "sum": 1966.4546370967769, + "avg": 655.484879032258, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 585.54296875, + "max": 700.8203125, + "sum": 1935.6321824596787, + "avg": 645.2107274865589, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T16:29:20.982Z", + "interval_end_time": "2023-04-14T16:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.04291315149839, + "min": 2.20755518967409, + "max": 3.75499438936294, + "avg": 3.0143043838328, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 591.69140625, + "max": 719.515625, + "sum": 1974.7953629032231, + "avg": 658.265120967742, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 585.56640625, + "max": 703.546875, + "sum": 1939.3046875, + "avg": 646.434895833333, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.04291315149839, + "min": 2.20755518967409, + "max": 3.75499438936294, + "avg": 3.0143043838328, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 591.69140625, + "max": 719.515625, + "sum": 1974.7953629032231, + "avg": 658.265120967742, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 585.56640625, + "max": 703.546875, + "sum": 1939.3046875, + "avg": 646.434895833333, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T16:44:20.982Z", + "interval_end_time": "2023-04-14T16:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.5671862739724, + "min": 3.08753737648151, + "max": 3.88855943243338, + "avg": 3.52239542465745, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 596.3359375, + "max": 715.51171875, + "sum": 1977.8702116935444, + "avg": 659.2900705645161, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 589.1484375, + "max": 703.3359375, + "sum": 1942.8647933467769, + "avg": 647.621597782258, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.5671862739724, + "min": 3.08753737648151, + "max": 3.88855943243338, + "avg": 3.52239542465745, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 596.3359375, + "max": 715.51171875, + "sum": 1977.8702116935444, + "avg": 659.2900705645161, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 589.1484375, + "max": 703.3359375, + "sum": 1942.8647933467769, + "avg": 647.621597782258, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T16:59:20.982Z", + "interval_end_time": "2023-04-14T17:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.77283014256012, + "min": 2.22594466240747, + "max": 3.91171864267036, + "avg": 2.92427671418671, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 595.09375, + "max": 714.77734375, + "sum": 1973.9478326612855, + "avg": 657.9826108870964, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 588.890625, + "max": 703.39453125, + "sum": 1942.2434475806426, + "avg": 647.4144825268821, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.77283014256012, + "min": 2.22594466240747, + "max": 3.91171864267036, + "avg": 2.92427671418671, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 595.09375, + "max": 714.77734375, + "sum": 1973.9478326612855, + "avg": 657.9826108870964, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 588.890625, + "max": 703.39453125, + "sum": 1942.2434475806426, + "avg": 647.4144825268821, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T17:14:20.982Z", + "interval_end_time": "2023-04-14T17:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.8640609704824, + "min": 2.24353211339999, + "max": 5.06897459706665, + "avg": 3.62135365682745, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 595.0859375, + "max": 716.28125, + "sum": 1979.0505292338753, + "avg": 659.6835097446242, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 588.92578125, + "max": 703.24609375, + "sum": 1945.008316532259, + "avg": 648.3361055107526, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.8640609704824, + "min": 2.24353211339999, + "max": 5.06897459706665, + "avg": 3.62135365682745, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 595.0859375, + "max": 716.28125, + "sum": 1979.0505292338753, + "avg": 659.6835097446242, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 588.92578125, + "max": 703.24609375, + "sum": 1945.008316532259, + "avg": 648.3361055107526, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T17:29:20.982Z", + "interval_end_time": "2023-04-14T17:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.303771608827, + "min": 3.19303099134812, + "max": 5.27164915240741, + "avg": 4.10125720294234, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 600.7890625, + "max": 720.25390625, + "sum": 1983.504410282259, + "avg": 661.1681367607526, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 593.32421875, + "max": 704.83203125, + "sum": 1948.3068296370984, + "avg": 649.4356098790321, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.303771608827, + "min": 3.19303099134812, + "max": 5.27164915240741, + "avg": 4.10125720294234, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 600.7890625, + "max": 720.25390625, + "sum": 1983.504410282259, + "avg": 661.1681367607526, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 593.32421875, + "max": 704.83203125, + "sum": 1948.3068296370984, + "avg": 649.4356098790321, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T17:44:20.982Z", + "interval_end_time": "2023-04-14T17:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.88046177254543, + "min": 2.21091980862957, + "max": 3.79593948783704, + "avg": 2.96015392418181, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 600.9609375, + "max": 717.27734375, + "sum": 1981.827116935482, + "avg": 660.6090389784946, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 593.61328125, + "max": 705.05859375, + "sum": 1949.7668850806426, + "avg": 649.9222950268821, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.88046177254543, + "min": 2.21091980862957, + "max": 3.79593948783704, + "avg": 2.96015392418181, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 600.9609375, + "max": 717.27734375, + "sum": 1981.827116935482, + "avg": 660.6090389784946, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 593.61328125, + "max": 705.05859375, + "sum": 1949.7668850806426, + "avg": 649.9222950268821, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T17:59:20.982Z", + "interval_end_time": "2023-04-14T18:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.94958328393977, + "min": 2.24761090759259, + "max": 3.8150791290186, + "avg": 2.98319442797992, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 601.1875, + "max": 717.3984375, + "sum": 1986.6217237903213, + "avg": 662.2072412634411, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 595.171875, + "max": 705.0859375, + "sum": 1951.9397681451608, + "avg": 650.6465893817206, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.94958328393977, + "min": 2.24761090759259, + "max": 3.8150791290186, + "avg": 2.98319442797992, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 601.1875, + "max": 717.3984375, + "sum": 1986.6217237903213, + "avg": 662.2072412634411, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 595.171875, + "max": 705.0859375, + "sum": 1951.9397681451608, + "avg": 650.6465893817206, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T18:14:20.982Z", + "interval_end_time": "2023-04-14T18:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.6959422357652, + "min": 3.16705717062588, + "max": 4.00928962749259, + "avg": 3.56531407858839, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 606.0234375, + "max": 718.52734375, + "sum": 1993.9778225806426, + "avg": 664.6592741935482, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 597.96875, + "max": 705.609375, + "sum": 1956.986895161295, + "avg": 652.3289650537633, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.6959422357652, + "min": 3.16705717062588, + "max": 4.00928962749259, + "avg": 3.56531407858839, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 606.0234375, + "max": 718.52734375, + "sum": 1993.9778225806426, + "avg": 664.6592741935482, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 597.96875, + "max": 705.609375, + "sum": 1956.986895161295, + "avg": 652.3289650537633, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T18:29:20.982Z", + "interval_end_time": "2023-04-14T18:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.18414829603026, + "min": 2.21657201254436, + "max": 3.96953617514077, + "avg": 3.06138276534342, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 605.34375, + "max": 718.76953125, + "sum": 1990.8679435483837, + "avg": 663.6226478494625, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 599.55859375, + "max": 705.64453125, + "sum": 1957.7373991935444, + "avg": 652.5791330645161, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.18414829603026, + "min": 2.21657201254436, + "max": 3.96953617514077, + "avg": 3.06138276534342, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 605.34375, + "max": 718.76953125, + "sum": 1990.8679435483837, + "avg": 663.6226478494625, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 599.55859375, + "max": 705.64453125, + "sum": 1957.7373991935444, + "avg": 652.5791330645161, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T18:44:20.982Z", + "interval_end_time": "2023-04-14T18:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.4773938469727, + "min": 2.22080172608882, + "max": 5.07865683601477, + "avg": 3.49246461565757, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 605.7578125, + "max": 723.578125, + "sum": 1999.2072832661247, + "avg": 666.4024277553768, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 599.40234375, + "max": 707.52734375, + "sum": 1963.6956905241966, + "avg": 654.5652301747313, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.4773938469727, + "min": 2.22080172608882, + "max": 5.07865683601477, + "avg": 3.49246461565757, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 605.7578125, + "max": 723.578125, + "sum": 1999.2072832661247, + "avg": 666.4024277553768, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 599.40234375, + "max": 707.52734375, + "sum": 1963.6956905241966, + "avg": 654.5652301747313, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T18:59:20.982Z", + "interval_end_time": "2023-04-14T19:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.8896534244778, + "min": 3.47680979265187, + "max": 5.1807445324371, + "avg": 4.2965511414926, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 614.703125, + "max": 722.19140625, + "sum": 2010.5089465725803, + "avg": 670.1696488575268, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 606.5078125, + "max": 708.6484375, + "sum": 1970.5293598790358, + "avg": 656.8431199596777, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.8896534244778, + "min": 3.47680979265187, + "max": 5.1807445324371, + "avg": 4.2965511414926, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 614.703125, + "max": 722.19140625, + "sum": 2010.5089465725803, + "avg": 670.1696488575268, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 606.5078125, + "max": 708.6484375, + "sum": 1970.5293598790358, + "avg": 656.8431199596777, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T19:14:20.982Z", + "interval_end_time": "2023-04-14T19:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.50028536230247, + "min": 2.17673640065563, + "max": 4.18001101019262, + "avg": 3.16676178743416, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 611.86328125, + "max": 722.64453125, + "sum": 2003.563004032259, + "avg": 667.8543346774196, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 606.41015625, + "max": 708.66796875, + "sum": 1969.5727066532231, + "avg": 656.524235551075, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.50028536230247, + "min": 2.17673640065563, + "max": 4.18001101019262, + "avg": 3.16676178743416, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 611.86328125, + "max": 722.64453125, + "sum": 2003.563004032259, + "avg": 667.8543346774196, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 606.41015625, + "max": 708.66796875, + "sum": 1969.5727066532231, + "avg": 656.524235551075, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T19:29:20.982Z", + "interval_end_time": "2023-04-14T19:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 0.008612013913388, + "min": 0.000361107147235, + "max": 0.003050324185815, + "avg": 0.001435335652231, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 0.0, + "max": 1330.0234375, + "sum": 3606.66143465909, + "avg": 601.110239109849, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 0.0, + "max": 1320.109375, + "sum": 3502.236328125, + "avg": 583.7060546875, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 0.008612013913388, + "min": 0.000361107147235, + "max": 0.003050324185815, + "avg": 0.001435335652231, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 0.0, + "max": 1330.0234375, + "sum": 3606.66143465909, + "avg": 601.110239109849, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 0.0, + "max": 1320.109375, + "sum": 3502.236328125, + "avg": 583.7060546875, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T19:44:20.982Z", + "interval_end_time": "2023-04-14T19:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.00125369576092, + "max": 0.00125369576092, + "avg": 0.000417898586973, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.23642774156611, + "min": 0.122641301400588, + "max": 4.05884393815185, + "avg": 3.0788092471887, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 194.62890625, + "max": 290.046875, + "sum": 730.8758820564518, + "avg": 243.62529401881696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 187.2265625, + "max": 281.9921875, + "sum": 701.5254536290321, + "avg": 233.84181787634373, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.00125369576092, + "max": 0.00125369576092, + "avg": 0.000417898586973, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.23642774156611, + "min": 0.122641301400588, + "max": 4.05884393815185, + "avg": 3.0788092471887, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 194.62890625, + "max": 290.046875, + "sum": 730.8758820564518, + "avg": 243.62529401881696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 187.2265625, + "max": 281.9921875, + "sum": 701.5254536290321, + "avg": 233.84181787634373, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T19:59:20.982Z", + "interval_end_time": "2023-04-14T20:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.04609118991037, + "min": 2.34309635937407, + "max": 3.88964089192222, + "avg": 3.01536372997012, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 229.984375, + "max": 314.703125, + "sum": 828.3160282258062, + "avg": 276.1053427419357, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 225.0703125, + "max": 307.4921875, + "sum": 799.6636844758062, + "avg": 266.5545614919357, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.04609118991037, + "min": 2.34309635937407, + "max": 3.88964089192222, + "avg": 3.01536372997012, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 229.984375, + "max": 314.703125, + "sum": 828.3160282258062, + "avg": 276.1053427419357, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 225.0703125, + "max": 307.4921875, + "sum": 799.6636844758062, + "avg": 266.5545614919357, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T20:14:20.982Z", + "interval_end_time": "2023-04-14T20:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.112328922496552, + "max": 0.085147492862069, + "avg": 0.037442974165517, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.46914730046654, + "min": 2.30112868885926, + "max": 4.58010182155185, + "avg": 2.82304910015551, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 251.234375, + "max": 346.984375, + "sum": 890.1745211693544, + "avg": 296.7248403897848, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 246.47265625, + "max": 335.62109375, + "sum": 859.1034526209679, + "avg": 286.3678175403223, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.112328922496552, + "max": 0.085147492862069, + "avg": 0.037442974165517, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.46914730046654, + "min": 2.30112868885926, + "max": 4.58010182155185, + "avg": 2.82304910015551, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 251.234375, + "max": 346.984375, + "sum": 890.1745211693544, + "avg": 296.7248403897848, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 246.47265625, + "max": 335.62109375, + "sum": 859.1034526209679, + "avg": 286.3678175403223, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T20:29:20.982Z", + "interval_end_time": "2023-04-14T20:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 13.2376485156556, + "min": 3.91502781582593, + "max": 4.85605234033704, + "avg": 4.41254950521852, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 271.42578125, + "max": 347.83984375, + "sum": 952.2685231854839, + "avg": 317.4228410618277, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 265.5390625, + "max": 338.46875, + "sum": 918.4469506048393, + "avg": 306.14898353494647, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 13.2376485156556, + "min": 3.91502781582593, + "max": 4.85605234033704, + "avg": 4.41254950521852, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 271.42578125, + "max": 347.83984375, + "sum": 952.2685231854839, + "avg": 317.4228410618277, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 265.5390625, + "max": 338.46875, + "sum": 918.4469506048393, + "avg": 306.14898353494647, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T20:44:20.982Z", + "interval_end_time": "2023-04-14T20:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.3112178759358, + "min": 3.33503295274444, + "max": 4.81386723182222, + "avg": 3.77040595864527, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 271.59375, + "max": 356.5390625, + "sum": 989.438004032259, + "avg": 329.8126680107527, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 265.66796875, + "max": 348.39453125, + "sum": 956.612777217741, + "avg": 318.8709257392473, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.3112178759358, + "min": 3.33503295274444, + "max": 4.81386723182222, + "avg": 3.77040595864527, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 271.59375, + "max": 356.5390625, + "sum": 989.438004032259, + "avg": 329.8126680107527, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 265.66796875, + "max": 348.39453125, + "sum": 956.612777217741, + "avg": 318.8709257392473, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T20:59:20.982Z", + "interval_end_time": "2023-04-14T21:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.23973705240321, + "min": 2.23026164174074, + "max": 3.92129674667037, + "avg": 3.07991235080107, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 290.625, + "max": 359.1015625, + "sum": 1001.7091733870983, + "avg": 333.9030577956991, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 286.27734375, + "max": 350.00390625, + "sum": 970.1455393145179, + "avg": 323.3818464381723, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 9.23973705240321, + "min": 2.23026164174074, + "max": 3.92129674667037, + "avg": 3.07991235080107, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 290.625, + "max": 359.1015625, + "sum": 1001.7091733870983, + "avg": 333.9030577956991, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 286.27734375, + "max": 350.00390625, + "sum": 970.1455393145179, + "avg": 323.3818464381723, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T21:14:20.982Z", + "interval_end_time": "2023-04-14T21:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.004116689491954, + "max": 0.002598697606897, + "avg": 0.001372229830651, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.87229159665284, + "min": 2.21689067767037, + "max": 3.59979932507037, + "avg": 2.62409719888428, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 295.34765625, + "max": 398.4921875, + "sum": 1034.1706149193574, + "avg": 344.7235383064518, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 291.51953125, + "max": 380.515625, + "sum": 1001.016129032259, + "avg": 333.6720430107527, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.004116689491954, + "max": 0.002598697606897, + "avg": 0.001372229830651, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.87229159665284, + "min": 2.21689067767037, + "max": 3.59979932507037, + "avg": 2.62409719888428, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 295.34765625, + "max": 398.4921875, + "sum": 1034.1706149193574, + "avg": 344.7235383064518, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 291.51953125, + "max": 380.515625, + "sum": 1001.016129032259, + "avg": 333.6720430107527, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T21:29:20.982Z", + "interval_end_time": "2023-04-14T21:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.6005743048741, + "min": 3.21516195458148, + "max": 3.92478116602223, + "avg": 3.53352476829136, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 329.65625, + "max": 390.6953125, + "sum": 1104.1881300403213, + "avg": 368.06271001344106, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 322.6484375, + "max": 382.08203125, + "sum": 1068.776839717741, + "avg": 356.2589465725803, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.6005743048741, + "min": 3.21516195458148, + "max": 3.92478116602223, + "avg": 3.53352476829136, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 329.65625, + "max": 390.6953125, + "sum": 1104.1881300403213, + "avg": 368.06271001344106, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 322.6484375, + "max": 382.08203125, + "sum": 1068.776839717741, + "avg": 356.2589465725803, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T21:44:20.982Z", + "interval_end_time": "2023-04-14T21:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.9410424960665, + "min": 3.18957297767777, + "max": 4.02861094841482, + "avg": 3.64701416535551, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 329.8359375, + "max": 446.5625, + "sum": 1225.6387348790358, + "avg": 408.5462449596777, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 323.28125, + "max": 431.42578125, + "sum": 1183.387726814518, + "avg": 394.4625756048384, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.9410424960665, + "min": 3.18957297767777, + "max": 4.02861094841482, + "avg": 3.64701416535551, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 329.8359375, + "max": 446.5625, + "sum": 1225.6387348790358, + "avg": 408.5462449596777, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 323.28125, + "max": 431.42578125, + "sum": 1183.387726814518, + "avg": 394.4625756048384, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T21:59:20.982Z", + "interval_end_time": "2023-04-14T22:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.18851521172901, + "min": 2.23911712425925, + "max": 3.99740168404445, + "avg": 2.72950507057634, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 417.515625, + "max": 472.35546875, + "sum": 1332.7711693548392, + "avg": 444.25705645161344, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 410.34765625, + "max": 461.05078125, + "sum": 1294.0414566532231, + "avg": 431.34715221774195, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 8.18851521172901, + "min": 2.23911712425925, + "max": 3.99740168404445, + "avg": 2.72950507057634, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 417.515625, + "max": 472.35546875, + "sum": 1332.7711693548392, + "avg": 444.25705645161344, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 410.34765625, + "max": 461.05078125, + "sum": 1294.0414566532231, + "avg": 431.34715221774195, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T22:14:20.982Z", + "interval_end_time": "2023-04-14T22:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.5538705072991, + "min": 2.32747479522221, + "max": 5.24432858166296, + "avg": 4.18462350243305, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 447.375, + "max": 521.5546875, + "sum": 1467.8884828629016, + "avg": 489.2961609543009, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 438.125, + "max": 510.3046875, + "sum": 1426.0090725806426, + "avg": 475.3363575268822, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 12.5538705072991, + "min": 2.32747479522221, + "max": 5.24432858166296, + "avg": 4.18462350243305, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 447.375, + "max": 521.5546875, + "sum": 1467.8884828629016, + "avg": 489.2961609543009, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 438.125, + "max": 510.3046875, + "sum": 1426.0090725806426, + "avg": 475.3363575268822, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T22:29:20.982Z", + "interval_end_time": "2023-04-14T22:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 13.0997042618841, + "min": 3.50427849813703, + "max": 5.33515178196666, + "avg": 4.36656808729469, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 481.91796875, + "max": 559.76953125, + "sum": 1563.6571320564556, + "avg": 521.2190440188169, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 475.24609375, + "max": 540.44140625, + "sum": 1520.0132308467769, + "avg": 506.671076948925, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 13.0997042618841, + "min": 3.50427849813703, + "max": 5.33515178196666, + "avg": 4.36656808729469, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 481.91796875, + "max": 559.76953125, + "sum": 1563.6571320564556, + "avg": 521.2190440188169, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 475.24609375, + "max": 540.44140625, + "sum": 1520.0132308467769, + "avg": 506.671076948925, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T22:44:20.982Z", + "interval_end_time": "2023-04-14T22:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.0524067195789, + "min": 2.66358841466294, + "max": 4.19660716037036, + "avg": 3.68413557319296, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 483.8046875, + "max": 557.84765625, + "sum": 1591.0030241935444, + "avg": 530.3343413978491, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 478.68359375, + "max": 540.7109375, + "sum": 1553.057207661295, + "avg": 517.6857358870964, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 11.0524067195789, + "min": 2.66358841466294, + "max": 4.19660716037036, + "avg": 3.68413557319296, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 483.8046875, + "max": 557.84765625, + "sum": 1591.0030241935444, + "avg": 530.3343413978491, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 478.68359375, + "max": 540.7109375, + "sum": 1553.057207661295, + "avg": 517.6857358870964, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T22:59:20.982Z", + "interval_end_time": "2023-04-14T23:14:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.11427328335358, + "min": 2.13855924275925, + "max": 2.74692213271852, + "avg": 2.37142442778453, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 483.82421875, + "max": 546.765625, + "sum": 1567.1585181451608, + "avg": 522.3861727150536, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 477.94140625, + "max": 533.4296875, + "sum": 1537.9644657258034, + "avg": 512.6548219086018, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.11427328335358, + "min": 2.13855924275925, + "max": 2.74692213271852, + "avg": 2.37142442778453, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 483.82421875, + "max": 546.765625, + "sum": 1567.1585181451608, + "avg": 522.3861727150536, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 477.94140625, + "max": 533.4296875, + "sum": 1537.9644657258034, + "avg": 512.6548219086018, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T23:14:20.982Z", + "interval_end_time": "2023-04-14T23:29:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.40207558177333, + "min": 2.17771477021481, + "max": 3.22089857927408, + "avg": 2.46735852725778, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 484.3359375, + "max": 630.69140625, + "sum": 1610.2723034274197, + "avg": 536.7574344758062, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 478.125, + "max": 615.4375, + "sum": 1576.3912550403213, + "avg": 525.4637516801071, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 7.40207558177333, + "min": 2.17771477021481, + "max": 3.22089857927408, + "avg": 2.46735852725778, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 484.3359375, + "max": 630.69140625, + "sum": 1610.2723034274197, + "avg": 536.7574344758062, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 478.125, + "max": 615.4375, + "sum": 1576.3912550403213, + "avg": 525.4637516801071, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T23:29:20.982Z", + "interval_end_time": "2023-04-14T23:44:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.8811287533044, + "min": 3.06415491851111, + "max": 3.97339506212593, + "avg": 3.62704291776815, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 501.6328125, + "max": 630.84765625, + "sum": 1724.2982610887145, + "avg": 574.7660870295696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 492.3828125, + "max": 616.39453125, + "sum": 1684.5724546370984, + "avg": 561.5241515456992, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.8811287533044, + "min": 3.06415491851111, + "max": 3.97339506212593, + "avg": 3.62704291776815, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 501.6328125, + "max": 630.84765625, + "sum": 1724.2982610887145, + "avg": 574.7660870295696, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 492.3828125, + "max": 616.39453125, + "sum": 1684.5724546370984, + "avg": 561.5241515456992, + "format": "MiB" + } + } + } + ] + } + ] + } + ] + }, + { + "version": "v2.0", + "experiment_name": "quarkus-resteasy-kruize-min-http-response-time-db", + "interval_start_time": "2023-04-14T23:44:20.982Z", + "interval_end_time": "2023-04-14T23:59:20.982Z", + "kubernetes_objects": [ + { + "type": "job", + "name": "tfb-qrh-job", + "namespace": "default", + "containers": [ + { + "container_image_name": "kruize/tfb-qrh:1.13.2.F_et17", + "container_name": "tfb-server-1", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.4764962408307, + "min": 3.01007331396298, + "max": 3.90357787986297, + "avg": 3.49216541361025, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 486.8984375, + "max": 627.91015625, + "sum": 1686.097152217741, + "avg": 562.0323840725804, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 481.13671875, + "max": 615.5625, + "sum": 1656.9078881048392, + "avg": 552.3026293682794, + "format": "MiB" + } + } + } + ] + }, + { + "container_image_name": "kruize/tfb-db:1.15", + "container_name": "tfb-server-0", + "metrics": [ + { + "name": "cpuRequest", + "results": { + "aggregation_info": { + "sum": 16.11, + "avg": 5.37, + "format": "cores" + } + } + }, + { + "name": "cpuLimit", + "results": { + "aggregation_info": { + "sum": 24.0, + "avg": 8.0, + "format": "cores" + } + } + }, + { + "name": "cpuThrottle", + "results": { + "aggregation_info": { + "sum": 0.0, + "max": 0.0, + "avg": 0.0, + "format": "cores" + } + } + }, + { + "name": "cpuUsage", + "results": { + "aggregation_info": { + "sum": 10.4764962408307, + "min": 3.01007331396298, + "max": 3.90357787986297, + "avg": 3.49216541361025, + "format": "cores" + } + } + }, + { + "name": "memoryRequest", + "results": { + "aggregation_info": { + "sum": 3413.2003784179688, + "avg": 1137.7334594726562, + "format": "MiB" + } + } + }, + { + "name": "memoryLimit", + "results": { + "aggregation_info": { + "sum": 4291.534423828125, + "avg": 1430.511474609375, + "format": "MiB" + } + } + }, + { + "name": "memoryUsage", + "results": { + "aggregation_info": { + "min": 486.8984375, + "max": 627.91015625, + "sum": 1686.097152217741, + "avg": 562.0323840725804, + "format": "MiB" + } + } + }, + { + "name": "memoryRSS", + "results": { + "aggregation_info": { + "min": 481.13671875, + "max": 615.5625, + "sum": 1656.9078881048392, + "avg": 552.3026293682794, + "format": "MiB" + } + } + } + ] + } + ] + } + ] } ] From fd74b6bf270b065156283ed1b8545a55e56c68cd Mon Sep 17 00:00:00 2001 From: msvinaykumar Date: Tue, 3 Sep 2024 15:34:13 +0530 Subject: [PATCH 77/77] crc build fail fix Signed-off-by: msvinaykumar --- .../autotune/metrics/KruizeNotificationCollectionRegistry.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java b/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java index 2b37e6ed3..a75ca6e8b 100644 --- a/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java +++ b/src/main/java/com/autotune/metrics/KruizeNotificationCollectionRegistry.java @@ -5,7 +5,6 @@ import com.autotune.analyzer.recommendations.objects.MappedRecommendationForTimestamp; import com.autotune.analyzer.recommendations.objects.TermRecommendations; import com.autotune.common.data.result.ContainerData; -import com.autotune.operator.InitializeDeployment; import com.autotune.operator.KruizeDeploymentInfo; import com.autotune.utils.KruizeConstants; import com.autotune.utils.MetricsConfig; @@ -82,7 +81,7 @@ public void createCounterTag(String level, String term, String model, Collection for (RecommendationNotification recommendationNotification : recommendationNotificationList) { Tags additionalTags = Tags.empty(); if (("|" + KruizeDeploymentInfo.log_recommendation_metrics_level + "|").contains("|" + recommendationNotification.getType() + "|") == true) { - String notificationLog = String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format_for_KIBANA, this.experiment_name, this.container_name, KruizeConstants.DateFormats.simpleDateFormatForUTC.format(this.interval_end_time), level, term, model, String.valueOf(recommendationNotification.getCode()), recommendationNotification.getType(), recommendationNotification.getMessage()); + String notificationLog = String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format_for_LOG, this.experiment_name, this.container_name, KruizeConstants.DateFormats.simpleDateFormatForUTC.format(this.interval_end_time), level, term, model, String.valueOf(recommendationNotification.getCode()), recommendationNotification.getType(), recommendationNotification.getMessage()); String metricEntry = String.format(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.notification_format_for_METRICS, term, model, recommendationNotification.getType()); LOGGER.info(notificationLog); additionalTags = additionalTags.and(KruizeConstants.KRUIZE_RECOMMENDATION_METRICS.TAG_NAME,metricEntry); // A metric entry with only three tags, which are unlikely to have many unique values, will therefore help reduce cardinality.