rename variables for clarity

This commit is contained in:
Henry Dollman
2024-09-27 14:56:53 -04:00
parent 82e3f3c7c1
commit 56c0b86025
2 changed files with 64 additions and 63 deletions

View File

@@ -30,12 +30,12 @@ type Agent struct {
addr string // Adress that the ssh server listens on addr string // Adress that the ssh server listens on
pubKey []byte // Public key for ssh server pubKey []byte // Public key for ssh server
sem chan struct{} // Semaphore to limit concurrent access to docker api sem chan struct{} // Semaphore to limit concurrent access to docker api
containerStatsMap map[string]*container.PrevContainerStats // Keeps track of container stats
containerStatsMutex *sync.Mutex // Mutex to prevent concurrent access to containerStatsMap
fsNames []string // List of filesystem device names being monitored fsNames []string // List of filesystem device names being monitored
fsStats map[string]*system.FsStats // Keeps track of disk stats for each filesystem fsStats map[string]*system.FsStats // Keeps track of disk stats for each filesystem
netInterfaces map[string]struct{} // Stores all valid network interfaces netInterfaces map[string]struct{} // Stores all valid network interfaces
netIoStats *system.NetIoStats // Keeps track of bandwidth usage netIoStats *system.NetIoStats // Keeps track of bandwidth usage
prevContainerStatsMap map[string]*container.PrevContainerStats // Keeps track of container stats
prevContainerStatsMutex *sync.Mutex // Mutex to prevent concurrent access to prevContainerStatsMap
dockerClient *http.Client // HTTP client to query docker api dockerClient *http.Client // HTTP client to query docker api
sensorsContext context.Context // Sensors context to override sys location sensorsContext context.Context // Sensors context to override sys location
debug bool // true if LOG_LEVEL is set to debug debug bool // true if LOG_LEVEL is set to debug
@@ -46,8 +46,8 @@ func NewAgent(pubKey []byte, addr string) *Agent {
addr: addr, addr: addr,
pubKey: pubKey, pubKey: pubKey,
sem: make(chan struct{}, 15), sem: make(chan struct{}, 15),
containerStatsMap: make(map[string]*container.PrevContainerStats), prevContainerStatsMap: make(map[string]*container.PrevContainerStats),
containerStatsMutex: &sync.Mutex{}, prevContainerStatsMutex: &sync.Mutex{},
netIoStats: &system.NetIoStats{}, netIoStats: &system.NetIoStats{},
dockerClient: newDockerClient(), dockerClient: newDockerClient(),
sensorsContext: context.Background(), sensorsContext: context.Background(),
@@ -223,21 +223,22 @@ func (a *Agent) getDockerStats() ([]container.Stats, error) {
} }
defer resp.Body.Close() defer resp.Body.Close()
var containers []container.ApiInfo // docker host container list response
if err := json.NewDecoder(resp.Body).Decode(&containers); err != nil { var res []container.ApiInfo
if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
slog.Error("Error decoding containers", "err", err) slog.Error("Error decoding containers", "err", err)
return nil, err return nil, err
} }
containerStats := make([]container.Stats, 0, len(containers)) containerStats := make([]container.Stats, 0, len(res))
containerStatsMutex := sync.Mutex{} containerStatsMutex := sync.Mutex{}
// store valid ids to clean up old container ids from map // store valid ids to clean up old container ids from map
validIds := make(map[string]struct{}, len(containers)) validIds := make(map[string]struct{}, len(res))
var wg sync.WaitGroup var wg sync.WaitGroup
for _, ctr := range containers { for _, ctr := range res {
ctr.IdShort = ctr.Id[:12] ctr.IdShort = ctr.Id[:12]
validIds[ctr.IdShort] = struct{}{} validIds[ctr.IdShort] = struct{}{}
// check if container is less than 1 minute old (possible restart) // check if container is less than 1 minute old (possible restart)
@@ -275,9 +276,9 @@ func (a *Agent) getDockerStats() ([]container.Stats, error) {
wg.Wait() wg.Wait()
// remove old / invalid container stats // remove old / invalid container stats
for id := range a.containerStatsMap { for id := range a.prevContainerStatsMap {
if _, exists := validIds[id]; !exists { if _, exists := validIds[id]; !exists {
delete(a.containerStatsMap, id) delete(a.prevContainerStatsMap, id)
} }
} }
@@ -285,77 +286,77 @@ func (a *Agent) getDockerStats() ([]container.Stats, error) {
} }
func (a *Agent) getContainerStats(ctr container.ApiInfo) (container.Stats, error) { func (a *Agent) getContainerStats(ctr container.ApiInfo) (container.Stats, error) {
cStats := container.Stats{} curStats := container.Stats{}
resp, err := a.dockerClient.Get("http://localhost/containers/" + ctr.IdShort + "/stats?stream=0&one-shot=1") resp, err := a.dockerClient.Get("http://localhost/containers/" + ctr.IdShort + "/stats?stream=0&one-shot=1")
if err != nil { if err != nil {
return cStats, err return curStats, err
} }
defer resp.Body.Close() defer resp.Body.Close()
// decode the json data from the response body // docker host container stats response
var statsJson container.ApiStats var res container.ApiStats
if err := json.NewDecoder(resp.Body).Decode(&statsJson); err != nil { if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
return cStats, err return curStats, err
} }
name := ctr.Names[0][1:] name := ctr.Names[0][1:]
// check if container has valid data, otherwise may be in restart loop (#103) // check if container has valid data, otherwise may be in restart loop (#103)
if statsJson.MemoryStats.Usage == 0 { if res.MemoryStats.Usage == 0 {
return cStats, fmt.Errorf("%s - no memory stats - see https://github.com/henrygd/beszel/issues/144", name) return curStats, fmt.Errorf("%s - no memory stats - see https://github.com/henrygd/beszel/issues/144", name)
} }
// memory (https://docs.docker.com/reference/cli/docker/container/stats/) // memory (https://docs.docker.com/reference/cli/docker/container/stats/)
memCache := statsJson.MemoryStats.Stats["inactive_file"] memCache := res.MemoryStats.Stats["inactive_file"]
if memCache == 0 { if memCache == 0 {
memCache = statsJson.MemoryStats.Stats["cache"] memCache = res.MemoryStats.Stats["cache"]
} }
usedMemory := statsJson.MemoryStats.Usage - memCache usedMemory := res.MemoryStats.Usage - memCache
a.containerStatsMutex.Lock() a.prevContainerStatsMutex.Lock()
defer a.containerStatsMutex.Unlock() defer a.prevContainerStatsMutex.Unlock()
// add empty values if they doesn't exist in map // add empty values if they doesn't exist in map
stats, initialized := a.containerStatsMap[ctr.IdShort] prevStats, initialized := a.prevContainerStatsMap[ctr.IdShort]
if !initialized { if !initialized {
stats = &container.PrevContainerStats{} prevStats = &container.PrevContainerStats{}
a.containerStatsMap[ctr.IdShort] = stats a.prevContainerStatsMap[ctr.IdShort] = prevStats
} }
// cpu // cpu
cpuDelta := statsJson.CPUStats.CPUUsage.TotalUsage - stats.Cpu[0] cpuDelta := res.CPUStats.CPUUsage.TotalUsage - prevStats.Cpu[0]
systemDelta := statsJson.CPUStats.SystemUsage - stats.Cpu[1] systemDelta := res.CPUStats.SystemUsage - prevStats.Cpu[1]
cpuPct := float64(cpuDelta) / float64(systemDelta) * 100 cpuPct := float64(cpuDelta) / float64(systemDelta) * 100
if cpuPct > 100 { if cpuPct > 100 {
return cStats, fmt.Errorf("%s cpu pct greater than 100: %+v", name, cpuPct) return curStats, fmt.Errorf("%s cpu pct greater than 100: %+v", name, cpuPct)
} }
stats.Cpu = [2]uint64{statsJson.CPUStats.CPUUsage.TotalUsage, statsJson.CPUStats.SystemUsage} prevStats.Cpu = [2]uint64{res.CPUStats.CPUUsage.TotalUsage, res.CPUStats.SystemUsage}
// network // network
var total_sent, total_recv uint64 var total_sent, total_recv uint64
for _, v := range statsJson.Networks { for _, v := range res.Networks {
total_sent += v.TxBytes total_sent += v.TxBytes
total_recv += v.RxBytes total_recv += v.RxBytes
} }
var sent_delta, recv_delta float64 var sent_delta, recv_delta float64
// prevent first run from sending all prev sent/recv bytes // prevent first run from sending all prev sent/recv bytes
if initialized { if initialized {
secondsElapsed := time.Since(stats.Net.Time).Seconds() secondsElapsed := time.Since(prevStats.Net.Time).Seconds()
sent_delta = float64(total_sent-stats.Net.Sent) / secondsElapsed sent_delta = float64(total_sent-prevStats.Net.Sent) / secondsElapsed
recv_delta = float64(total_recv-stats.Net.Recv) / secondsElapsed recv_delta = float64(total_recv-prevStats.Net.Recv) / secondsElapsed
} }
stats.Net.Sent = total_sent prevStats.Net.Sent = total_sent
stats.Net.Recv = total_recv prevStats.Net.Recv = total_recv
stats.Net.Time = time.Now() prevStats.Net.Time = time.Now()
cStats.Name = name curStats.Name = name
cStats.Cpu = twoDecimals(cpuPct) curStats.Cpu = twoDecimals(cpuPct)
cStats.Mem = bytesToMegabytes(float64(usedMemory)) curStats.Mem = bytesToMegabytes(float64(usedMemory))
cStats.NetworkSent = bytesToMegabytes(sent_delta) curStats.NetworkSent = bytesToMegabytes(sent_delta)
cStats.NetworkRecv = bytesToMegabytes(recv_delta) curStats.NetworkRecv = bytesToMegabytes(recv_delta)
return cStats, nil return curStats, nil
} }
func (a *Agent) gatherStats() system.CombinedData { func (a *Agent) gatherStats() system.CombinedData {

View File

@@ -12,9 +12,9 @@ func (a *Agent) releaseSemaphore() {
// delete container stats from map using mutex // delete container stats from map using mutex
func (a *Agent) deleteContainerStatsSync(id string) { func (a *Agent) deleteContainerStatsSync(id string) {
a.containerStatsMutex.Lock() a.prevContainerStatsMutex.Lock()
defer a.containerStatsMutex.Unlock() defer a.prevContainerStatsMutex.Unlock()
delete(a.containerStatsMap, id) delete(a.prevContainerStatsMap, id)
} }
func bytesToMegabytes(b float64) float64 { func bytesToMegabytes(b float64) float64 {