Skip to content

Commit

Permalink
use shirou/gopsutil for machine sampling
Browse files Browse the repository at this point in the history
  • Loading branch information
cvilsmeier committed Jan 7, 2025
1 parent 7cec98d commit 0a7b4dd
Show file tree
Hide file tree
Showing 11 changed files with 406 additions and 836 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/go-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: go-linux

on: [push]

jobs:

build:
runs-on: windows-latest

strategy:
matrix:
go-version: ['1.21', '1.22', '1.23']

steps:
- uses: actions/checkout@v4

- name: setup go ${{matrix.go-version}}
uses: actions/setup-go@v5
with:
go-version: ${{matrix.go-version}}
cache: false

- name: go version
run: go version

- name: go test
run: go test ./...

- name: go build
run: CGO_ENABLED=0 go build .
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Moni is a command-line tool to interact with the Monibot REST API. It is used to
- Query metrics from Monibot
- Send metric values to Monibot

It is written in [Go](https://go.dev/) and runs on Linux/amd64.
It is written in [Go](https://go.dev/) and runs on Linux/amd64 and Windows/amd64.

## Download

Expand Down Expand Up @@ -166,6 +166,7 @@ Exit Codes
### v0.3.0

- remove watchdog, machine and metric command
- use shirou/gopsutil for machine sampling (to support windows)

### v0.2.2

Expand Down
9 changes: 9 additions & 0 deletions check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

set -e
stat go.mod > /dev/null # must be in src dir

git status
go test ./... -count 1
staticcheck ./...
echo "check ok"
6 changes: 6 additions & 0 deletions clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

set -e
stat go.mod > /dev/null # must be in src dir

rm -rf _dist
16 changes: 16 additions & 0 deletions dist.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh

set -e
stat go.mod > /dev/null # must be in src dir

rm -rf _dist
mkdir -p _dist/linux _dist/windows

echo "go build"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o _dist/linux .
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o _dist/windows .

echo "tar"
tar -czf _dist/linux/moni-linux-amd64.tar.gz README.md -C _dist/linux moni
tar -czf _dist/windows/moni-windows-amd64.tar.gz README.md -C _dist/windows moni.exe

20 changes: 19 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,22 @@ module github.com/cvilsmeier/moni

go 1.21

require github.com/cvilsmeier/monibot-go v0.1.1
require (
github.com/cvilsmeier/monibot-go v0.1.1
github.com/shirou/gopsutil/v4 v4.24.12
github.com/stretchr/testify v1.10.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ebitengine/purego v0.8.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/sys v0.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
42 changes: 36 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
github.com/cvilsmeier/monibot-go v0.1.0 h1:KCRwEJsLHr0X6D7iZZKhVwRHUcjhT19vYHhvW/L2xTc=
github.com/cvilsmeier/monibot-go v0.1.0/go.mod h1:NBtP4dmXJTmL6i3GNXQyqpX8tOr1O+HPLnc6hEXFprs=
github.com/cvilsmeier/monibot-go v0.1.1-0.20240106193739-2524e4b72865 h1:R7AmKiVzyjRBAbkzZ5Rlkz2KsQ+/dqQv7M54iFjrQu8=
github.com/cvilsmeier/monibot-go v0.1.1-0.20240106193739-2524e4b72865/go.mod h1:NBtP4dmXJTmL6i3GNXQyqpX8tOr1O+HPLnc6hEXFprs=
github.com/cvilsmeier/monibot-go v0.1.1-0.20240106195016-372c30a7176a h1:U5LZSTKQgwKgXO0CgBY8S1psLRUOqV0qmIeK4WmxB7o=
github.com/cvilsmeier/monibot-go v0.1.1-0.20240106195016-372c30a7176a/go.mod h1:NBtP4dmXJTmL6i3GNXQyqpX8tOr1O+HPLnc6hEXFprs=
github.com/cvilsmeier/monibot-go v0.1.1 h1:HQuTlycndLktv+3fzicaIyRIV6HUjK/EBDzCUwLZ59w=
github.com/cvilsmeier/monibot-go v0.1.1/go.mod h1:NBtP4dmXJTmL6i3GNXQyqpX8tOr1O+HPLnc6hEXFprs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ebitengine/purego v0.8.1 h1:sdRKd6plj7KYW33EH5As6YKfe8m9zbN9JMrOjNVF/BE=
github.com/ebitengine/purego v0.8.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/shirou/gopsutil/v4 v4.24.12 h1:qvePBOk20e0IKA1QXrIIU+jmk+zEiYVVx06WjBRlZo4=
github.com/shirou/gopsutil/v4 v4.24.12/go.mod h1:DCtMPAad2XceTeIAbGyVfycbYQNBGk2P8cvDi7/VN9o=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
6 changes: 3 additions & 3 deletions moni.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ func main() {
log.Printf("WARNING: interval %s is below min, force-changing it to %s", fmtDuration(interval), fmtDuration(minHeartbeatInterval))
interval = minHeartbeatInterval
}
log.Printf("will send heartbeats in background every %s", fmtDuration(interval))
log.Printf("INFO: will send heartbeats in background every %s", fmtDuration(interval))
}
err := api.PostWatchdogHeartbeat(watchdogId)
if err != nil {
Expand Down Expand Up @@ -337,14 +337,14 @@ func main() {
log.Printf("WARNING: interval %s is below min, force-changing it to %s", fmtDuration(interval), fmtDuration(minSampleInterval))
interval = minSampleInterval
}
sampler := NewSampler()
sampler := NewSampler(Platform{})
// we must warm up the sampler first
_, err = sampler.Sample()
if err != nil {
fatal(1, "cannot sample: %s", err)
}
// entering sampling loop
log.Printf("will send samples in background every %s", fmtDuration(interval))
log.Printf("INFO: will send samples in background every %s", fmtDuration(interval))
for {
// sleep
time.Sleep(interval)
Expand Down
95 changes: 95 additions & 0 deletions platform.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package main

import (
"fmt"
"time"

"github.com/shirou/gopsutil/v4/cpu"
"github.com/shirou/gopsutil/v4/disk"
"github.com/shirou/gopsutil/v4/load"
"github.com/shirou/gopsutil/v4/mem"
"github.com/shirou/gopsutil/v4/net"
)

type Platform struct{}

func (p Platform) UnixMilli() int64 {
return time.Now().UnixMilli()
}

func (p Platform) CpuPercent() (float64, error) {
percents, err := cpu.Percent(0, false)
if err != nil {
return 0, fmt.Errorf("cannot cpu.Percent(): %w", err)
}
if len(percents) == 0 {
return 0, fmt.Errorf("cpu.Percent(): empty result")
}
return percents[0], err
}

func (p Platform) MemPercent() (float64, error) {
vm, err := mem.VirtualMemory()
if err != nil {
return 0, fmt.Errorf("cannot mem.VirtualMemory(): %w", err)
}
return vm.UsedPercent, nil
}

func (p Platform) DiskPercent() (float64, error) {
partitions, err := disk.Partitions(false)
if err != nil {
return 0, fmt.Errorf("cannot disk.Partitions(): %w", err)
}
var total uint64
var used uint64
for _, p := range partitions {
usage, err := disk.Usage(p.Mountpoint)
if err != nil {
return 0, fmt.Errorf("cannot disk.Usage(%q): %w", p.Mountpoint, err)
}
total += usage.Total
used += usage.Used
}
return float64(used) * 100.0 / float64(total), nil
}

func (p Platform) Load() ([3]float64, error) {
avg, err := load.Avg()
if err != nil {
return [3]float64{0, 0, 0}, fmt.Errorf("cannot load.Avg(): %w", err)
}
return [3]float64{avg.Load1, avg.Load5, avg.Load15}, nil
}

func (p Platform) DiskBytes() (uint64, uint64, error) {
parts, err := disk.Partitions(false)
if err != nil {
return 0, 0, fmt.Errorf("cannot disk.Partitions(): %w", err)
}
var readBytes, writeBytes uint64
for _, p := range parts {
iocMap, err := disk.IOCounters(p.Device)
if err != nil {
return 0, 0, fmt.Errorf("cannot disk.IOCounters(%q): %w", p.Device, err)
}
for _, ioc := range iocMap {
readBytes += ioc.ReadBytes
writeBytes += ioc.WriteBytes
}
}
return readBytes, writeBytes, nil
}

func (p Platform) NetBytes() (uint64, uint64, error) {
iocs, err := net.IOCounters(false)
if err != nil {
return 0, 0, fmt.Errorf("cannot net.IOCounters(): %w", err)
}
var recvBytes, sendBytes uint64
for _, ioc := range iocs {
recvBytes += ioc.BytesRecv
sendBytes += ioc.BytesSent
}
return recvBytes, sendBytes, nil
}
Loading

0 comments on commit 0a7b4dd

Please sign in to comment.