1
0
Fork 0
cpu_ctrl/producer/os_darwin.go

328 lines
8.5 KiB
Go

package producer
import (
"github.com/mackerelio/go-osstat/memory"
"github.com/mackerelio/go-osstat/loadavg"
"github.com/mackerelio/go-osstat/network"
"github.com/mackerelio/go-osstat/uptime"
"github.com/mackerelio/go-osstat/cpu"
"github.com/hako/durafmt"
"amuz.es/src/infra/goutils/misc"
"time"
"go.uber.org/multierr"
"sync"
"runtime"
)
type NetIOInfo struct {
Name string `json:"name"`
RxKBytes int64 `json:"rx_kbytes"`
TxKBytes int64 `json:"tx_kbytes"`
}
type MemoryInfo struct {
Total int64 `json:"total_kbytes"`
Active int64 `json:"active_kbytes"`
Cached int64 `json:"cached_kbytes"`
Free int64 `json:"free_kbytes"`
Inactive int64 `json:"inactive_kbytes"`
SwapFree int64 `json:"swap_free_kbytes"`
SwapTotal int64 `json:"swap_total_kbytes"`
SwapUsed int64 `json:"swap_used_kbytes"`
Used int64 `json:"used_kbytes"`
}
type LoadInfo struct {
Avg1 float64 `json:"avg_1"`
Avg5 float64 `json:"avg_5"`
Avg15 float64 `json:"avg_15"`
}
type CPUInfo struct {
Idle float64 `json:"idle"`
Nice float64 `json:"nice"`
System float64 `json:"system"`
User float64 `json:"user"`
}
type OSMetricInfo struct {
Memory MemoryInfo `json:"memory"`
Load LoadInfo `json:"load"`
NetIO map[string]NetIOInfo `json:"net_io"`
Uptime time.Duration `json:"uptime"`
CPU CPUInfo `json:"cpu"`
Host string `json:"host"`
At time.Time `json:"at"`
}
func (p *OSMetricInfo) MarshalUptime() (name string, tags []map[string]string, fields []map[string]interface{}) {
name, tags, fields =
"uptime",
[]map[string]string{
{
"os": runtime.GOOS,
},
},
[]map[string]interface{}{
{
"duration": p.Uptime,
},
}
return
}
func (p *OSMetricInfo) MarshalLoad() (name string, tags []map[string]string, fields []map[string]interface{}) {
name, tags, fields =
"load",
[]map[string]string{
{
"os": runtime.GOOS,
},
},
[]map[string]interface{}{
{
"avg_1": p.Load.Avg1,
"avg_5": p.Load.Avg5,
"avg_15": p.Load.Avg15,
},
}
return
}
func (p *OSMetricInfo) MarshalCPU() (name string, tags []map[string]string, fields []map[string]interface{}) {
name, tags, fields =
"cpu",
[]map[string]string{
{
"os": runtime.GOOS,
},
},
[]map[string]interface{}{
{
"idle": p.CPU.Idle,
"nice": p.CPU.Nice,
"system": p.CPU.System,
"user": p.CPU.User,
},
}
return
}
func (p *OSMetricInfo) MarshalNetworks() (name string, tags []map[string]string, fields []map[string]interface{}) {
name = "network"
tags = make([]map[string]string, 0)
fields = make([]map[string]interface{}, 0)
for name, info := range p.NetIO {
tags, fields =
append(tags, map[string]string{
"os": runtime.GOOS,
"name": name,
}),
append(fields, map[string]interface{}{
"rx_kbytes": info.RxKBytes,
"tx_kbytes": info.TxKBytes,
})
}
return
}
func (p *OSMetricInfo) MarshalMemory() (name string, tags []map[string]string, fields []map[string]interface{}) {
name, tags, fields =
"memory",
[]map[string]string{
{
"os": runtime.GOOS,
},
},
[]map[string]interface{}{
{
"total_kbytes": p.Memory.Total,
"active_kbytes": p.Memory.Active,
"cached_kbytes": p.Memory.Cached,
"free_kbytes": p.Memory.Free,
"inactive_kbytes": p.Memory.Inactive,
"swap_free_kbytes": p.Memory.SwapFree,
"swap_total_kbytes": p.Memory.SwapTotal,
"swap_used_kbytes": p.Memory.SwapUsed,
"used_kbytes": p.Memory.Used,
},
}
return
}
func (p *OSMetricInfo) Applier() (generator []OSMetricPointGen) {
generator = append(
generator,
p.MarshalLoad,
p.MarshalCPU,
p.MarshalMemory,
p.MarshalNetworks,
p.MarshalUptime,
)
return
}
func (p *osMetric) readMemoryStat(info *OSMetricInfo, errChan chan<- error, waiter *sync.WaitGroup) {
memoryInfo, err := memory.Get()
defer func() {
defer waiter.Done()
if panicErr := recover(); panicErr != nil {
err = multierr.Append(err, panicErr.(error))
}
if err != nil {
p.logger.Error("unable to retrieve readMemoryStat: ", err)
errChan <- err
}
}()
if err != nil {
return
}
p.logger.Debug("memory total: ", misc.FileSizeIEC(memoryInfo.Total))
p.logger.Debug("memory active: ", misc.FileSizeIEC(memoryInfo.Active))
p.logger.Debug("memory cached: ", misc.FileSizeIEC(memoryInfo.Cached))
p.logger.Debug("memory free: ", misc.FileSizeIEC(memoryInfo.Free))
p.logger.Debug("memory inactive: ", misc.FileSizeIEC(memoryInfo.Inactive))
p.logger.Debug("memory swapFree: ", misc.FileSizeIEC(memoryInfo.SwapFree))
p.logger.Debug("memory swapTotal: ", misc.FileSizeIEC(memoryInfo.SwapTotal))
p.logger.Debug("memory swapUsed: ", misc.FileSizeIEC(memoryInfo.SwapUsed))
p.logger.Debug("memory used: ", misc.FileSizeIEC(memoryInfo.Used))
info.Memory.Total = int64(memoryInfo.Total>>10)
info.Memory.Active = int64(memoryInfo.Active>>10)
info.Memory.Cached = int64(memoryInfo.Cached>>10)
info.Memory.Free = int64(memoryInfo.Free>>10)
info.Memory.Inactive = int64(memoryInfo.Inactive>>10)
info.Memory.SwapFree = int64(memoryInfo.SwapFree>>10)
info.Memory.SwapTotal = int64(memoryInfo.SwapTotal>>10)
info.Memory.SwapUsed = int64(memoryInfo.SwapUsed>>10)
info.Memory.Used = int64(memoryInfo.Used>>10)
return
}
func (p *osMetric) readLoadStat(info *OSMetricInfo, errChan chan<- error, waiter *sync.WaitGroup) {
load, err := loadavg.Get()
defer func() {
defer waiter.Done()
if panicErr := recover(); panicErr != nil {
err = multierr.Append(err, panicErr.(error))
}
if err != nil {
p.logger.Error("unable to retrieve readLoadStat: ", err)
errChan <- err
}
}()
if err != nil {
return
}
p.logger.Debugf("load Loadavg1: %f", load.Loadavg1)
p.logger.Debugf("load Loadavg5: %f", load.Loadavg5)
p.logger.Debugf("load Loadavg15: %f", load.Loadavg15)
info.Load.Avg1 = load.Loadavg1
info.Load.Avg5 = load.Loadavg5
info.Load.Avg15 = load.Loadavg15
return
}
func (p *osMetric) readNetworkStat(info *OSMetricInfo, errChan chan<- error, waiter *sync.WaitGroup) {
netios, err := network.Get()
defer func() {
defer waiter.Done()
if panicErr := recover(); panicErr != nil {
err = multierr.Append(err, panicErr.(error))
}
if err != nil {
p.logger.Error("unable to retrieve readNetworkStat: ", err)
errChan <- err
}
}()
if err != nil {
return
}
netIoMap := make(map[string]NetIOInfo)
for _, netio := range netios {
p.logger.Debug("netio name: ", netio.Name)
p.logger.Debug("netio rxBytes: ", misc.FileSizeIEC(netio.RxBytes))
p.logger.Debug("netio txBytes: ", misc.FileSizeIEC(netio.TxBytes))
netIoMap[netio.Name] = NetIOInfo{
Name: netio.Name,
RxKBytes: int64(netio.RxBytes>>10),
TxKBytes: int64(netio.TxBytes>>10),
}
}
info.NetIO = netIoMap
return
}
func (p *osMetric) readUptimeStat(info *OSMetricInfo, errChan chan<- error, waiter *sync.WaitGroup) {
ut, err := uptime.Get()
defer func() {
defer waiter.Done()
if panicErr := recover(); panicErr != nil {
err = multierr.Append(err, panicErr.(error))
}
if err != nil {
p.logger.Error("unable to retrieve readUptimeStat: ", err)
errChan <- err
}
}()
if err != nil {
return
}
p.logger.Debugf("readUptimeStat: %s", durafmt.Parse(ut).String())
info.Uptime = ut
return
}
func (p *osMetric) readCpuStat(info *OSMetricInfo, errChan chan<- error, waiter *sync.WaitGroup) {
ct, err := cpu.Get()
defer func() {
defer waiter.Done()
if panicErr := recover(); panicErr != nil {
err = multierr.Append(err, panicErr.(error))
}
if err != nil {
p.logger.Error("unable to retrieve readCpuStat: ", err)
errChan <- err
}
}()
if err != nil {
return
}
p.logger.Debugf("readCpuStat: idle=%d", ct.Idle)
p.logger.Debugf("readCpuStat: nice=%d", ct.Nice)
p.logger.Debugf("readCpuStat: system=%d", ct.System)
p.logger.Debugf("readCpuStat: total=%d", ct.Total)
p.logger.Debugf("readCpuStat: user=%d", ct.User)
p.logger.Debugf("readCpuStat: idle=%f%%", float64(ct.Idle*100)/float64(ct.Total))
p.logger.Debugf("readCpuStat: nice=%f%%", float64(ct.Nice*100)/float64(ct.Total))
p.logger.Debugf("readCpuStat: system=%f%%", float64(ct.System*100)/float64(ct.Total))
p.logger.Debugf("readCpuStat: user=%f%%", float64(ct.User*100)/float64(ct.Total))
info.CPU.Idle = float64(ct.Idle*100) / float64(ct.Total)
info.CPU.Nice = float64(ct.Nice*100) / float64(ct.Total)
info.CPU.System = float64(ct.System*100) / float64(ct.Total)
info.CPU.User = float64(ct.User*100) / float64(ct.Total)
return
}
func (p *osMetric) availableMetrics() (appliers []osMetricApplier) {
appliers = append(appliers,
p.readLoadStat,
p.readMemoryStat,
p.readCpuStat,
p.readNetworkStat,
p.readUptimeStat,
)
return
}