From 2fc8daaff6b59641477da6644c1ebd7d4019ce30 Mon Sep 17 00:00:00 2001 From: Lauri Nevala Date: Sun, 26 Apr 2020 00:29:58 +0300 Subject: [PATCH] Add missing prometheus queries Signed-off-by: Lauri Nevala --- src/main/prometheus/helm.ts | 8 +++++ src/main/prometheus/lens.ts | 63 +++++++++++++++++++++++++++++++++ src/main/prometheus/operator.ts | 63 +++++++++++++++++++++++++++++++++ src/main/prometheus/provider.ts | 27 ++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 src/main/prometheus/helm.ts create mode 100644 src/main/prometheus/lens.ts create mode 100644 src/main/prometheus/operator.ts create mode 100644 src/main/prometheus/provider.ts diff --git a/src/main/prometheus/helm.ts b/src/main/prometheus/helm.ts new file mode 100644 index 0000000000..4d6a63b3e6 --- /dev/null +++ b/src/main/prometheus/helm.ts @@ -0,0 +1,8 @@ +import { PrometheusLens } from "./lens" + +export class PrometheusHelm extends PrometheusLens { + constructor() { + super() + this.rateAccuracy = "5m" + } +} \ No newline at end of file diff --git a/src/main/prometheus/lens.ts b/src/main/prometheus/lens.ts new file mode 100644 index 0000000000..2603e860be --- /dev/null +++ b/src/main/prometheus/lens.ts @@ -0,0 +1,63 @@ +import { PrometheusProvider, PrometheusQuery, PrometheusQueryOpts } from "./provider"; +export class PrometheusLens implements PrometheusProvider { + rateAccuracy = "1m" + + public getQueries(opts: PrometheusQueryOpts): PrometheusQuery { + switch(opts.category) { + case 'cluster': + return { + 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=~"${opts.nodes}"}`), + memoryRequests: `sum(kube_pod_container_resource_requests{node=~"${opts.nodes}", resource="memory"}) by (component)`, + memoryLimits: `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="memory"}) by (component)`, + memoryCapacity: `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="memory"}) by (component)`, + cpuUsage: `sum(rate(node_cpu_seconds_total{kubernetes_node=~"${opts.nodes}", mode=~"user|system"}[${this.rateAccuracy}]))`, + cpuRequests:`sum(kube_pod_container_resource_requests{node=~"${opts.nodes}", resource="cpu"}) by (component)`, + cpuLimits: `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="cpu"}) by (component)`, + cpuCapacity: `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="cpu"}) by (component)`, + podUsage: `sum(kubelet_running_pod_count{instance=~"${opts.nodes}"})`, + podCapacity: `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="pods"}) by (component)`, + fsSize: `sum(node_filesystem_size_bytes{kubernetes_node=~"${opts.nodes}", mountpoint="/"}) by (kubernetes_node)`, + fsUsage: `sum(node_filesystem_size_bytes{kubernetes_node=~"${opts.nodes}", mountpoint="/"} - node_filesystem_avail_bytes{kubernetes_node=~"${opts.nodes}", mountpoint="/"}) by (kubernetes_node)` + } + case 'nodes': + return { + memoryUsage: `sum (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) by (kubernetes_node)`, + memoryCapacity: `sum(kube_node_status_capacity{resource="memory"}) by (node)`, + cpuUsage: `sum(rate(node_cpu_seconds_total{mode=~"user|system"}[${this.rateAccuracy}])) by(kubernetes_node)`, + cpuCapacity: `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`, + fsSize: `sum(node_filesystem_size_bytes{mountpoint="/"}) by (kubernetes_node)`, + fsUsage: `sum(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) by (kubernetes_node)` + } + case 'pods': + return { + cpuUsage: `sum(rate(container_cpu_usage_seconds_total{container!="POD",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`, + cpuRequests: `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}",resource="cpu",namespace="${opts.namespace}"}) by (${opts.selector})`, + cpuLimits: `sum(kube_pod_container_resource_limits{pod=~"${opts.pods}",resource="cpu",namespace="${opts.namespace}"}) by (${opts.selector})`, + memoryUsage: `sum(container_memory_working_set_bytes{container!="POD",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}) by (${opts.selector})`, + memoryRequests: `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}",resource="memory",namespace="${opts.namespace}"}) by (${opts.selector})`, + memoryLimits: `sum(kube_pod_container_resource_limits{pod=~"${opts.pods}",resource="memory",namespace="${opts.namespace}"}) by (${opts.selector})`, + fsUsage: `sum(container_fs_usage_bytes{container!="POD",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}) by (${opts.selector})`, + networkReceive: `sum(rate(container_network_receive_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`, + networkTransit: `sum(rate(container_network_transmit_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})` + } + case 'pvc': + return { + diskUsage: `sum(kubelet_volume_stats_used_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)`, + diskCapacity: `sum(kubelet_volume_stats_capacity_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)` + } + case 'ingress': + const bytesSent = (ingress: string, statuses: string) => + `sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress)` + return { + bytesSentSuccess: bytesSent(opts.igress, "^2\\\\d*"), + bytesSentFailure: bytesSent(opts.ingres, "^5\\\\d*"), + requestDurationSeconds: `sum(rate(nginx_ingress_controller_request_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)`, + responseDurationSeconds: `sum(rate(nginx_ingress_controller_response_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)` + } + } + } +} \ No newline at end of file diff --git a/src/main/prometheus/operator.ts b/src/main/prometheus/operator.ts new file mode 100644 index 0000000000..87f8d51fec --- /dev/null +++ b/src/main/prometheus/operator.ts @@ -0,0 +1,63 @@ +import { PrometheusProvider, PrometheusQuery, PrometheusQueryOpts } from "./provider"; +export class PrometheusOperator implements PrometheusProvider { + rateAccuracy = "1m" + + public getQueries(opts: PrometheusQueryOpts): PrometheusQuery { + switch(opts.category) { + case 'cluster': + return { + memoryUsage: ` + sum( + node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes) + ) by (node) + `.replace(/_bytes/g, `_bytes * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"}`), + memoryRequests: `sum(kube_pod_container_resource_requests{node=~"${opts.nodes}", resource="memory"}) by (component)`, + memoryLimits: `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="memory"}) by (component)`, + memoryCapacity: `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="memory"}) by (component)`, + cpuUsage: `sum(rate(node_cpu_seconds_total{mode=~"user|system"}[${this.rateAccuracy}])* on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"}) by (node)`, + cpuRequests:`sum(kube_pod_container_resource_requests{node=~"${opts.nodes}", resource="cpu"}) by (component)`, + cpuLimits: `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="cpu"}) by (component)`, + cpuCapacity: `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="cpu"}) by (component)`, + podUsage: `sum(kubelet_running_pod_count{node=~"${opts.nodes}"})`, + podCapacity: `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="pods"}) by (component)`, + fsSize: `sum(node_filesystem_size_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"}) by (node)`, + fsUsage: `sum(node_filesystem_size_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"} - node_filesystem_avail_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"}) by (node)` + } + case 'nodes': + return { + memoryUsage: `sum((node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) * on (pod,namespace) group_left(node) kube_pod_info) by (node)`, + memoryCapacity: `sum(kube_node_status_capacity{resource="memory"}) by (node)`, + cpuUsage: `sum(rate(node_cpu_seconds_total{mode=~"user|system"}[${this.rateAccuracy}]) * on (pod,namespace) group_left(node) kube_pod_info) by (node)`, + cpuCapacity: `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`, + fsSize: `sum(node_filesystem_size_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info) by (node)`, + fsUsage: `sum((node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) * on (pod,namespace) group_left(node) kube_pod_info) by (node)` + } + case 'pods': + return { + cpuUsage: `sum(rate(container_cpu_usage_seconds_total{container!="POD",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`, + cpuRequests: `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}",resource="cpu",namespace="${opts.namespace}"}) by (${opts.selector})`, + cpuLimits: `sum(kube_pod_container_resource_limits{pod=~"${opts.pods}",resource="cpu",namespace="${opts.namespace}"}) by (${opts.selector})`, + memoryUsage: `sum(container_memory_working_set_bytes{container!="POD",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}) by (${opts.selector})`, + memoryRequests: `sum(kube_pod_container_resource_requests{pod=~"${opts.pods}",resource="memory",namespace="${opts.namespace}"}) by (${opts.selector})`, + memoryLimits: `sum(kube_pod_container_resource_limits{pod=~"${opts.pods}",resource="memory",namespace="${opts.namespace}"}) by (${opts.selector})`, + fsUsage: `sum(container_fs_usage_bytes{container!="POD",container!="",pod=~"${opts.pods}",namespace="${opts.namespace}"}) by (${opts.selector})`, + networkReceive: `sum(rate(container_network_receive_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})`, + networkTransit: `sum(rate(container_network_transmit_bytes_total{pod=~"${opts.pods}",namespace="${opts.namespace}"}[${this.rateAccuracy}])) by (${opts.selector})` + } + case 'pvc': + return { + diskUsage: `sum(kubelet_volume_stats_used_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)`, + diskCapacity: `sum(kubelet_volume_stats_capacity_bytes{persistentvolumeclaim="${opts.pvc}"}) by (persistentvolumeclaim, namespace)` + } + case 'ingress': + const bytesSent = (ingress: string, statuses: string) => + `sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}", status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress)`; + return { + bytesSentSuccess: bytesSent(opts.igress, "^2\\\\d*"), + bytesSentFailure: bytesSent(opts.ingres, "^5\\\\d*"), + requestDurationSeconds: `sum(rate(nginx_ingress_controller_request_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)`, + responseDurationSeconds: `sum(rate(nginx_ingress_controller_response_duration_seconds_sum{ingress="${opts.ingress}"}[${this.rateAccuracy}])) by (ingress)` + } + } + } +} \ No newline at end of file diff --git a/src/main/prometheus/provider.ts b/src/main/prometheus/provider.ts new file mode 100644 index 0000000000..5086874742 --- /dev/null +++ b/src/main/prometheus/provider.ts @@ -0,0 +1,27 @@ +import { PrometheusHelm } from "./helm" +import { PrometheusLens } from "./lens" +import { PrometheusOperator } from "./operator"; + +export type PrometheusQuery = { + [key: string]: string; +} + +export type PrometheusQueryOpts = { + [key: string]: string | any; +}; + +export interface PrometheusProvider { + getQueries(opts: PrometheusQueryOpts): PrometheusQuery; +} + +export class PrometheusProviderFactory { + static createProvider(type: string): PrometheusProvider { + if (type == "helm") { + return new PrometheusHelm() + } else if (type == "operator") { + return new PrometheusOperator() + } else { + return new PrometheusLens() + } + } +} \ No newline at end of file