zadmin/internal/agent/collect.go
2024-12-14 15:45:40 +01:00

148 lines
3.4 KiB
Go

package agent
import (
"encoding/json"
"log"
"net/http"
"os"
"time"
"github.com/mackerelio/go-osstat/cpu"
"github.com/mackerelio/go-osstat/loadavg"
"github.com/mackerelio/go-osstat/memory"
"github.com/mackerelio/go-osstat/uptime"
"git.mziesel.nl/mans/zadmin/internal/models"
"github.com/nats-io/nats.go"
)
func PublishMachineData(ac models.MachineAgentConfig, nc *nats.Conn) {
machineData, err := GetMachine(ac)
if err != nil {
LogError("failed to get Machine", err)
return
}
machineDataJSON, err := json.Marshal(machineData)
if err != nil {
LogError("failed to marshal Machine", err)
return
}
if err := nc.Publish("client/machinedata", machineDataJSON); err != nil {
LogError("failed to publish Machine", err)
}
log.Println("sent data to nats-server")
}
func GetMachine(ac models.MachineAgentConfig) (models.Machine, error) {
data := models.Machine{}
// get hostname
hostname, err := os.Hostname()
if err != nil {
LogError("failed to get system hostname", err)
return data, err
}
data.Hostname = hostname
type IPResponse struct {
Address string `json:"address"`
}
// get public ipv4
ip4resp, err := http.Get(ac.GetIPv4Endpoint)
if err != nil {
LogError("failed to get IPv4 address", err)
return data, err
}
ipResponseBody := IPResponse{}
if err := json.NewDecoder(ip4resp.Body).Decode(&ipResponseBody); err != nil {
LogError("failed to decode IPv4 address", err)
return data, err
}
data.PublicIPv4Address = ipResponseBody.Address
// get public ipv6
ip6resp, err := http.Get(ac.GetIPv6Endpoint)
if err != nil {
LogError("failed to get IPv6 address", err)
return data, err
}
if err := json.NewDecoder(ip6resp.Body).Decode(&ipResponseBody); err != nil {
LogError("failed to decode IPv6 address", err)
return data, err
}
data.PublicIPv6Address = ipResponseBody.Address
// get machine uptime
uptime, err := uptime.Get()
if err != nil {
LogError("failed to get machine uptime", err)
return data, nil
}
data.UptimeSeconds = int(uptime.Seconds())
// get useage statistics
useageStatistics, err := CollectUsageStatistics(ac)
if err != nil {
LogError("failed to get useage statistics", err)
return data, nil
}
data.UsageStatistics = useageStatistics
return data, nil
}
func LogError(msg string, err error) {
log.Printf("ERROR: %s: %v", msg, err)
}
func CollectUsageStatistics(ac models.MachineAgentConfig) (models.UsageStatistics, error) {
statistics := models.UsageStatistics{}
statistics.TimeCollected = time.Now()
memory, err := memory.Get()
if err != nil {
LogError("failed to collect memory statistics", err)
return statistics, err
}
statistics.MemoryTotal = memory.Total
statistics.MemoryUsed = memory.Used
statistics.MemoryCached = memory.Cached
statistics.MemoryFree = memory.Free
statistics.MemoryAvailable = memory.Available
cpu, err := cpu.Get()
if err != nil {
LogError("failed to collect cpu statistics", err)
return statistics, err
}
statistics.CpuUser = cpu.User
statistics.CpuSystem = cpu.System
statistics.CpuIdle = cpu.Idle
statistics.CpuIowait = cpu.Iowait
statistics.CpuSteal = cpu.Steal
statistics.CpuCount = cpu.CPUCount
loadAvg, err := loadavg.Get()
if err != nil {
LogError("failed to collect loadavg statistics", err)
return statistics, err
}
statistics.LoadAVG1 = loadAvg.Loadavg1
statistics.LoadAVG5 = loadAvg.Loadavg5
statistics.LoadAVG15 = loadAvg.Loadavg15
return statistics, nil
}