mirror of
https://github.com/bolucat/Archive.git
synced 2025-10-06 00:27:31 +08:00
166 lines
5.8 KiB
Go
166 lines
5.8 KiB
Go
package metric_reader
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"strings"
|
|
"time"
|
|
|
|
dto "github.com/prometheus/client_model/go"
|
|
)
|
|
|
|
const (
|
|
metricCPUSecondsTotal = "node_cpu_seconds_total"
|
|
metricLoad1 = "node_load1"
|
|
metricLoad5 = "node_load5"
|
|
metricLoad15 = "node_load15"
|
|
metricMemoryTotalBytes = "node_memory_total_bytes"
|
|
metricMemoryActiveBytes = "node_memory_active_bytes"
|
|
metricMemoryWiredBytes = "node_memory_wired_bytes"
|
|
metricMemoryMemTotalBytes = "node_memory_MemTotal_bytes"
|
|
metricMemoryMemAvailableBytes = "node_memory_MemAvailable_bytes"
|
|
metricFilesystemSizeBytes = "node_filesystem_size_bytes"
|
|
metricFilesystemAvailBytes = "node_filesystem_avail_bytes"
|
|
metricNetworkReceiveBytesTotal = "node_network_receive_bytes_total"
|
|
metricNetworkTransmitBytesTotal = "node_network_transmit_bytes_total"
|
|
)
|
|
|
|
type NodeMetrics struct {
|
|
// cpu
|
|
CpuCoreCount int `json:"cpu_core_count"`
|
|
CpuLoadInfo string `json:"cpu_load_info"`
|
|
CpuUsagePercent float64 `json:"cpu_usage_percent"`
|
|
|
|
// memory
|
|
MemoryTotalBytes int64 `json:"memory_total_bytes"`
|
|
MemoryUsageBytes int64 `json:"memory_usage_bytes"`
|
|
MemoryUsagePercent float64 `json:"memory_usage_percent"`
|
|
|
|
// disk
|
|
DiskTotalBytes int64 `json:"disk_total_bytes"`
|
|
DiskUsageBytes int64 `json:"disk_usage_bytes"`
|
|
DiskUsagePercent float64 `json:"disk_usage_percent"`
|
|
|
|
// network
|
|
NetworkReceiveBytesTotal int64 `json:"network_receive_bytes_total"`
|
|
NetworkTransmitBytesTotal int64 `json:"network_transmit_bytes_total"`
|
|
NetworkReceiveBytesRate float64 `json:"network_receive_bytes_rate"`
|
|
NetworkTransmitBytesRate float64 `json:"network_transmit_bytes_rate"`
|
|
|
|
SyncTime time.Time
|
|
}
|
|
type cpuStats struct {
|
|
totalTime float64
|
|
idleTime float64
|
|
cores int
|
|
}
|
|
|
|
func (b *readerImpl) ParseNodeMetrics(metricMap map[string]*dto.MetricFamily, nm *NodeMetrics) error {
|
|
isMac := metricMap[metricMemoryTotalBytes] != nil
|
|
cpu := &cpuStats{}
|
|
|
|
b.processCPUMetrics(metricMap, cpu)
|
|
b.processMemoryMetrics(metricMap, nm, isMac)
|
|
b.processDiskMetrics(metricMap, nm)
|
|
b.processNetworkMetrics(metricMap, nm)
|
|
b.processLoadMetrics(metricMap, nm)
|
|
|
|
b.calculateFinalMetrics(nm, cpu)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (b *readerImpl) processCPUMetrics(metricMap map[string]*dto.MetricFamily, cpu *cpuStats) {
|
|
if cpuMetric, ok := metricMap[metricCPUSecondsTotal]; ok {
|
|
for _, metric := range cpuMetric.Metric {
|
|
value := getMetricValue(metric, cpuMetric.GetType())
|
|
cpu.totalTime += value
|
|
if getLabel(metric, "mode") == "idle" {
|
|
cpu.idleTime += value
|
|
cpu.cores++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (b *readerImpl) processMemoryMetrics(metricMap map[string]*dto.MetricFamily, nm *NodeMetrics, isMac bool) {
|
|
if isMac {
|
|
nm.MemoryTotalBytes = sumInt64Metric(metricMap, metricMemoryTotalBytes)
|
|
nm.MemoryUsageBytes = sumInt64Metric(metricMap, metricMemoryActiveBytes) + sumInt64Metric(metricMap, metricMemoryWiredBytes)
|
|
} else {
|
|
nm.MemoryTotalBytes = sumInt64Metric(metricMap, metricMemoryMemTotalBytes)
|
|
availableMemory := sumInt64Metric(metricMap, metricMemoryMemAvailableBytes)
|
|
nm.MemoryUsageBytes = nm.MemoryTotalBytes - availableMemory
|
|
}
|
|
}
|
|
|
|
func (b *readerImpl) processDiskMetrics(metricMap map[string]*dto.MetricFamily, nm *NodeMetrics) {
|
|
nm.DiskTotalBytes = sumInt64Metric(metricMap, metricFilesystemSizeBytes)
|
|
availableDisk := sumInt64Metric(metricMap, metricFilesystemAvailBytes)
|
|
nm.DiskUsageBytes = nm.DiskTotalBytes - availableDisk
|
|
}
|
|
|
|
func (b *readerImpl) processNetworkMetrics(metricMap map[string]*dto.MetricFamily, nm *NodeMetrics) {
|
|
nm.NetworkReceiveBytesTotal = sumInt64Metric(metricMap, metricNetworkReceiveBytesTotal)
|
|
nm.NetworkTransmitBytesTotal = sumInt64Metric(metricMap, metricNetworkTransmitBytesTotal)
|
|
}
|
|
|
|
func (b *readerImpl) processLoadMetrics(metricMap map[string]*dto.MetricFamily, nm *NodeMetrics) {
|
|
loads := []string{metricLoad1, metricLoad5, metricLoad15}
|
|
for _, load := range loads {
|
|
value := sumFloat64Metric(metricMap, load)
|
|
nm.CpuLoadInfo += fmt.Sprintf("%.2f|", value)
|
|
}
|
|
nm.CpuLoadInfo = strings.TrimRight(nm.CpuLoadInfo, "|")
|
|
}
|
|
|
|
func (b *readerImpl) calculateFinalMetrics(nm *NodeMetrics, cpu *cpuStats) {
|
|
nm.CpuCoreCount = cpu.cores
|
|
nm.CpuUsagePercent = 100 * (cpu.totalTime - cpu.idleTime) / cpu.totalTime
|
|
nm.MemoryUsagePercent = 100 * float64(nm.MemoryUsageBytes) / float64(nm.MemoryTotalBytes)
|
|
nm.DiskUsagePercent = 100 * float64(nm.DiskUsageBytes) / float64(nm.DiskTotalBytes)
|
|
|
|
nm.CpuUsagePercent = math.Round(nm.CpuUsagePercent*100) / 100
|
|
nm.MemoryUsagePercent = math.Round(nm.MemoryUsagePercent*100) / 100
|
|
nm.DiskUsagePercent = math.Round(nm.DiskUsagePercent*100) / 100
|
|
|
|
if b.lastMetrics != nil {
|
|
duration := time.Since(b.lastMetrics.SyncTime).Seconds()
|
|
if duration > 0.1 {
|
|
nm.NetworkReceiveBytesRate = math.Max(0, float64(nm.NetworkReceiveBytesTotal-b.lastMetrics.NetworkReceiveBytesTotal)/duration)
|
|
nm.NetworkTransmitBytesRate = math.Max(0, float64(nm.NetworkTransmitBytesTotal-b.lastMetrics.NetworkTransmitBytesTotal)/duration)
|
|
nm.NetworkReceiveBytesRate = math.Round(nm.NetworkReceiveBytesRate)
|
|
nm.NetworkTransmitBytesRate = math.Round(nm.NetworkTransmitBytesRate)
|
|
}
|
|
}
|
|
}
|
|
|
|
func sumInt64Metric(metricMap map[string]*dto.MetricFamily, metricName string) int64 {
|
|
ret := int64(0)
|
|
if metric, ok := metricMap[metricName]; ok && len(metric.Metric) > 0 {
|
|
for _, m := range metric.Metric {
|
|
ret += int64(getMetricValue(m, metric.GetType()))
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func sumFloat64Metric(metricMap map[string]*dto.MetricFamily, metricName string) float64 {
|
|
ret := float64(0)
|
|
if metric, ok := metricMap[metricName]; ok && len(metric.Metric) > 0 {
|
|
for _, m := range metric.Metric {
|
|
ret += getMetricValue(m, metric.GetType())
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func getLabel(metric *dto.Metric, name string) string {
|
|
for _, label := range metric.Label {
|
|
if label.GetName() == name {
|
|
return label.GetValue()
|
|
}
|
|
}
|
|
return ""
|
|
}
|