diff --git a/src/main/prometheus/lens.ts b/src/main/prometheus/lens.ts index 87e2367636..63341fe30e 100644 --- a/src/main/prometheus/lens.ts +++ b/src/main/prometheus/lens.ts @@ -54,12 +54,16 @@ export class PrometheusLens extends PrometheusProvider { switch (queryName) { case "memoryUsage": return `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}"}`); + case "workloadMemoryUsage": + return `sum(container_memory_working_set_bytes{container!="POD",container!="",instance=~"${opts.nodes}"}) by (component)`; case "memoryRequests": return `sum(kube_pod_container_resource_requests{node=~"${opts.nodes}", resource="memory"}) by (component)`; case "memoryLimits": return `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="memory"}) by (component)`; case "memoryCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="memory"}) by (component)`; + case "memoryAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="memory"}) by (component)`; case "cpuUsage": return `sum(rate(node_cpu_seconds_total{kubernetes_node=~"${opts.nodes}", mode=~"user|system"}[${this.rateAccuracy}]))`; case "cpuRequests": @@ -68,10 +72,14 @@ export class PrometheusLens extends PrometheusProvider { return `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="cpu"}) by (component)`; case "cpuCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="cpu"}) by (component)`; + case "cpuAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="cpu"}) by (component)`; case "podUsage": return `sum({__name__=~"kubelet_running_pod_count|kubelet_running_pods", instance=~"${opts.nodes}"})`; case "podCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="pods"}) by (component)`; + case "podAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="pods"}) by (component)`; case "fsSize": return `sum(node_filesystem_size_bytes{kubernetes_node=~"${opts.nodes}", mountpoint="/"}) by (kubernetes_node)`; case "fsUsage": @@ -82,12 +90,18 @@ export class PrometheusLens extends PrometheusProvider { switch (queryName) { case "memoryUsage": return `sum (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) by (kubernetes_node)`; + case "workloadMemoryUsage": + return `sum(container_memory_working_set_bytes{container!="POD",container!=""}) by (instance)`; case "memoryCapacity": return `sum(kube_node_status_capacity{resource="memory"}) by (node)`; + case "memoryAllocatableCapacity": + return `sum(kube_node_status_allocatable{resource="memory"}) by (node)`; case "cpuUsage": return `sum(rate(node_cpu_seconds_total{mode=~"user|system"}[${this.rateAccuracy}])) by(kubernetes_node)`; case "cpuCapacity": return `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`; + case "cpuAllocatableCapacity": + return `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`; case "fsSize": return `sum(node_filesystem_size_bytes{mountpoint="/"}) by (kubernetes_node)`; case "fsUsage": diff --git a/src/main/prometheus/operator.ts b/src/main/prometheus/operator.ts index 2ee3b50cf9..58d41210b5 100644 --- a/src/main/prometheus/operator.ts +++ b/src/main/prometheus/operator.ts @@ -39,12 +39,16 @@ export class PrometheusOperator extends PrometheusProvider { switch (queryName) { case "memoryUsage": return `sum(node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes))`.replace(/_bytes/g, `_bytes * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"}`); + case "workloadMemoryUsage": + return `sum(container_memory_working_set_bytes{container!="POD",container!="",instance=~"${opts.nodes}"}) by (component)`; case "memoryRequests": return `sum(kube_pod_container_resource_requests{node=~"${opts.nodes}", resource="memory"})`; case "memoryLimits": return `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="memory"})`; case "memoryCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="memory"})`; + case "memoryAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="memory"})`; case "cpuUsage": return `sum(rate(node_cpu_seconds_total{mode=~"user|system"}[${this.rateAccuracy}])* on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"})`; case "cpuRequests": @@ -53,10 +57,14 @@ export class PrometheusOperator extends PrometheusProvider { return `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="cpu"})`; case "cpuCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="cpu"})`; + case "cpuAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="cpu"})`; case "podUsage": return `sum({__name__=~"kubelet_running_pod_count|kubelet_running_pods", node=~"${opts.nodes}"})`; case "podCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="pods"})`; + case "podAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="pods"})`; case "fsSize": return `sum(node_filesystem_size_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info{node=~"${opts.nodes}"})`; case "fsUsage": @@ -67,12 +75,18 @@ export class PrometheusOperator extends PrometheusProvider { switch (queryName) { case "memoryUsage": return `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)`; + case "workloadMemoryUsage": + return `sum(container_memory_working_set_bytes{container!="POD",container!=""}) by (node)`; case "memoryCapacity": return `sum(kube_node_status_capacity{resource="memory"}) by (node)`; + case "memoryAllocatableCapacity": + return `sum(kube_node_status_allocatable{resource="memory"}) by (node)`; case "cpuUsage": return `sum(rate(node_cpu_seconds_total{mode=~"user|system"}[${this.rateAccuracy}]) * on (pod,namespace) group_left(node) kube_pod_info) by (node)`; case "cpuCapacity": return `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`; + case "cpuAllocatableCapacity": + return `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`; case "fsSize": return `sum(node_filesystem_size_bytes{mountpoint="/"} * on (pod,namespace) group_left(node) kube_pod_info) by (node)`; case "fsUsage": diff --git a/src/main/prometheus/stacklight.ts b/src/main/prometheus/stacklight.ts index 2e14508b22..7960e666a8 100644 --- a/src/main/prometheus/stacklight.ts +++ b/src/main/prometheus/stacklight.ts @@ -54,12 +54,16 @@ export class PrometheusStacklight extends PrometheusProvider { switch (queryName) { case "memoryUsage": return `sum(node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) by (kubernetes_name)`.replace(/_bytes/g, `_bytes{node=~"${opts.nodes}"}`); + case "workloadMemoryUsage": + return `sum(container_memory_working_set_bytes{container!="POD",container!="",instance=~"${opts.nodes}"}) by (component)`; case "memoryRequests": return `sum(kube_pod_container_resource_requests{node=~"${opts.nodes}", resource="memory"}) by (component)`; case "memoryLimits": return `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="memory"}) by (component)`; case "memoryCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="memory"}) by (component)`; + case "memoryAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="memory"}) by (component)`; case "cpuUsage": return `sum(rate(node_cpu_seconds_total{node=~"${opts.nodes}", mode=~"user|system"}[${this.rateAccuracy}]))`; case "cpuRequests": @@ -68,10 +72,14 @@ export class PrometheusStacklight extends PrometheusProvider { return `sum(kube_pod_container_resource_limits{node=~"${opts.nodes}", resource="cpu"}) by (component)`; case "cpuCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="cpu"}) by (component)`; + case "cpuAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="cpu"}) by (component)`; case "podUsage": return `sum({__name__=~"kubelet_running_pod_count|kubelet_running_pods", instance=~"${opts.nodes}"})`; case "podCapacity": return `sum(kube_node_status_capacity{node=~"${opts.nodes}", resource="pods"}) by (component)`; + case "podAllocatableCapacity": + return `sum(kube_node_status_allocatable{node=~"${opts.nodes}", resource="pods"}) by (component)`; case "fsSize": return `sum(node_filesystem_size_bytes{node=~"${opts.nodes}", mountpoint="/"}) by (node)`; case "fsUsage": @@ -82,12 +90,18 @@ export class PrometheusStacklight extends PrometheusProvider { switch (queryName) { case "memoryUsage": return `sum (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) by (node)`; + case "workloadMemoryUsage": + return `sum(container_memory_working_set_bytes{container!="POD",container!=""}) by (instance)`; case "memoryCapacity": return `sum(kube_node_status_capacity{resource="memory"}) by (node)`; + case "memoryAllocatableCapacity": + return `sum(kube_node_status_allocatable{resource="memory"}) by (node)`; case "cpuUsage": return `sum(rate(node_cpu_seconds_total{mode=~"user|system"}[${this.rateAccuracy}])) by(node)`; case "cpuCapacity": return `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`; + case "cpuAllocatableCapacity": + return `sum(kube_node_status_allocatable{resource="cpu"}) by (node)`; case "fsSize": return `sum(node_filesystem_size_bytes{mountpoint="/"}) by (node)`; case "fsUsage": diff --git a/src/renderer/api/endpoints/cluster.api.ts b/src/renderer/api/endpoints/cluster.api.ts index 5c3f05ce91..75f15b5a5b 100644 --- a/src/renderer/api/endpoints/cluster.api.ts +++ b/src/renderer/api/endpoints/cluster.api.ts @@ -33,15 +33,19 @@ export class ClusterApi extends KubeApi { return metricsApi.getMetrics({ memoryUsage: opts, + workloadMemoryUsage: opts, memoryRequests: opts, memoryLimits: opts, memoryCapacity: opts, + memoryAllocatableCapacity: opts, cpuUsage: opts, cpuRequests: opts, cpuLimits: opts, cpuCapacity: opts, + cpuAllocatableCapacity: opts, podUsage: opts, podCapacity: opts, + podAllocatableCapacity: opts, fsSize: opts, fsUsage: opts }, params); diff --git a/src/renderer/api/endpoints/nodes.api.ts b/src/renderer/api/endpoints/nodes.api.ts index 40dc2aeadb..17a7571209 100644 --- a/src/renderer/api/endpoints/nodes.api.ts +++ b/src/renderer/api/endpoints/nodes.api.ts @@ -31,7 +31,9 @@ export class NodesApi extends KubeApi { return metricsApi.getMetrics({ memoryUsage: opts, + workloadMemoryUsage: opts, memoryCapacity: opts, + memoryAllocatableCapacity: opts, cpuUsage: opts, cpuCapacity: opts, fsSize: opts, @@ -43,7 +45,9 @@ export class NodesApi extends KubeApi { export interface INodeMetrics { [metric: string]: T; memoryUsage: T; + workloadMemoryUsage: T; memoryCapacity: T; + memoryAllocatableCapacity: T; cpuUsage: T; cpuCapacity: T; fsUsage: T; diff --git a/src/renderer/components/+cluster/cluster-pie-charts.tsx b/src/renderer/components/+cluster/cluster-pie-charts.tsx index 2dc4b25971..609f41d1ad 100644 --- a/src/renderer/components/+cluster/cluster-pie-charts.tsx +++ b/src/renderer/components/+cluster/cluster-pie-charts.tsx @@ -45,20 +45,20 @@ export const ClusterPieCharts = observer(() => { const renderCharts = () => { const data = getMetricLastPoints(clusterOverviewStore.metrics); - const { memoryUsage, memoryRequests, memoryCapacity, memoryLimits } = data; - const { cpuUsage, cpuRequests, cpuCapacity, cpuLimits } = data; - const { podUsage, podCapacity } = data; - const cpuLimitsOverload = cpuLimits > cpuCapacity; - const memoryLimitsOverload = memoryLimits > memoryCapacity; + const { memoryUsage, memoryRequests, memoryAllocatableCapacity, memoryCapacity, memoryLimits } = data; + const { cpuUsage, cpuRequests, cpuAllocatableCapacity, cpuCapacity, cpuLimits } = data; + const { podUsage, podAllocatableCapacity, podCapacity } = data; + const cpuLimitsOverload = cpuLimits > cpuAllocatableCapacity; + const memoryLimitsOverload = memoryLimits > memoryAllocatableCapacity; const defaultColor = ThemeStore.getInstance().activeTheme.colors.pieChartDefaultColor; - - if (!memoryCapacity || !cpuCapacity || !podCapacity) return null; + + if (!memoryCapacity || !cpuCapacity || !podCapacity || !memoryAllocatableCapacity || !cpuAllocatableCapacity || !podAllocatableCapacity) return null; const cpuData: ChartData = { datasets: [ { data: [ cpuUsage, - cpuUsage ? cpuCapacity - cpuUsage : 1, + cpuUsage ? cpuAllocatableCapacity - cpuUsage : 1, ], backgroundColor: [ "#c93dce", @@ -70,7 +70,7 @@ export const ClusterPieCharts = observer(() => { { data: [ cpuRequests, - cpuRequests ? cpuCapacity - cpuRequests : 1, + cpuRequests ? cpuAllocatableCapacity - cpuRequests : 1, ], backgroundColor: [ "#4caf50", @@ -82,7 +82,7 @@ export const ClusterPieCharts = observer(() => { { data: [ cpuLimits, - cpuLimitsOverload ? 0 : cpuCapacity - cpuLimits, + cpuLimitsOverload ? 0 : cpuAllocatableCapacity - cpuLimits, ], backgroundColor: [ "#3d90ce", @@ -96,6 +96,7 @@ export const ClusterPieCharts = observer(() => { `Usage: ${cpuUsage ? cpuUsage.toFixed(2) : "N/A"}`, `Requests: ${cpuRequests ? cpuRequests.toFixed(2) : "N/A"}`, `Limits: ${cpuLimits ? cpuLimits.toFixed(2) : "N/A"}`, + `Allocatable Capacity: ${cpuAllocatableCapacity || "N/A"}`, `Capacity: ${cpuCapacity || "N/A"}` ] }; @@ -104,7 +105,7 @@ export const ClusterPieCharts = observer(() => { { data: [ memoryUsage, - memoryUsage ? memoryCapacity - memoryUsage : 1, + memoryUsage ? memoryAllocatableCapacity - memoryUsage : 1, ], backgroundColor: [ "#c93dce", @@ -116,7 +117,7 @@ export const ClusterPieCharts = observer(() => { { data: [ memoryRequests, - memoryRequests ? memoryCapacity - memoryRequests : 1, + memoryRequests ? memoryAllocatableCapacity - memoryRequests : 1, ], backgroundColor: [ "#4caf50", @@ -128,7 +129,7 @@ export const ClusterPieCharts = observer(() => { { data: [ memoryLimits, - memoryLimitsOverload ? 0 : memoryCapacity - memoryLimits, + memoryLimitsOverload ? 0 : memoryAllocatableCapacity - memoryLimits, ], backgroundColor: [ "#3d90ce", @@ -142,7 +143,8 @@ export const ClusterPieCharts = observer(() => { `Usage: ${bytesToUnits(memoryUsage)}`, `Requests: ${bytesToUnits(memoryRequests)}`, `Limits: ${bytesToUnits(memoryLimits)}`, - `Capacity: ${bytesToUnits(memoryCapacity)}`, + `Allocatable Capacity: ${bytesToUnits(memoryAllocatableCapacity)}`, + `Capacity: ${bytesToUnits(memoryCapacity)}` ] }; const podsData: ChartData = { @@ -150,7 +152,7 @@ export const ClusterPieCharts = observer(() => { { data: [ podUsage, - podUsage ? podCapacity - podUsage : 1, + podUsage ? podAllocatableCapacity - podUsage : 1, ], backgroundColor: [ "#4caf50", @@ -162,7 +164,7 @@ export const ClusterPieCharts = observer(() => { ], labels: [ `Usage: ${podUsage || 0}`, - `Capacity: ${podCapacity}`, + `Capacity: ${podAllocatableCapacity}`, ] }; @@ -172,7 +174,13 @@ export const ClusterPieCharts = observer(() => { {cpuLimitsOverload && renderLimitWarning()} @@ -180,7 +188,13 @@ export const ClusterPieCharts = observer(() => { {memoryLimitsOverload && renderLimitWarning()} diff --git a/src/renderer/components/+nodes/node-charts.tsx b/src/renderer/components/+nodes/node-charts.tsx index 664da5a19b..60d6e08842 100644 --- a/src/renderer/components/+nodes/node-charts.tsx +++ b/src/renderer/components/+nodes/node-charts.tsx @@ -47,11 +47,14 @@ export const NodeCharts = observer(() => { const { memoryUsage, + workloadMemoryUsage, memoryRequests, memoryCapacity, + memoryAllocatableCapacity, cpuUsage, cpuRequests, cpuCapacity, + cpuAllocatableCapacity, podUsage, podCapacity, fsSize, @@ -75,6 +78,13 @@ export const NodeCharts = observer(() => { borderColor: "#30b24d", data: cpuRequests.map(([x, y]) => ({ x, y })) }, + { + id: `${id}-cpuAllocatableCapacity`, + label: `Allocatable Capacity`, + tooltip: `CPU allocatable capacity`, + borderColor: "#032b4d", + data: cpuAllocatableCapacity.map(([x, y]) => ({ x, y })) + }, { id: `${id}-cpuCapacity`, label: `Capacity`, @@ -92,6 +102,13 @@ export const NodeCharts = observer(() => { borderColor: "#c93dce", data: memoryUsage.map(([x, y]) => ({ x, y })) }, + { + id: `${id}-workloadMemoryUsage`, + label: `Workload Memory Usage`, + tooltip: `Workload memory usage`, + borderColor: "#9cd3ce", + data: workloadMemoryUsage.map(([x, y]) => ({ x, y })) + }, { id: "memoryRequests", label: `Requests`, @@ -99,6 +116,13 @@ export const NodeCharts = observer(() => { borderColor: "#30b24d", data: memoryRequests.map(([x, y]) => ({ x, y })) }, + { + id: `${id}-memoryAllocatableCapacity`, + label: `Allocatable Capacity`, + tooltip: `Memory allocatable capacity`, + borderColor: "#032b4d", + data: memoryAllocatableCapacity.map(([x, y]) => ({ x, y })) + }, { id: `${id}-memoryCapacity`, label: `Capacity`, @@ -148,7 +172,7 @@ export const NodeCharts = observer(() => { yAxes: [{ ticks: { callback: value => value - } + } }] }, tooltips: { diff --git a/src/renderer/components/+nodes/nodes.tsx b/src/renderer/components/+nodes/nodes.tsx index 2b774f3618..abd389d6e7 100644 --- a/src/renderer/components/+nodes/nodes.tsx +++ b/src/renderer/components/+nodes/nodes.tsx @@ -97,7 +97,7 @@ export class Nodes extends React.Component { } renderMemoryUsage(node: Node) { - const metrics = nodesStore.getLastMetricValues(node, ["memoryUsage", "memoryCapacity"]); + const metrics = nodesStore.getLastMetricValues(node, ["workloadMemoryUsage", "memoryAllocatableCapacity"]); if (!metrics || !metrics[1]) return ; const usage = metrics[0];