mirror of
https://github.com/fankes/komari-agent.git
synced 2025-10-19 02:59:23 +08:00
feat(monitoring): 增加网络总量和进程计数监控
- 在 net.go 中添加总量统计功能,记录上次采样值 - 在 main.go 中添加进程计数监控 - 修改 remote.go 中的 JSON 字段名称 - 优化 report 函数,增加网络总量和进程计数数据
This commit is contained in:
@@ -16,10 +16,10 @@ type RemoteConfig struct {
|
||||
Swap bool `json:"swap"`
|
||||
Load bool `json:"load"`
|
||||
Uptime bool `json:"uptime"`
|
||||
Temperature bool `json:"temperature"`
|
||||
Temperature bool `json:"temp"`
|
||||
Os bool `json:"os"`
|
||||
Disk bool `json:"disk"`
|
||||
Network bool `json:"network"`
|
||||
Network bool `json:"net"`
|
||||
Process bool `json:"process"`
|
||||
Interval int `json:"interval"`
|
||||
Connections bool `json:"connections"`
|
||||
@@ -38,7 +38,7 @@ func LoadRemoteConfig(endpoint string, token string) (RemoteConfig, error) {
|
||||
var err error
|
||||
|
||||
for attempt := 1; attempt <= maxRetry; attempt++ {
|
||||
resp, err = http.Get(endpoint,)
|
||||
resp, err = http.Get(endpoint)
|
||||
if err == nil && resp.StatusCode == http.StatusOK {
|
||||
break
|
||||
}
|
||||
|
23
main.go
23
main.go
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"komari/config"
|
||||
"komari/monitoring"
|
||||
"log"
|
||||
@@ -181,8 +182,14 @@ func uploadBasicInfo(endpoint string, token string) error {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
message := string(body)
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("status code: %d", resp.StatusCode)
|
||||
return fmt.Errorf("status code: %d,%s", resp.StatusCode, message)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -229,13 +236,15 @@ func report(localConfig config.LocalConfig, remoteConfig config.RemoteConfig) []
|
||||
}
|
||||
}
|
||||
if remoteConfig.Network {
|
||||
networkUp, networkDown, err := monitoring.NetworkSpeed()
|
||||
totalUp, totalDown, networkUp, networkDown, err := monitoring.NetworkSpeed(remoteConfig.Interval)
|
||||
if err != nil {
|
||||
message += fmt.Sprintf("failed to get network speed: %v\n", err)
|
||||
}
|
||||
data["network"] = map[string]interface{}{
|
||||
"up": networkUp,
|
||||
"down": networkDown,
|
||||
"up": networkUp,
|
||||
"down": networkDown,
|
||||
"totalUp": totalUp,
|
||||
"totalDown": totalDown,
|
||||
}
|
||||
}
|
||||
if remoteConfig.Connections {
|
||||
@@ -243,7 +252,7 @@ func report(localConfig config.LocalConfig, remoteConfig config.RemoteConfig) []
|
||||
if err != nil {
|
||||
message += fmt.Sprintf("failed to get connections: %v\n", err)
|
||||
}
|
||||
data["network"] = map[string]interface{}{
|
||||
data["connections"] = map[string]interface{}{
|
||||
"tcp": tcpCount,
|
||||
"udp": udpCount,
|
||||
}
|
||||
@@ -255,6 +264,10 @@ func report(localConfig config.LocalConfig, remoteConfig config.RemoteConfig) []
|
||||
}
|
||||
data["uptime"] = uptime
|
||||
}
|
||||
if remoteConfig.Process {
|
||||
processcount := monitoring.ProcessCount()
|
||||
data["process"] = processcount
|
||||
}
|
||||
data["message"] = message
|
||||
|
||||
s, err := json.Marshal(data)
|
||||
|
@@ -19,15 +19,20 @@ func ConnectionsCount() (tcpCount, udpCount int, err error) {
|
||||
return len(tcps), len(udps), nil
|
||||
}
|
||||
|
||||
func NetworkSpeed() (upSpeed, downSpeed float64, err error) {
|
||||
var (
|
||||
lastUp uint64
|
||||
lastDown uint64
|
||||
)
|
||||
|
||||
func NetworkSpeed(interval int) (totalUp, totalDown, upSpeed, downSpeed uint64, err error) {
|
||||
// Get the network IO counters
|
||||
ioCounters, err := net.IOCounters(false)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to get network IO counters: %w", err)
|
||||
return 0, 0, 0, 0, fmt.Errorf("failed to get network IO counters: %w", err)
|
||||
}
|
||||
|
||||
if len(ioCounters) == 0 {
|
||||
return 0, 0, fmt.Errorf("no network interfaces found")
|
||||
return 0, 0, 0, 0, fmt.Errorf("no network interfaces found")
|
||||
}
|
||||
|
||||
for _, interfaceStats := range ioCounters {
|
||||
@@ -42,10 +47,14 @@ func NetworkSpeed() (upSpeed, downSpeed float64, err error) {
|
||||
if isLoopback {
|
||||
continue // Skip loopback interface
|
||||
}
|
||||
upSpeed += float64(interfaceStats.BytesSent) / float64(interfaceStats.PacketsSent)
|
||||
downSpeed += float64(interfaceStats.BytesRecv) / float64(interfaceStats.PacketsRecv)
|
||||
totalUp += interfaceStats.BytesSent
|
||||
totalDown += interfaceStats.BytesRecv
|
||||
|
||||
}
|
||||
upSpeed = (totalUp - lastUp) / uint64(interval)
|
||||
downSpeed = (totalDown - lastDown) / uint64(interval)
|
||||
|
||||
return upSpeed, downSpeed, nil
|
||||
lastUp = totalUp
|
||||
lastDown = totalDown
|
||||
return totalUp, totalDown, upSpeed, downSpeed, nil
|
||||
}
|
||||
|
77
monitoring/process.go
Normal file
77
monitoring/process.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package monitoring
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// ProcessCount returns the number of running processes
|
||||
func ProcessCount() (count int) {
|
||||
if runtime.GOOS == "windows" {
|
||||
return processCountWindows()
|
||||
}
|
||||
return processCountLinux()
|
||||
}
|
||||
|
||||
// processCountLinux counts processes by reading /proc directory
|
||||
func processCountLinux() (count int) {
|
||||
procDir := "/proc"
|
||||
|
||||
entries, err := os.ReadDir(procDir)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
if _, err := strconv.ParseInt(entry.Name(), 10, 64); err == nil {
|
||||
//if _, err := filepath.ParseInt(entry.Name(), 10, 64); err == nil {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
// processCountWindows counts processes using Windows API
|
||||
func processCountWindows() (count int) {
|
||||
// Load kernel32.dll
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
|
||||
// Get EnumProcesses function
|
||||
enumProcesses, err := syscall.GetProcAddress(kernel32, "K32EnumProcesses")
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Prepare buffer for process IDs
|
||||
const maxProcesses = 1024
|
||||
pids := make([]uint32, maxProcesses)
|
||||
var bytesReturned uint32
|
||||
|
||||
// Call EnumProcesses
|
||||
ret, _, _ := syscall.SyscallN(
|
||||
uintptr(enumProcesses),
|
||||
uintptr(unsafe.Pointer(&pids[0])),
|
||||
uintptr(len(pids)*4),
|
||||
uintptr(unsafe.Pointer(&bytesReturned)),
|
||||
)
|
||||
|
||||
if ret == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Count valid PIDs
|
||||
count = int(bytesReturned) / 4 // bytesReturned is size in bytes, divide by 4 for uint32 count
|
||||
if count > maxProcesses {
|
||||
count = maxProcesses
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
Reference in New Issue
Block a user