[ Cmii ] [ Octopus ] - reformat agent-go - 1

This commit is contained in:
zeaslity
2024-03-29 11:39:14 +08:00
parent aa4412f042
commit 1be48aaac2
52 changed files with 683 additions and 557 deletions

77
agent-go/a_status/CPU.go Normal file
View File

@@ -0,0 +1,77 @@
package a_status
import (
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/load"
"time"
)
type CPUMetric struct {
NumCores int
CPUPercent float64
CPULoads *load.AvgStat
}
type CPUInfo struct {
CPUMetric
CPUInfo []cpu.InfoStat
}
func GetCPUMetric() (*CPUMetric, error) {
numCores, err := cpu.Counts(true)
if err != nil {
return nil, err
}
cpuPercent, err := cpu.Percent(time.Second, false)
if err != nil {
return nil, err
}
cpuLoads, err := load.Avg()
if err != nil {
return nil, err
}
return &CPUMetric{
NumCores: numCores,
CPUPercent: cpuPercent[0],
CPULoads: cpuLoads,
}, nil
}
func GetCPUInfo() (*CPUInfo, error) {
numCores, err := cpu.Counts(true)
if err != nil {
return nil, err
}
cpuPercent, err := cpu.Percent(time.Second, false)
if err != nil {
return nil, err
}
cpuLoads, err := load.Avg()
if err != nil {
return nil, err
}
infoStats, err := cpu.Info()
if err != nil {
return nil, err
}
return &CPUInfo{
CPUMetric: CPUMetric{
NumCores: numCores,
CPUPercent: cpuPercent[0],
CPULoads: cpuLoads,
},
CPUInfo: infoStats,
}, nil
}

View File

@@ -0,0 +1,36 @@
package a_status
import (
"encoding/json"
"fmt"
"testing"
)
func TestGetCPUStatus(t *testing.T) {
cpuStatus, err := GetCPUMetric()
if err != nil {
return
}
marshalIndent, err := json.MarshalIndent(cpuStatus, "", " ")
if err != nil {
fmt.Printf("error")
}
fmt.Println(string(marshalIndent))
}
func TestGetCPUInfo(t *testing.T) {
cpuInfo, err := GetCPUInfo()
if err != nil {
return
}
marshalIndent, err := json.MarshalIndent(cpuInfo, "", " ")
if err != nil {
fmt.Printf("error")
}
fmt.Println(string(marshalIndent))
}

117
agent-go/a_status/Disk.go Normal file
View File

@@ -0,0 +1,117 @@
package a_status
import (
"fmt"
"github.com/shirou/gopsutil/v3/disk"
"regexp"
"time"
)
type DiskStatus struct {
DiskInfo
}
type DiskInfo struct {
Device string `json:"device"`
Mountpoint string `json:"mountpoint"`
Fstype string `json:"fstype"`
Total uint64 `json:"total"`
Free uint64 `json:"free"`
Used uint64 `json:"used"`
UsedPercent float64 `json:"usedPercent"`
}
func GetDiskStatus() *DiskStatus {
ds := &DiskStatus{}
// Get disk usage
du, _ := disk.Usage("/")
ds.Total = du.Total
ds.Used = du.Used
// 2023年7月14日 去除此部分 没什么用
// Get logical disk info for Linux systems
//if runtime.GOOS == "linux" {
// ld, _ := disk.Partitions(true)
// ds.LogicalDisk = ld
//}
return ds
}
func GetDiskInfo() ([]DiskInfo, error) {
partitionStats, err := disk.Partitions(false)
if err != nil {
log.ErrorF("[GetDiskInfo] - get disk partition info error ! => %v", err)
return nil, err
}
var result []DiskInfo
for _, partitionStat := range partitionStats {
if !MatchNeededDisk(partitionStat.Device) {
continue
}
usageStat, err := disk.Usage(partitionStat.Mountpoint)
if err != nil {
log.ErrorF("[GetDiskInfo] - device [%s] get mount point [%s] usage error => %v", partitionStat.Device, partitionStat.Mountpoint, err)
return nil, err
}
// new disk info
diskInfo := DiskInfo{
Device: partitionStat.Device,
Mountpoint: partitionStat.Mountpoint,
Fstype: partitionStat.Fstype,
Total: usageStat.Total,
Free: usageStat.Free,
Used: usageStat.Used,
UsedPercent: usageStat.UsedPercent,
}
// assign
result = append(result, diskInfo)
}
return result, nil
}
func CalculateDiskIO() {
// Get initial disk IO counters
counters1, _ := disk.IOCounters()
time.Sleep(time.Second)
// Get disk IO counters after 1 second
counters2, _ := disk.IOCounters()
for device, counter1 := range counters1 {
counter2 := counters2[device]
readSpeed := float64(counter2.ReadBytes-counter1.ReadBytes) / 1024
writeSpeed := float64(counter2.WriteBytes-counter1.WriteBytes) / 1024
fmt.Printf("%v: read %vKB/s, write %vKB/s\n", device, readSpeed, writeSpeed)
}
}
func MatchNeededDisk(deviceName string) bool {
match, _ := regexp.MatchString(`^(/dev/loop)\d+`, deviceName)
if match {
return false
}
//if strings.HasPrefix(deviceName, "/sys") {
// return false
//}
//if strings.HasPrefix(deviceName, "/run") {
// return false
//}
//if strings.HasPrefix(deviceName, "/snap") {
// return false
//}
//if strings.HasPrefix(deviceName, "tracefs") {
// return false
//}
return true
}

View File

@@ -0,0 +1,33 @@
package a_status
import (
"encoding/json"
"fmt"
"testing"
"wdd.io/agent-common/utils"
)
func TestGetDiskStatus(t *testing.T) {
ds := GetDiskStatus()
fmt.Printf("Total: %v, Used: %v\n", ds.Total, ds.Used)
marshalIndent, err := json.MarshalIndent(ds, "", " ")
if err != nil {
fmt.Printf("error")
}
fmt.Println(string(marshalIndent))
}
func TestGetDiskInfo(t *testing.T) {
diskInfo, err := GetDiskInfo()
if err != nil {
t.Errorf("get disk info error ! => %v", err)
}
utils.BeautifulPrint(diskInfo)
}

View File

@@ -0,0 +1,17 @@
package a_status
import (
"testing"
)
func TestGetDockerInfo(t *testing.T) {
GetDockerInfo()
//diskInfo, err :=
//if err != nil {
// t.Errorf("get docker info error %v", err)
//}
//
//utils.BeautifulPrint(diskInfo)
}

View File

@@ -0,0 +1,56 @@
package a_status
import (
"github.com/shirou/gopsutil/v3/docker"
"strings"
"wdd.io/agent-common/utils"
)
type DockerMetric struct {
DockerStats []docker.CgroupDockerStat
}
func GetDockerMetric() (*DockerMetric, error) {
dockerStats, err := docker.GetDockerStat()
if err != nil {
log.ErrorF("[GetDockerMetric] - get docker stats list error %v", err)
return nil, err
}
return &DockerMetric{
DockerStats: dockerStats,
}, nil
}
func GetDockerInfo() {
//dockerIDList, err := docker.GetDockerIDList()
//if err != nil {
// log.ErrorF("[GetDockerInfo] - get docker id list error %v", err)
//}
//utils.BeautifulPrint(dockerIDList)
dockerStats, err := docker.GetDockerStat()
if err != nil {
log.ErrorF("[GetDockerInfo] - get docker stats list error %v", err)
}
utils.BeautifulPrint(dockerStats)
for _, dockerStat := range dockerStats {
if strings.Contains(dockerStat.Name, "mysql") {
cpuDocker, _ := docker.CgroupCPUDocker(dockerStat.ContainerID)
utils.BeautifulPrint(cpuDocker)
//usageDocker, _ := docker.CgroupCPUUsageDocker(dockerStat.ContainerID)
//utils.BeautifulPrint(usageDocker)
mem, _ := docker.CgroupMemDocker(dockerStat.ContainerID)
utils.BeautifulPrint(mem)
}
}
}

22
agent-go/a_status/Host.go Normal file
View File

@@ -0,0 +1,22 @@
package a_status
import (
"github.com/shirou/gopsutil/v3/host"
)
type HostInfo struct {
host.InfoStat
}
func GetHostInfo() (*HostInfo, error) {
info, err := host.Info()
if err != nil {
log.ErrorF("get host info error => %v", err)
return nil, err
}
return &HostInfo{
InfoStat: *info,
}, nil
}

View File

@@ -0,0 +1,16 @@
package a_status
import (
"testing"
"wdd.io/agent-common/utils"
)
func TestGetHostInfo(t *testing.T) {
info, err := GetHostInfo()
if err != nil {
t.Errorf("get host info error is %v", err)
}
utils.BeautifulPrint(info)
}

121
agent-go/a_status/Memory.go Normal file
View File

@@ -0,0 +1,121 @@
package a_status
import (
"fmt"
"github.com/shirou/gopsutil/v3/mem"
)
type MemoryMetric struct {
TotalMemory uint64
AvailableMemory uint64
UsedMemory uint64
UsedPercent float64 `json:"usedPercent"`
FreeMemory uint64 `json:"free"`
}
type MemoryInfo struct {
MemoryMetric
Buffers uint64 `json:"buffers"`
Cached uint64 `json:"cached"`
WriteBack uint64 `json:"writeBack"`
Dirty uint64 `json:"dirty"`
WriteBackTmp uint64 `json:"writeBackTmp"`
Shared uint64 `json:"shared"`
Slab uint64 `json:"slab"`
Sreclaimable uint64 `json:"sreclaimable"`
Sunreclaim uint64 `json:"sunreclaim"`
PageTables uint64 `json:"pageTables"`
SwapCached uint64 `json:"swapCached"`
CommitLimit uint64 `json:"commitLimit"`
CommittedAS uint64 `json:"committedAS"`
HighTotal uint64 `json:"highTotal"`
HighFree uint64 `json:"highFree"`
LowTotal uint64 `json:"lowTotal"`
LowFree uint64 `json:"lowFree"`
SwapTotal uint64 `json:"swapTotal"`
SwapFree uint64 `json:"swapFree"`
Mapped uint64 `json:"mapped"`
VmallocTotal uint64 `json:"vmallocTotal"`
VmallocUsed uint64 `json:"vmallocUsed"`
VmallocChunk uint64 `json:"vmallocChunk"`
HugePagesTotal uint64 `json:"hugePagesTotal"`
HugePagesFree uint64 `json:"hugePagesFree"`
HugePagesRsvd uint64 `json:"hugePagesRsvd"`
HugePagesSurp uint64 `json:"hugePagesSurp"`
HugePageSize uint64 `json:"hugePageSize"`
}
func GetMemoryMetric() (*MemoryMetric, error) {
virtualMemoryStat, err := mem.VirtualMemory()
if err != nil {
return nil, err
}
return &MemoryMetric{
TotalMemory: virtualMemoryStat.Total,
AvailableMemory: virtualMemoryStat.Available,
UsedMemory: virtualMemoryStat.Used,
UsedPercent: virtualMemoryStat.UsedPercent,
FreeMemory: virtualMemoryStat.Free,
}, nil
}
func GetMemoryInfo() (*MemoryInfo, error) {
virtualMemoryStat, err := mem.VirtualMemory()
if err != nil {
return nil, err
}
return &MemoryInfo{
MemoryMetric: MemoryMetric{
TotalMemory: virtualMemoryStat.Total,
AvailableMemory: virtualMemoryStat.Available,
UsedMemory: virtualMemoryStat.Used,
UsedPercent: virtualMemoryStat.UsedPercent,
FreeMemory: virtualMemoryStat.Free,
},
Buffers: virtualMemoryStat.Buffers,
Cached: virtualMemoryStat.Cached,
WriteBack: virtualMemoryStat.WriteBack,
Dirty: virtualMemoryStat.Dirty,
WriteBackTmp: virtualMemoryStat.WriteBackTmp,
Shared: virtualMemoryStat.Shared,
Slab: virtualMemoryStat.Slab,
Sreclaimable: virtualMemoryStat.Sreclaimable,
Sunreclaim: virtualMemoryStat.Sunreclaim,
PageTables: virtualMemoryStat.PageTables,
SwapCached: virtualMemoryStat.SwapCached,
CommitLimit: virtualMemoryStat.CommitLimit,
CommittedAS: virtualMemoryStat.CommittedAS,
HighTotal: virtualMemoryStat.HighTotal,
HighFree: virtualMemoryStat.HighFree,
LowTotal: virtualMemoryStat.LowTotal,
LowFree: virtualMemoryStat.LowFree,
SwapTotal: virtualMemoryStat.SwapTotal,
SwapFree: virtualMemoryStat.SwapFree,
Mapped: virtualMemoryStat.Mapped,
VmallocTotal: virtualMemoryStat.VmallocTotal,
VmallocUsed: virtualMemoryStat.VmallocUsed,
VmallocChunk: virtualMemoryStat.VmallocChunk,
HugePagesTotal: virtualMemoryStat.HugePagesTotal,
HugePagesFree: virtualMemoryStat.HugePagesFree,
HugePagesRsvd: virtualMemoryStat.HugePagesRsvd,
HugePagesSurp: virtualMemoryStat.HugePagesSurp,
HugePageSize: virtualMemoryStat.HugePageSize,
}, nil
}
func FormatMemorySize(size uint64) string {
const unit = 1024
if size < unit {
return fmt.Sprintf("%d B", size)
}
div, exp := int64(unit), 0
for n := size / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %cB", float64(size)/float64(div), "KMGTPE"[exp])
}

View File

@@ -0,0 +1,49 @@
package a_status
import (
"encoding/json"
"fmt"
"testing"
)
func TestGetMemoryStatus(t *testing.T) {
memoryStatus, err := GetMemoryMetric()
if err != nil {
return
}
fmt.Printf("Total Memory: %s\n", FormatMemorySize(memoryStatus.TotalMemory))
fmt.Printf("Available Memory: %s\n", FormatMemorySize(memoryStatus.AvailableMemory))
fmt.Printf("Used Memory: %s\n ", FormatMemorySize(memoryStatus.UsedMemory))
fmt.Printf("UsedPercent: %.2f %%\n", memoryStatus.UsedPercent)
fmt.Printf("Free Memory: %s\n", FormatMemorySize(memoryStatus.FreeMemory))
marshalIndent, err := json.MarshalIndent(memoryStatus, "", " ")
if err != nil {
fmt.Printf("error")
}
fmt.Println(string(marshalIndent))
}
func TestGetMemoryInfo(t *testing.T) {
memoryStatus, err := GetMemoryInfo()
if err != nil {
return
}
fmt.Printf("Total Memory: %s\n", FormatMemorySize(memoryStatus.TotalMemory))
fmt.Printf("Used Memory: %s\n", FormatMemorySize(memoryStatus.UsedMemory))
fmt.Printf("Available Memory: %s\n", FormatMemorySize(memoryStatus.AvailableMemory))
fmt.Printf("UsedPercent: %.2f %%\n", memoryStatus.UsedPercent)
fmt.Printf("Free Memory: %s\n", FormatMemorySize(memoryStatus.FreeMemory))
marshalIndent, err := json.MarshalIndent(memoryStatus, "", " ")
if err != nil {
fmt.Printf("error")
}
fmt.Println(string(marshalIndent))
}

View File

@@ -0,0 +1,330 @@
package a_status
import (
"encoding/json"
"errors"
"fmt"
"github.com/shirou/gopsutil/v3/net"
net2 "net"
"regexp"
"strconv"
"strings"
"time"
"wdd.io/agent-common/utils"
)
type NetworkMetric struct {
net.IOCountersStat
SendSpeed float64
RecvSpeed float64
}
type NetworkInfo struct {
Name string `json:"name"` // e.g., "en0", "lo0", "eth0.100"
MTU int `json:"mtu"` // maximum transmission unit
HardwareAddr string `json:"hardwareAddr"` // IEEE MAC-48, EUI-48 and EUI-64 form
Flags []string `json:"flags"` // e.g., FlagUp, FlagLoopback, FlagMulticast
InternalIPv4 []string `json:"internal_ip_v4,omitempty"`
InternalIPv6 []string `json:"internal_ip_v6,omitempty"`
ExternalIPv4 []string `json:"external_ip_v4,omitempty"`
ExternalIPv6 []string `json:"external_ip_v6,omitempty"`
}
type NetworkStatus struct {
Name string `json:"name,omitempty"`
InternalIPv4 []string `json:"internal_ip_v4,omitempty"`
InternalIPv6 []string `json:"internal_ip_v6,omitempty"`
ExternalIPv4 []string `json:"external_ip_v4,omitempty"`
ExternalIPv6 []string `json:"external_ip_v6,omitempty"`
Mac string `json:"mac,omitempty"`
Sent uint64 `json:"sent,omitempty"`
Recv uint64 `json:"recv,omitempty"`
SentRate string `json:"sent_rate,omitempty"`
RecvRate string `json:"recv_rate,omitempty"`
}
func GetNetworkMetric() ([]NetworkMetric, error) {
interfaceStatList, err := net.Interfaces()
if err != nil {
log.ErrorF("[GetNetworkMetric] - get interface list error %v\n", err)
return nil, err
}
contains := false
for _, interfaceStat := range interfaceStatList {
if MatchNetInterfaceRight(interfaceStat.Name) {
contains = true
break
}
}
if !contains {
msg := "[GetNetworkMetric]- can not find desired net interface !"
log.Warn(msg)
return nil, errors.New(msg)
}
ioCountersStats, err := net.IOCounters(true)
if err != nil {
log.ErrorF("[GetNetworkMetric] - get io counter list error %v\n", err)
return nil, err
}
//marshal, _ := json.Marshal(ioCountersStats)
//fmt.Println(string(marshal))
duration := time.Second * 2
log.DebugF("[GetNetworkMetric] - start to wait %d seconds ", duration/1000000000)
time.Sleep(duration)
afterIoCounterList, err := net.IOCounters(true)
if err != nil {
log.ErrorF("[GetNetworkMetric] - get io counter list second error %v\n", err)
return nil, err
}
var result []NetworkMetric
for _, interfaceStat := range interfaceStatList {
if MatchNetInterfaceRight(interfaceStat.Name) {
log.DebugF("[GetNetworkMetric] - match net interface name is => %s", interfaceStat.Name)
for _, after := range afterIoCounterList {
if strings.HasPrefix(after.Name, interfaceStat.Name) {
for _, before := range ioCountersStats {
if strings.HasPrefix(before.Name, interfaceStat.Name) {
// match after and before interface
// assign
networkMetric := NetworkMetric{
IOCountersStat: after,
SendSpeed: 0,
RecvSpeed: 0,
}
// calculate speed
networkMetric.SendSpeed = (float64(after.BytesSent - before.BytesSent)) / duration.Seconds()
networkMetric.RecvSpeed = (float64(after.BytesRecv - before.BytesRecv)) / duration.Seconds()
// append result
result = append(result, networkMetric)
}
}
}
}
}
}
return result, nil
}
func GetNetworkInfo() ([]NetworkInfo, error) {
interfaceStatList, err := net.Interfaces()
if err != nil {
log.ErrorF("[GetNetworkInfo] - get net interface list error %s", err.Error())
}
var result []NetworkInfo
for _, interfaceStat := range interfaceStatList {
if MatchNetInterfaceRight(interfaceStat.Name) {
// just collect useful net interface
// new result
networkInfo := NetworkInfo{
Name: interfaceStat.Name,
MTU: interfaceStat.MTU,
HardwareAddr: interfaceStat.HardwareAddr,
Flags: interfaceStat.Flags,
InternalIPv4: []string{},
InternalIPv6: []string{},
ExternalIPv4: nil,
ExternalIPv6: nil,
}
// calculate real ip addr
for _, interfaceAddr := range interfaceStat.Addrs {
ip, cidr, err := net2.ParseCIDR(interfaceAddr.Addr)
if err != nil {
log.ErrorF("[GetNetworkInfo] - parse interface addr error %v", err)
continue
}
// get the mask size
maskLength, _ := cidr.Mask.Size()
if ip.To4() != nil {
networkInfo.InternalIPv4 = append(networkInfo.InternalIPv4, ip.String()+"/"+strconv.Itoa(maskLength))
} else if ip.To16() != nil {
networkInfo.InternalIPv6 = append(networkInfo.InternalIPv6, ip.String()+"/"+strconv.Itoa(maskLength))
}
}
// assign
result = append(result, networkInfo)
}
}
return result, nil
}
func GetLocalHostIP() string {
interfaceStatList, err := net.Interfaces()
if err != nil {
log.ErrorF("[GetLocalHostIP] -- error %s", err.Error())
return ""
}
utils.BeautifulPrint(interfaceStatList)
return ""
}
func GetNetworkConnectionALl() []net.ConnectionStat {
connections, err := net.Connections("all")
if err != nil {
log.ErrorF("[GetNetworkConnectionALl] - get network connections error ! %v", err)
return nil
}
for _, con := range connections {
fmt.Println()
marshal, _ := json.Marshal(con)
fmt.Println(string(marshal))
fmt.Println()
}
return connections
}
func GetNetworkConnectionTCP4() {
}
func GetNetworkConnectionTCP6() {
connections, _ := net.Connections("tcp6")
for _, con := range connections {
fmt.Println()
marshal, _ := json.Marshal(con)
fmt.Println(string(marshal))
fmt.Println()
}
}
func GetNetworkConnectionUDP4() {
}
func GetNetworkConnectionUDP6() {
}
func GetNetworkStatus() (*NetworkStatus, error) {
interfaces, err := net.Interfaces()
if err != nil {
return nil, err
}
var mainInterface net.InterfaceStat
for _, intf := range interfaces {
if strings.HasPrefix(intf.Name, "ens") || strings.HasPrefix(intf.Name, "eth") || strings.HasPrefix(intf.Name, "eno") {
mainInterface = intf
break
}
}
var allAddrs []string
log.DebugF("all main interface address are %v", mainInterface.Addrs)
for _, addr := range mainInterface.Addrs {
allAddrs = append(allAddrs, addr.Addr)
}
ipv4List, ipv6List := GetInternalIpAdders(allAddrs)
log.DebugF("ipv4 list are => %v, ipv6 list are => %v", ipv4List, ipv6List)
counters, err := net.IOCounters(true)
if err != nil {
return nil, err
}
var sent uint64
var recv uint64
for _, counter := range counters {
if counter.Name == mainInterface.Name {
sent = counter.BytesSent
recv = counter.BytesRecv
break
}
}
// 休眠3秒
time.Sleep(3 * time.Second)
var sentAfter uint64
var recvAfter uint64
countersAfter, err := net.IOCounters(true)
if err != nil {
return nil, err
}
for _, counter := range countersAfter {
if counter.Name == mainInterface.Name {
sentAfter = counter.BytesSent
recvAfter = counter.BytesRecv
break
}
}
sendRate := fmt.Sprintf(formatBytes((sentAfter-sent)/3) + "/s")
recvRate := fmt.Sprintf(formatBytes((recvAfter-recv)/3) + "/s")
info := &NetworkStatus{
Name: mainInterface.Name,
InternalIPv4: ipv4List,
InternalIPv6: ipv6List,
ExternalIPv4: nil,
ExternalIPv6: nil,
Mac: mainInterface.HardwareAddr,
Sent: sent,
Recv: recv,
SentRate: sendRate,
RecvRate: recvRate,
}
return info, nil
}
func formatBytes(bytes uint64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
}
func GetInternalIpAdders(addresses []string) (ipv4List []string, ipv6List []string) {
for _, addr := range addresses {
// it parse (0.0.0.0) not cidr
ip, _, err := net2.ParseCIDR(addr)
if err != nil {
continue
}
if ip.To4() != nil {
ipv4List = append(ipv4List, addr)
} else if ip.To16() != nil {
ipv6List = append(ipv6List, addr)
}
}
return ipv4List, ipv6List
}
func MatchNetInterfaceRight(interfaceName string) bool {
match, _ := regexp.MatchString(`^(eth|enp|wlan|ens|eno)\d+`, interfaceName)
if match {
return true
}
match, _ = regexp.MatchString(`^(lo)`, interfaceName)
if match {
return true
}
return match
}

View File

@@ -0,0 +1,44 @@
package a_status
import (
"encoding/json"
"fmt"
"testing"
"wdd.io/agent-common/utils"
)
func TestMatchNetInterfaceRight(t *testing.T) {
interfaceNames := []string{"eth0", "eth1", "enp3s0", "wlan0", "lo", "ens12", "eno1", "asdas", "en0"}
for _, name := range interfaceNames {
if MatchNetInterfaceRight(name) {
t.Logf("匹配到的网卡名称: %s\n", name)
}
}
}
func TestGetNetworkMetric(t *testing.T) {
metric, err := GetNetworkMetric()
if err != nil {
t.Logf("get network metric error %s\n", err.Error())
}
for _, networkMetric := range metric {
fmt.Println()
bytes, _ := json.MarshalIndent(networkMetric, "", " ")
fmt.Println(string(bytes))
fmt.Println()
}
}
func TestGetNetworkInfo(t *testing.T) {
networkInfos, err := GetNetworkInfo()
if err != nil {
t.Errorf("GetNetworkInfo error of %s", err)
}
for _, networkInfo := range networkInfos {
utils.BeautifulPrint(networkInfo)
}
}

308
agent-go/a_status/Status.go Normal file
View File

@@ -0,0 +1,308 @@
package a_status
import (
"fmt"
"time"
"wdd.io/agent-common/logger"
"wdd.io/agent-go/g"
)
var log = logger.Log
var pool = g.G.P
type StatusMessage struct {
/**
* which kind of status should be return
"PING";
* METRIC => short time message
* ALL => all agent status message
* */
StatusType string `json:"statusType,omitempty"`
MetricRepeatCount int `json:"metricRepeatCount,omitempty"`
metricRepeatPinch int `json:"metricRepeatPinch,omitempty"`
}
type AgentMetric struct {
CPUMetric *CPUMetric
MemoryMetric *MemoryMetric
NetworkMetric []NetworkMetric
DiskMetric []DiskInfo
DockerMetric *DockerMetric
}
type AgentInfo struct {
CPUInfo *CPUInfo
MemoryInfo *MemoryInfo
NetworkInfo []NetworkInfo
DiskInfo []DiskInfo
HostInfo *HostInfo
DockerInfo *DockerMetric
}
func Activate() {
log.Info("Module [ STATUS ] activated !")
//v, ok := (octopusMessage.Content).(string)
//if !ok {
// log.ErrorF("convert to string is wrong %s", v)
//}
//
//statusMsgString := octopusMessage.Content.(string)
//
//var statusMessage *a_status.StatusMessage
//err := json.Unmarshal([]byte(statusMsgString), &statusMessage)
//if err != nil {
// fmt.Println(err.Error())
// log.Error(fmt.Sprintf("status message convert to json is wrong! msg is => %s", octopusMessage))
// return
//}
//
//// OMessageStatusTypeEnum
//var statusRes string
//if strings.HasPrefix(statusMessage.StatusType, "PING") {
// // ping info
// statusRes = a_status.Ping()
//} else if strings.HasPrefix(statusMessage.StatusType, "METRIC") {
// // metric info
// agentStatusString, _ := json.Marshal(a_status.ReportAgentMetric())
// statusRes = string(agentStatusString)
//} else if strings.HasPrefix(statusMessage.StatusType, "INFO") {
// log.InfoF("[statusOMHandler] - call for agent info !")
//} else {
// log.WarnF("[statusOMHandler] - error octopus status message type of %s", statusMessage.StatusType)
//}
//
//// 返回消息
//// 组装消息
//octopusMessage.ACTime = utils.ParseDateTimeTime()
//octopusMessage.Result = statusRes
//// 发送回去
//statusOctopusReplayMessage, _ := json.Marshal(octopusMessage)
//OctopusToServerQueue.Send(statusOctopusReplayMessage)
//
//// 输出日志
//log.InfoF("接收到查询Agent状态的请求结果为 => %s", statusRes)
}
func Ping() string {
return "PONG"
}
func ReportAgentMetric() *AgentMetric {
lenOfAgentMetric := 5
waitResultChan := make(chan string, lenOfAgentMetric)
timeout := time.After(5 * time.Second)
var err error
var cpuMetric *CPUMetric
err = pool.Submit(func() {
cpuMetric, err = GetCPUMetric()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetCPUMetric error !"
return
}
waitResultChan <- "GetCPUMetric success !"
})
if err != nil {
log.ErrorF("[ReportAgentMetric] - GetCPUMetric exec error => %v", err)
}
var memoryMetric *MemoryMetric
err = pool.Submit(func() {
memoryMetric, err = GetMemoryMetric()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetMemoryMetric error !"
return
}
waitResultChan <- "GetMemoryMetric success !"
})
if err != nil {
log.ErrorF("[ReportAgentMetric] - GetMemoryMetric exec error => %v", err)
}
var diskInfoList []DiskInfo
err = pool.Submit(func() {
diskInfoList, err = GetDiskInfo()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetDiskInfo error !"
return
}
waitResultChan <- "GetDiskInfo success !"
})
if err != nil {
log.ErrorF("[ReportAgentMetric] - GetDiskInfo exec error => %v", err)
}
var networkMetric []NetworkMetric
err = pool.Submit(func() {
networkMetric, err = GetNetworkMetric()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetNetworkMetric error !"
return
}
waitResultChan <- "GetNetworkMetric success !"
})
if err != nil {
log.ErrorF("[ReportAgentMetric] - GetNetworkMetric exec error => %v", err)
}
var dockerMetric *DockerMetric
err = pool.Submit(func() {
dockerMetric, err = GetDockerMetric()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetDockerMetric error !"
return
}
waitResultChan <- "GetDockerMetric success !"
})
if err != nil {
log.ErrorF("[ReportAgentMetric] - GetDockerMetric exec error => %v", err)
}
for i := 0; i < lenOfAgentMetric; i++ {
select {
case result := <-waitResultChan:
log.DebugF("[ReportAgentMetric] - metric received => %s", result)
case <-timeout:
fmt.Println("[ReportAgentMetric] - Timeout! Not all results received.")
break
}
}
return &AgentMetric{
CPUMetric: cpuMetric,
MemoryMetric: memoryMetric,
NetworkMetric: networkMetric,
DiskMetric: diskInfoList,
DockerMetric: dockerMetric,
}
}
func ReportAgentInfo() *AgentInfo {
lenOfAgentMetric := 6
waitResultChan := make(chan string, lenOfAgentMetric)
timeout := time.After(5 * time.Second)
var err error
var cpuInfo *CPUInfo
err = pool.Submit(func() {
cpuInfo, err = GetCPUInfo()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetCPUInfo error !"
return
}
waitResultChan <- "GetCPUInfo success !"
})
if err != nil {
log.ErrorF("[ReportAgentInfo] - GetCPUInfo exec error => %v", err)
}
var memoryInfo *MemoryInfo
err = pool.Submit(func() {
memoryInfo, err = GetMemoryInfo()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetMemoryInfo error !"
return
}
waitResultChan <- "GetMemoryInfo success !"
})
if err != nil {
log.ErrorF("[ReportAgentInfo] - GetMemoryInfo exec error => %v", err)
}
var diskInfoList []DiskInfo
err = pool.Submit(func() {
diskInfoList, err = GetDiskInfo()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetDiskInfo error !"
return
}
waitResultChan <- "GetDiskInfo success !"
})
if err != nil {
log.ErrorF("[ReportAgentInfo] - GetDiskInfo exec error => %v", err)
}
var hostInfo *HostInfo
err = pool.Submit(func() {
hostInfo, err = GetHostInfo()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetHostInfo error !"
return
}
waitResultChan <- "hostInfo success !"
})
if err != nil {
log.ErrorF("[ReportAgentInfo] - hostInfo exec error => %v", err)
}
var networkInfo []NetworkInfo
err = pool.Submit(func() {
networkInfo, err = GetNetworkInfo()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetNetworkInfo error !"
return
}
waitResultChan <- "GetNetworkInfo success !"
})
if err != nil {
log.ErrorF("[ReportAgentInfo] - GetNetworkInfo exec error => %v", err)
}
var dockerMetric *DockerMetric
err = pool.Submit(func() {
dockerMetric, err = GetDockerMetric()
if err != nil {
log.ErrorF("获取Agent的状态出现错误 请检查 => %v", err)
waitResultChan <- "GetDockerMetric error !"
return
}
waitResultChan <- "GetDockerMetric success !"
})
if err != nil {
log.ErrorF("[ReportAgentInfo] - GetDockerMetric exec error => %v", err)
}
for i := 0; i < lenOfAgentMetric; i++ {
select {
case result := <-waitResultChan:
log.DebugF("[ReportAgentInfo] - metric received => %s", result)
case <-timeout:
fmt.Println("[ReportAgentInfo] - Timeout! Not all results received.")
break
}
}
return &AgentInfo{
CPUInfo: cpuInfo,
MemoryInfo: memoryInfo,
NetworkInfo: networkInfo,
DiskInfo: diskInfoList,
HostInfo: hostInfo,
DockerInfo: dockerMetric,
}
}
func ConvertToFormat(eventData float64) string {
duration := time.Duration(eventData) * time.Second
fmt.Println(duration)
hours := int(duration.Hours())
minutes := int(duration.Minutes()) % 60
seconds := int(duration.Seconds()) % 60
milliseconds := duration.Milliseconds() % 1000
return fmt.Sprintf("%02d:%02d:%02d,%03d", hours, minutes, seconds, milliseconds)
}

View File

@@ -0,0 +1,38 @@
package a_status
import (
"fmt"
"testing"
"time"
"wdd.io/agent-common/utils"
)
func TestConvertToFormat(t *testing.T) {
convertToFormat := ConvertToFormat(99.92)
fmt.Println(convertToFormat)
}
func TestReportAppStatus(t *testing.T) {
startTime := time.Now()
agentStatus := ReportAgentMetric()
endTime := time.Now()
elapsedTime := endTime.Sub(startTime)
fmt.Println("函数执行时间:", elapsedTime)
utils.BeautifulPrint(agentStatus)
}
func TestReportAgentInfo(t *testing.T) {
startTime := time.Now()
agentInfo := ReportAgentInfo()
endTime := time.Now()
elapsedTime := endTime.Sub(startTime)
fmt.Println("函数执行时间:", elapsedTime)
utils.BeautifulPrint(agentInfo)
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,188 @@
{
"CPUMetric": {
"NumCores": 8,
"CPUPercent": 33.37515683815345,
"CPULoads": {
"load1": 3.94,
"load5": 2.64,
"load15": 2
}
},
"MemoryMetric": {
"TotalMemory": 16604577792,
"AvailableMemory": 10842226688,
"UsedMemory": 4859039744,
"usedPercent": 29.263253813903418,
"free": 6947397632
},
"NetworkMetric": [
{
"name": "lo",
"bytesSent": 10833552,
"bytesRecv": 10833552,
"packetsSent": 134017,
"packetsRecv": 134017,
"errin": 0,
"errout": 0,
"dropin": 0,
"dropout": 0,
"fifoin": 0,
"fifoout": 0,
"SendSpeed": 7084.5,
"RecvSpeed": 7084.5
},
{
"name": "eno2",
"bytesSent": 42069937,
"bytesRecv": 9954190,
"packetsSent": 96154,
"packetsRecv": 114005,
"errin": 0,
"errout": 0,
"dropin": 0,
"dropout": 0,
"fifoin": 0,
"fifoout": 0,
"SendSpeed": 160668.5,
"RecvSpeed": 28342
}
],
"DiskInfo": [
{
"device": "/dev/nvme0n1p7",
"mountpoint": "/",
"fstype": "ext4",
"total": 153682100224,
"free": 54671085568,
"used": 91129868288,
"usedPercent": 62.502930109774326
},
{
"device": "/dev/nvme0n1p1",
"mountpoint": "/boot/efi",
"fstype": "vfat",
"total": 520093696,
"free": 426680320,
"used": 93413376,
"usedPercent": 17.96087449596774
}
],
"HostInfo": {
"hostname": "wdd-Lap-Office",
"uptime": 1980,
"bootTime": 1705560863,
"procs": 358,
"os": "linux",
"platform": "ubuntu",
"platformFamily": "debian",
"platformVersion": "20.04",
"kernelVersion": "5.15.0-91-generic",
"kernelArch": "x86_64",
"virtualizationSystem": "kvm",
"virtualizationRole": "host",
"hostId": "4c4c4544-004e-4a10-8036-b7c04f4e3533"
},
"DockerMetric": {
"DockerStats": [
{
"containerID": "b256661bcab1626be7fba15c487db61082de68dca473e145f66db7b06f212e4a",
"name": "octopus-redis-1",
"image": "redis/redis-stack:6.2.6-v10",
"status": "Up 32 minutes",
"running": true
},
{
"containerID": "04334154b90fabb2e5f595d4746641a75deb85b00848791492bc9742e8119da1",
"name": "octopus-rabbitmq-1",
"image": "docker.io/bitnami/rabbitmq:3.11.10-debian-11-r0",
"status": "Up 32 minutes",
"running": true
},
{
"containerID": "48c759747ab0bc24c4411fcfd59f1f33a50e71986eab582cb92c3cfaa2c38b6b",
"name": "octopus-mysql-1",
"image": "bitnami/mysql:8.0.32-debian-11-r12",
"status": "Up 32 minutes (unhealthy)",
"running": true
},
{
"containerID": "b1016d88ba47aacf1cccbbf90d6ac04b0ccdfbf6de15ca31303d5af8c7c1d897",
"name": "harbor-jobservice",
"image": "goharbor/harbor-jobservice:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "0d2321d74fe8c7261a6a368d8ca7d0f6b3029eff16bdf490bdfd7c51d81f7ac1",
"name": "nginx",
"image": "goharbor/nginx-photon:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "9b6ad191743d6a0422a62bfbf7fcc3477645f296df88479ff584a3032b7a3991",
"name": "harbor-core",
"image": "goharbor/harbor-core:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "84c452be11a3b51bf82ccdd3b5e92044d230929f34141a3782fcc8b53e549d80",
"name": "harbor-db",
"image": "goharbor/harbor-db:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "f5f1da78ea2ac4141571d426f7457cb9d16befd69443d353dbede27b085326fb",
"name": "registryctl",
"image": "goharbor/harbor-registryctl:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "b2e97123f38b3c95ec58f4b494cc1f261cbef184834ec0584e50377ae3923bb0",
"name": "registry",
"image": "goharbor/registry-photon:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "1ba12ec625c13be6ecb052330443d6748b0ab9e692302397fadfad085768906f",
"name": "harbor-portal",
"image": "goharbor/harbor-portal:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "250afc54541ddc7318dc7ff3a62013ca1da538de089e676b1d44c1e487742e0d",
"name": "redis",
"image": "goharbor/redis-photon:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "a2724d367906efd2c6277d405c5d3da00a80a206c4f9b10aa9a867b735c441f9",
"name": "harbor-log",
"image": "goharbor/harbor-log:v2.9.0",
"status": "Up 32 minutes (healthy)",
"running": true
},
{
"containerID": "ea12324df45a77f1f073e88f11de7eae0a95ce5a32c0c30992cdf689d705a842",
"name": "wdd-minio1-1",
"image": "bitnami/minio:2022.5.4",
"status": "Up 32 minutes",
"running": true
},
{
"containerID": "d2df045ccb00b8c7ad14635556217cec743be4d302091ff1bfaa1039277e6da6",
"name": "root-minio1-1",
"image": "bitnami/minio:2022.5.4",
"status": "Exited (1) 5 months ago",
"running": false
}
]
}
}