categraf/inputs/system/system.go

135 lines
2.9 KiB
Go

package system
import (
"fmt"
"log"
"os"
"strings"
"time"
"flashcat.cloud/categraf/config"
"flashcat.cloud/categraf/inputs"
"flashcat.cloud/categraf/types"
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/host"
"github.com/shirou/gopsutil/v3/load"
)
const InputName = "system"
type SystemStats struct {
PrintConfigs bool
IntervalSeconds int64
Labels map[string]string
quit chan struct{}
CollectUserNumber bool
}
func init() {
inputs.Add(InputName, func() inputs.Input {
return &SystemStats{}
})
}
func (s *SystemStats) getInterval() time.Duration {
if s.IntervalSeconds != 0 {
return time.Duration(s.IntervalSeconds) * time.Second
}
return config.GetInterval()
}
// overwrite func
func (s *SystemStats) TidyConfig() error {
return nil
}
// overwrite func
func (s *SystemStats) StopGoroutines() {
s.quit <- struct{}{}
}
// overwrite func
func (s *SystemStats) StartGoroutines(queue chan *types.Sample) {
go s.LoopGather(queue)
}
func (s *SystemStats) LoopGather(queue chan *types.Sample) {
interval := s.getInterval()
for {
select {
case <-s.quit:
close(s.quit)
return
default:
time.Sleep(interval)
defer func() {
if r := recover(); r != nil {
if strings.Contains(fmt.Sprint(r), "closed channel") {
return
} else {
log.Println("E! gather metrics panic:", r)
}
}
}()
s.Gather(queue)
}
}
}
// overwrite func
func (s *SystemStats) Gather(queue chan *types.Sample) {
var samples []*types.Sample
defer func() {
now := time.Now()
for i := 0; i < len(samples); i++ {
samples[i].Timestamp = now
samples[i].Metric = InputName + "_" + samples[i].Metric
queue <- samples[i]
}
}()
loadavg, err := load.Avg()
if err != nil && !strings.Contains(err.Error(), "not implemented") {
log.Println("E! failed to gather system load:", err)
return
}
numCPUs, err := cpu.Counts(true)
if err != nil {
log.Println("E! failed to gather cpu number:", err)
return
}
samples = append(samples,
inputs.NewSample("load1", loadavg.Load1),
inputs.NewSample("load5", loadavg.Load5),
inputs.NewSample("load15", loadavg.Load15),
inputs.NewSample("n_cpus", float64(numCPUs)),
inputs.NewSample("load_norm_1", loadavg.Load1/float64(numCPUs)),
inputs.NewSample("load_norm_5", loadavg.Load5/float64(numCPUs)),
inputs.NewSample("load_norm_15", loadavg.Load15/float64(numCPUs)),
)
uptime, err := host.Uptime()
if err != nil {
log.Println("E! failed to get host uptime:", err)
return
}
samples = append(samples, inputs.NewSample("uptime", float64(uptime)))
if s.CollectUserNumber {
users, err := host.Users()
if err == nil {
samples = append(samples, inputs.NewSample("n_users", float64(len(users))))
} else if os.IsNotExist(err) {
log.Println("W! reading os users:", err)
} else if os.IsPermission(err) {
log.Println("W! reading os users:", err)
}
}
}