From 7476e169b9a1be8b4163ba015b7285754b9c6b67 Mon Sep 17 00:00:00 2001 From: Lauri Nevala Date: Sat, 25 Apr 2020 23:57:19 +0300 Subject: [PATCH] Allow to select Prometheus query style Signed-off-by: Lauri Nevala --- dashboard/client/api/endpoints/cluster.api.ts | 42 ++++++----------- dashboard/client/api/endpoints/ingress.api.ts | 15 ++---- dashboard/client/api/endpoints/nodes.api.ts | 23 +++------- .../endpoints/persistent-volume-claims.api.ts | 7 +-- dashboard/client/api/endpoints/pods.api.ts | 28 ++++------- dashboard/server/common/metrics.ts | 2 +- src/main/cluster.ts | 1 + src/main/routes/metrics.ts | 13 +++++- .../ClusterSettings/Preferences/index.vue | 46 +++++++++++++++++-- 9 files changed, 92 insertions(+), 85 deletions(-) diff --git a/dashboard/client/api/endpoints/cluster.api.ts b/dashboard/client/api/endpoints/cluster.api.ts index 1f772d57bf..e602340219 100644 --- a/dashboard/client/api/endpoints/cluster.api.ts +++ b/dashboard/client/api/endpoints/cluster.api.ts @@ -5,37 +5,21 @@ import { KubeApi } from "../kube-api"; export class ClusterApi extends KubeApi { async getMetrics(nodeNames: string[], params?: IMetricsReqParams): Promise { const nodes = nodeNames.join("|"); - const memoryUsage = ` - sum( - node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) - ) by (kubernetes_name) - `.replace(/_bytes/g, `_bytes{kubernetes_node=~"${nodes}"}`); - - const memoryRequests = `sum(kube_pod_container_resource_requests{node=~"${nodes}", resource="memory"}) by (component)`; - const memoryLimits = `sum(kube_pod_container_resource_limits{node=~"${nodes}", resource="memory"}) by (component)`; - const memoryCapacity = `sum(kube_node_status_capacity{node=~"${nodes}", resource="memory"}) by (component)`; - const cpuUsage = `sum(rate(node_cpu_seconds_total{kubernetes_node=~"${nodes}", mode=~"user|system"}[1m]))`; - const cpuRequests = `sum(kube_pod_container_resource_requests{node=~"${nodes}", resource="cpu"}) by (component)`; - const cpuLimits = `sum(kube_pod_container_resource_limits{node=~"${nodes}", resource="cpu"}) by (component)`; - const cpuCapacity = `sum(kube_node_status_capacity{node=~"${nodes}", resource="cpu"}) by (component)`; - const podUsage = `sum(kubelet_running_pod_count{instance=~"${nodes}"})`; - const podCapacity = `sum(kube_node_status_capacity{node=~"${nodes}", resource="pods"}) by (component)`; - const fsSize = `sum(node_filesystem_size_bytes{kubernetes_node=~"${nodes}", mountpoint="/"}) by (kubernetes_node)`; - const fsUsage = `sum(node_filesystem_size_bytes{kubernetes_node=~"${nodes}", mountpoint="/"} - node_filesystem_avail_bytes{kubernetes_node=~"${nodes}", mountpoint="/"}) by (kubernetes_node)`; + const opts = { category: "cluster", nodes: nodes } return metricsApi.getMetrics({ - memoryUsage, - memoryRequests, - memoryLimits, - memoryCapacity, - cpuUsage, - cpuRequests, - cpuLimits, - cpuCapacity, - podUsage, - podCapacity, - fsSize, - fsUsage + memoryUsage: opts, + memoryRequests: opts, + memoryLimits: opts, + memoryCapacity: opts, + cpuUsage: opts, + cpuRequests: opts, + cpuLimits: opts, + cpuCapacity: opts, + podUsage: opts, + podCapacity: opts, + fsSize: opts, + fsUsage: opts }, params); } } diff --git a/dashboard/client/api/endpoints/ingress.api.ts b/dashboard/client/api/endpoints/ingress.api.ts index 4105f484a9..dc277af04b 100644 --- a/dashboard/client/api/endpoints/ingress.api.ts +++ b/dashboard/client/api/endpoints/ingress.api.ts @@ -5,17 +5,12 @@ import { KubeApi } from "../kube-api"; export class IngressApi extends KubeApi { getMetrics(ingress: string, namespace: string): Promise { - const bytesSent = (statuses: string) => - `sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[1m])) by (ingress)`; - const bytesSentSuccess = bytesSent("^2\\\\d*"); // Requests with status 2** - const bytesSentFailure = bytesSent("^5\\\\d*"); // Requests with status 5** - const requestDurationSeconds = `sum(rate(nginx_ingress_controller_request_duration_seconds_sum{ingress="${ingress}"}[1m])) by (ingress)`; - const responseDurationSeconds = `sum(rate(nginx_ingress_controller_response_duration_seconds_sum{ingress="${ingress}"}[1m])) by (ingress)`; + const opts = { category: "ingress", ingress } return metricsApi.getMetrics({ - bytesSentSuccess, - bytesSentFailure, - requestDurationSeconds, - responseDurationSeconds + bytesSentSuccess: opts, + bytesSentFailure: opts, + requestDurationSeconds: opts, + responseDurationSeconds: opts }, { namespace, }); diff --git a/dashboard/client/api/endpoints/nodes.api.ts b/dashboard/client/api/endpoints/nodes.api.ts index 862fd831ba..23b42100bb 100644 --- a/dashboard/client/api/endpoints/nodes.api.ts +++ b/dashboard/client/api/endpoints/nodes.api.ts @@ -5,24 +5,15 @@ import { KubeApi } from "../kube-api"; export class NodesApi extends KubeApi { getMetrics(): Promise { - const memoryUsage = ` - sum ( - node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) - ) by (kubernetes_node) - `; - const memoryCapacity = `sum(kube_node_status_capacity{resource="memory"}) by (node)`; - const cpuUsage = `sum(rate(node_cpu_seconds_total{mode=~"user|system"}[1m])) by(kubernetes_node)`; - const cpuCapacity = `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`; - const fsSize = `sum(node_filesystem_size_bytes{mountpoint="/"}) by (kubernetes_node)`; - const fsUsage = `sum(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) by (kubernetes_node)`; + const opts = { category: "nodes"} return metricsApi.getMetrics({ - memoryUsage, - memoryCapacity, - cpuUsage, - cpuCapacity, - fsSize, - fsUsage + memoryUsage: opts, + memoryCapacity: opts, + cpuUsage: opts, + cpuCapacity: opts, + fsSize: opts, + fsUsage: opts }); } } diff --git a/dashboard/client/api/endpoints/persistent-volume-claims.api.ts b/dashboard/client/api/endpoints/persistent-volume-claims.api.ts index 3f6dafd6b8..f6464cdf67 100644 --- a/dashboard/client/api/endpoints/persistent-volume-claims.api.ts +++ b/dashboard/client/api/endpoints/persistent-volume-claims.api.ts @@ -6,12 +6,9 @@ import { KubeApi } from "../kube-api"; export class PersistentVolumeClaimsApi extends KubeApi { getMetrics(pvcName: string, namespace: string): Promise { - const diskUsage = `sum(kubelet_volume_stats_used_bytes{persistentvolumeclaim="${pvcName}"}) by (persistentvolumeclaim, namespace)`; - const diskCapacity = `sum(kubelet_volume_stats_capacity_bytes{persistentvolumeclaim="${pvcName}"}) by (persistentvolumeclaim, namespace)`; - return metricsApi.getMetrics({ - diskUsage, - diskCapacity + diskUsage: { category: 'pvc', pvc: pvcName }, + diskCapacity: { category: 'pvc', pvc: pvcName } }, { namespace }); diff --git a/dashboard/client/api/endpoints/pods.api.ts b/dashboard/client/api/endpoints/pods.api.ts index aaf5a67152..046bb7f1c8 100644 --- a/dashboard/client/api/endpoints/pods.api.ts +++ b/dashboard/client/api/endpoints/pods.api.ts @@ -11,26 +11,18 @@ export class PodsApi extends KubeApi { getMetrics(pods: Pod[], namespace: string, selector = "pod, namespace"): Promise { const podSelector = pods.map(pod => pod.getName()).join("|"); - const cpuUsage = `sum(rate(container_cpu_usage_seconds_total{container_name!="POD",container_name!="",pod_name=~"${podSelector}",namespace="${namespace}"}[1m])) by (${selector})`; - const cpuRequests = `sum(kube_pod_container_resource_requests{pod=~"${podSelector}",resource="cpu",namespace="${namespace}"}) by (${selector})`; - const cpuLimits = `sum(kube_pod_container_resource_limits{pod=~"${podSelector}",resource="cpu",namespace="${namespace}"}) by (${selector})`; - const memoryUsage = `sum(container_memory_working_set_bytes{container_name!="POD",container_name!="",pod_name=~"${podSelector}",namespace="${namespace}"}) by (${selector})`; - const memoryRequests = `sum(kube_pod_container_resource_requests{pod=~"${podSelector}",resource="memory",namespace="${namespace}"}) by (${selector})`; - const memoryLimits = `sum(kube_pod_container_resource_limits{pod=~"${podSelector}",resource="memory",namespace="${namespace}"}) by (${selector})`; - const fsUsage = `sum(container_fs_usage_bytes{container_name!="POD",container_name!="",pod_name=~"${podSelector}",namespace="${namespace}"}) by (${selector})`; - const networkReceive = `sum(rate(container_network_receive_bytes_total{pod_name=~"${podSelector}",namespace="${namespace}"}[1m])) by (${selector})`; - const networkTransit = `sum(rate(container_network_transmit_bytes_total{pod_name=~"${podSelector}",namespace="${namespace}"}[1m])) by (${selector})`; + const opts = { category: "pods", pods: podSelector, namespace, selector } return metricsApi.getMetrics({ - cpuUsage, - cpuRequests, - cpuLimits, - memoryUsage, - memoryRequests, - memoryLimits, - fsUsage, - networkReceive, - networkTransit, + cpuUsage: opts, + cpuRequests: opts, + cpuLimits: opts, + memoryUsage: opts, + memoryRequests: opts, + memoryLimits: opts, + fsUsage: opts, + networkReceive: opts, + networkTransit: opts, }, { namespace, }); diff --git a/dashboard/server/common/metrics.ts b/dashboard/server/common/metrics.ts index 6bfd78d52d..60233e420b 100644 --- a/dashboard/server/common/metrics.ts +++ b/dashboard/server/common/metrics.ts @@ -1,4 +1,4 @@ export type IMetricsQuery = string | string[] | { - [metricName: string]: string; + [metricName: string]: string | object; } diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 5f4372997e..9259240663 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -47,6 +47,7 @@ export type ClusterPreferences = { service: string; port: number; }; + prometheusSource?: string; icon?: string; httpsProxy?: string; } diff --git a/src/main/routes/metrics.ts b/src/main/routes/metrics.ts index 90eecb6685..e5b42ed701 100644 --- a/src/main/routes/metrics.ts +++ b/src/main/routes/metrics.ts @@ -1,6 +1,8 @@ import { LensApiRequest } from "../router" import { LensApi } from "../lens-api" import * as requestPromise from "request-promise-native" +import logger from "../logger" +import { PrometheusProviderFactory} from "../prometheus/provider" type MetricsQuery = string | string[] | { [metricName: string]: string; @@ -22,10 +24,12 @@ class MetricsRoute extends LensApi { queryParams[key] = value }) + const prometheusInstallationSource = cluster.preferences.prometheusSource || "lens" // prometheus metrics loader const attempts: { [query: string]: number } = {}; const maxAttempts = 5; const loadMetrics = (orgQuery: string): Promise => { + logger.info(orgQuery) const query = orgQuery.trim() const attempt = attempts[query] = (attempts[query] || 0) + 1; return requestPromise(metricsUrl, { @@ -61,8 +65,15 @@ class MetricsRoute extends LensApi { else { data = {}; const result = await Promise.all( - Object.values(query).map(loadMetrics) + Object.entries(query).map((objectArr: any) => { + const queryName = objectArr[0] + const queryOpts = objectArr[1] + logger.info(prometheusInstallationSource) + const q = PrometheusProviderFactory.createProvider(prometheusInstallationSource).getQueries(queryOpts)[queryName] + return loadMetrics(q) + }) ); + logger.info(JSON.stringify(result)) Object.keys(query).forEach((metricName, index) => { data[metricName] = result[index]; }); diff --git a/src/renderer/components/ClusterSettings/Preferences/index.vue b/src/renderer/components/ClusterSettings/Preferences/index.vue index 9753fafb6c..76bdfa5f31 100644 --- a/src/renderer/components/ClusterSettings/Preferences/index.vue +++ b/src/renderer/components/ClusterSettings/Preferences/index.vue @@ -31,6 +31,16 @@ @blur="onPrometheusSave" /> + + +
@@ -57,6 +67,7 @@