189 lines
6.8 KiB
Go
189 lines
6.8 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"strings"
|
|
|
|
"github.com/golang/glog"
|
|
|
|
"kubesphere.io/kubesphere/pkg/client"
|
|
|
|
ksutil "kubesphere.io/kubesphere/pkg/util"
|
|
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
type ResultNameSpaceForContainer struct {
|
|
NameSpace string `json:"namespace"`
|
|
PodsCount string `json:"pods_count"`
|
|
Pods []ResultPodForContainer `json:"pods"`
|
|
}
|
|
|
|
type ResultPodForContainer struct {
|
|
PodName string `json:"pod_name"`
|
|
ContainersCount string `json:"containers_count"`
|
|
Containers []ResultContainer `json:"containers"`
|
|
}
|
|
type ResultContainer struct {
|
|
ContainerName string `json:"container_name"`
|
|
CPURequest string `json:"cpu_request"`
|
|
CPULimit string `json:"cpu_limit"`
|
|
MemoryRequest string `json:"mem_request"`
|
|
MemoryLimit string `json:"mem_limit"`
|
|
CPU []CPUContainer `json:"cpu"`
|
|
Memory []MemoryContainer `json:"memory"`
|
|
}
|
|
type CPUContainer struct {
|
|
TimeStamp string `json:"timestamp"`
|
|
UsedCPU string `json:"used_cpu"`
|
|
CPUUtilization string `json:"cpu_utilization"`
|
|
}
|
|
|
|
type MemoryContainer struct {
|
|
TimeStamp string `json:"timestamp"`
|
|
UsedMemory string `json:"used_mem"`
|
|
MemoryUtilization string `json:"mem_utilization"`
|
|
}
|
|
|
|
/*
|
|
Get all containers under specified namespace in default cluster
|
|
*/
|
|
func GetContainers(namespace, podName string) []string {
|
|
containersList := client.GetHeapsterMetrics("/namespaces/" + namespace + "/pods/" + podName + "/containers")
|
|
var containers []string
|
|
dec := json.NewDecoder(strings.NewReader(containersList))
|
|
err := dec.Decode(&containers)
|
|
if err != nil {
|
|
glog.Error(err)
|
|
}
|
|
return containers
|
|
}
|
|
|
|
func FormatContainersMetrics(nodeName, namespace, podName string) ResultNameSpaceForContainer {
|
|
var resultNameSpaceForContainer ResultNameSpaceForContainer
|
|
var resultPodsForContainer []ResultPodForContainer
|
|
|
|
var pods []string
|
|
if nodeName == "" {
|
|
pods = GetPods(namespace)
|
|
} else {
|
|
pods = GetPodsForNode(nodeName, namespace)
|
|
}
|
|
|
|
resultNameSpaceForContainer.NameSpace = namespace
|
|
resultNameSpaceForContainer.PodsCount = strconv.Itoa(len(pods))
|
|
|
|
if podName != "" {
|
|
var resultPodForContainer ResultPodForContainer
|
|
resultPodForContainer.PodName = podName
|
|
resultPodForContainer = FormatPodMetricsWithContainers(namespace, podName)
|
|
resultPodsForContainer = append(resultPodsForContainer, resultPodForContainer)
|
|
resultNameSpaceForContainer.Pods = resultPodsForContainer
|
|
return resultNameSpaceForContainer
|
|
}
|
|
for _, pod := range pods {
|
|
var resultPodForContainer ResultPodForContainer
|
|
resultPodForContainer.PodName = pod
|
|
resultPodForContainer = FormatPodMetricsWithContainers(namespace, pod)
|
|
resultPodsForContainer = append(resultPodsForContainer, resultPodForContainer)
|
|
}
|
|
resultNameSpaceForContainer.Pods = resultPodsForContainer
|
|
return resultNameSpaceForContainer
|
|
}
|
|
|
|
func FormatPodMetricsWithContainers(namespace, pod string) ResultPodForContainer {
|
|
|
|
var resultPod ResultPodForContainer
|
|
var containers []string
|
|
var resultContainers []ResultContainer
|
|
|
|
resultPod.PodName = pod
|
|
containers = GetContainers(namespace, pod)
|
|
resultPod.ContainersCount = strconv.Itoa(len(containers))
|
|
|
|
for _, container := range containers {
|
|
var resultContainer ResultContainer
|
|
var containerCPUMetrics []CPUContainer
|
|
var containerMemMetrics []MemoryContainer
|
|
var cpuMetrics CPUContainer
|
|
var memMetrics MemoryContainer
|
|
|
|
resultContainer.ContainerName = container
|
|
cpuRequest := client.GetHeapsterMetrics("/namespaces/" + namespace + "/pods/" + pod + "/containers/" + container + "/metrics/cpu/request")
|
|
cpuRequest = ksutil.JsonRawMessage(cpuRequest).Find("metrics").ToList()[0].Find("value").ToString()
|
|
if cpuRequest != "" && cpuRequest != "0" {
|
|
resultContainer.CPURequest = cpuRequest
|
|
} else {
|
|
resultContainer.CPURequest = "inf"
|
|
}
|
|
|
|
cpuLimit := client.GetHeapsterMetrics("/namespaces/" + namespace + "/pods/" + pod + "/containers/" + container + "/metrics/cpu/limit")
|
|
cpuLimit = ksutil.JsonRawMessage(cpuLimit).Find("metrics").ToList()[0].Find("value").ToString()
|
|
if cpuLimit != "" && cpuLimit != "0" {
|
|
resultContainer.CPULimit = cpuLimit
|
|
} else {
|
|
resultContainer.CPULimit = "inf"
|
|
}
|
|
memoryRequest := client.GetHeapsterMetrics("/namespaces/" + namespace + "/pods/" + pod + "/containers/" + container + "/metrics/memory/request")
|
|
resultContainer.MemoryRequest = ConvertMemory(memoryRequest)
|
|
|
|
memoryLimit := client.GetHeapsterMetrics("/namespaces/" + namespace + "/pods/" + pod + "/containers/" + container + "/metrics/memory/limit")
|
|
resultContainer.MemoryLimit = ConvertMemory(memoryLimit)
|
|
|
|
cpuUsageRate := client.GetHeapsterMetrics("/namespaces/" + namespace + "/pods/" + pod + "/containers/" + container + "/metrics/cpu/usage_rate")
|
|
if cpuUsageRate != "" {
|
|
metrics := ksutil.JsonRawMessage(cpuUsageRate).Find("metrics").ToList()
|
|
|
|
for _, metric := range metrics {
|
|
timestamp := metric.Find("timestamp")
|
|
cpu_utilization, _ := strconv.ParseFloat(metric.Find("value").ToString(), 64)
|
|
cpuMetrics.TimeStamp = timestamp.ToString()
|
|
cpuMetrics.CPUUtilization = fmt.Sprintf("%.3f", cpu_utilization/1000)
|
|
if resultContainer.CPULimit != "inf" {
|
|
cpu_limit, _ := strconv.ParseFloat(resultContainer.CPULimit, 64)
|
|
cpuMetrics.UsedCPU = fmt.Sprintf("%.1f", cpu_limit*cpu_utilization/1000)
|
|
} else {
|
|
cpuMetrics.UsedCPU = "inf"
|
|
}
|
|
glog.Info("pod " + pod + " has limit cpu " + resultContainer.CPULimit + " CPU utilization " + fmt.Sprintf("%.3f", cpu_utilization/1000) + " at time" + timestamp.ToString())
|
|
containerCPUMetrics = append(containerCPUMetrics, cpuMetrics)
|
|
}
|
|
|
|
}
|
|
|
|
resultContainer.CPU = containerCPUMetrics
|
|
|
|
var used_mem_bytes float64
|
|
|
|
memUsage := client.GetHeapsterMetrics("/namespaces/" + namespace + "/pods/" + pod + "/containers/" + container + "/metrics/memory/usage")
|
|
if memUsage != "" {
|
|
metrics := ksutil.JsonRawMessage(memUsage).Find("metrics").ToList()
|
|
|
|
for _, metric := range metrics {
|
|
timestamp := metric.Find("timestamp")
|
|
used_mem_bytes, _ = strconv.ParseFloat(metric.Find("value").ToString(), 64)
|
|
used_mem := used_mem_bytes / 1024 / 1024
|
|
memMetrics.TimeStamp = timestamp.ToString()
|
|
memMetrics.UsedMemory = fmt.Sprintf("%.1f", used_mem)
|
|
if resultContainer.MemoryLimit != "inf" {
|
|
mem_limit, _ := strconv.ParseFloat(resultContainer.MemoryLimit, 64)
|
|
memMetrics.MemoryUtilization = fmt.Sprintf("%.3f", used_mem/mem_limit)
|
|
} else {
|
|
memMetrics.MemoryUtilization = "inf"
|
|
}
|
|
|
|
glog.Info("pod " + pod + " has limit mem " + resultContainer.MemoryLimit + " mem utilization " + memMetrics.MemoryUtilization + " at time" + timestamp.ToString())
|
|
containerMemMetrics = append(containerMemMetrics, memMetrics)
|
|
}
|
|
}
|
|
|
|
resultContainer.Memory = containerMemMetrics
|
|
resultContainers = append(resultContainers, resultContainer)
|
|
}
|
|
resultPod.Containers = resultContainers
|
|
|
|
return resultPod
|
|
}
|