Added other stats and json serialization
This commit is contained in:
46
main.go
46
main.go
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -20,11 +21,37 @@ var (
|
|||||||
// TODO: bench test with pointer
|
// TODO: bench test with pointer
|
||||||
func getMetrics() (Metric, error) {
|
func getMetrics() (Metric, error) {
|
||||||
log.Println("Started getMetrics")
|
log.Println("Started getMetrics")
|
||||||
var s = Stat{}
|
|
||||||
m := Metric{}
|
m := Metric{}
|
||||||
cpustats := s.CPUStats()
|
err := m.getMemory()
|
||||||
m.Load1m = cpustats.LoadMin1
|
if err != nil {
|
||||||
log.Printf("Metric: %v\n", m)
|
log.Printf("Cannot get memory: %s\n", err)
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.getLoadAvg()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Cannot get load average: %s\n", err)
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.getCpuMetric()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Cannot get CPU metrics: %s\n", err)
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.getDiskMetrics()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Cannot get disk metrics: %s\n", err)
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.getNetworkMetrics()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Cannot get network metrics: %s\n", err)
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,8 +158,19 @@ func (t *Test) stopTest(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Test) testStatus(w http.ResponseWriter, req *http.Request) {
|
func (t *Test) testStatus(w http.ResponseWriter, req *http.Request) {
|
||||||
|
qFormat := req.URL.Query().Get("format")
|
||||||
|
if qFormat == "json" {
|
||||||
|
b, err := json.Marshal(t.Result)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Cannot marshal json: %s\n", err)
|
||||||
|
http.Error(w, err.Error(), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "%s\n", b)
|
||||||
|
} else {
|
||||||
fmt.Fprintf(w, "%v\n", t.Result)
|
fmt.Fprintf(w, "%v\n", t.Result)
|
||||||
fmt.Fprintf(w, "Test %s, status: %s\n", t.Name, t.Status)
|
fmt.Fprintf(w, "Test %s, status: %s\n", t.Name, t.Status)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTest() *Test {
|
func newTest() *Test {
|
||||||
|
|||||||
125
stats.go
125
stats.go
@@ -1,43 +1,100 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
// #cgo LDFLAGS: -lstatgrab
|
import (
|
||||||
// #include <statgrab.h>
|
"log"
|
||||||
import "C"
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
var mainfunc = make(chan func())
|
"github.com/mackerelio/go-osstat/cpu"
|
||||||
|
"github.com/mackerelio/go-osstat/disk"
|
||||||
|
"github.com/mackerelio/go-osstat/loadavg"
|
||||||
|
"github.com/mackerelio/go-osstat/memory"
|
||||||
|
"github.com/mackerelio/go-osstat/network"
|
||||||
|
)
|
||||||
|
|
||||||
func do(f func()) {
|
func (m *Metric) getMemory() error {
|
||||||
done := make(chan bool, 1)
|
memory, err := memory.Get()
|
||||||
mainfunc <- func() {
|
if err != nil {
|
||||||
f()
|
log.Printf("Cannot get memory: %s\n", err)
|
||||||
done <- true
|
return err
|
||||||
}
|
}
|
||||||
<-done
|
m.MemMetrics.FreeMem = memory.Free
|
||||||
|
m.MemMetrics.TotalMem = memory.Total
|
||||||
|
m.MemMetrics.UsedMem = memory.Used
|
||||||
|
m.MemMetrics.BuffersMem = memory.Buffers
|
||||||
|
m.MemMetrics.CachedMem = memory.Cached
|
||||||
|
m.MemMetrics.AvailableMem = memory.Available
|
||||||
|
m.MemMetrics.ActiveMem = memory.Active
|
||||||
|
m.MemMetrics.InactiveMem = memory.Inactive
|
||||||
|
m.MemMetrics.SwapTotal = memory.SwapTotal
|
||||||
|
m.MemMetrics.SwapUsed = memory.SwapUsed
|
||||||
|
m.MemMetrics.SwapCached = memory.SwapCached
|
||||||
|
m.MemMetrics.SwapFree = memory.SwapFree
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stat) CPUStats() *CPUStats {
|
func (m *Metric) getLoadAvg() error {
|
||||||
s.Lock()
|
loadAvg, err := loadavg.Get()
|
||||||
defer s.Unlock()
|
if err != nil {
|
||||||
|
log.Printf("Cannot get loadAvg(): %s\n", err)
|
||||||
var cpu *CPUStats
|
return err
|
||||||
|
|
||||||
do(func() {
|
|
||||||
cpup := C.sg_get_cpu_percents_of(C.sg_new_diff_cpu_percent, nil)
|
|
||||||
loadStat := C.sg_get_load_stats(nil)
|
|
||||||
cpu = &CPUStats{
|
|
||||||
User: float64(cpup.user),
|
|
||||||
Kernel: float64(cpup.kernel),
|
|
||||||
Idle: float64(cpup.idle),
|
|
||||||
IOWait: float64(cpup.iowait),
|
|
||||||
Swap: float64(cpup.swap),
|
|
||||||
Nice: float64(cpup.nice),
|
|
||||||
LoadMin1: float64(loadStat.min1),
|
|
||||||
LoadMin5: float64(loadStat.min5),
|
|
||||||
LoadMin15: float64(loadStat.min15),
|
|
||||||
Period: time.Duration(int(cpup.time_taken)) * time.Second,
|
|
||||||
TimeTaken: time.Now(),
|
|
||||||
}
|
}
|
||||||
})
|
m.LoadMetrics.Load1m = loadAvg.Loadavg1
|
||||||
return cpu
|
m.LoadMetrics.Load5m = loadAvg.Loadavg5
|
||||||
|
m.LoadMetrics.Load15m = loadAvg.Loadavg15
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Metric) getCpuMetric() error {
|
||||||
|
cpu, err := cpu.Get()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Cannot get cpu(): %s\n", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.CPUMetrics.User = cpu.User
|
||||||
|
m.CPUMetrics.Nice = cpu.Nice
|
||||||
|
m.CPUMetrics.System = cpu.System
|
||||||
|
m.CPUMetrics.Idle = cpu.Idle
|
||||||
|
m.CPUMetrics.Iowait = cpu.Iowait
|
||||||
|
m.CPUMetrics.Irq = cpu.Irq
|
||||||
|
m.CPUMetrics.Softirq = cpu.Softirq
|
||||||
|
m.CPUMetrics.Steal = cpu.Steal
|
||||||
|
m.CPUMetrics.Guest = cpu.Guest
|
||||||
|
m.CPUMetrics.GuestNice = cpu.GuestNice
|
||||||
|
m.CPUMetrics.Total = cpu.Total
|
||||||
|
m.CPUMetrics.CPUCount = cpu.CPUCount
|
||||||
|
m.CPUMetrics.StatCount = cpu.StatCount
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Metric) getDiskMetrics() error {
|
||||||
|
disk, err := disk.Get()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Cannot get disk(): %s\n", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, _ := range disk {
|
||||||
|
tmpM := DiskMetric{
|
||||||
|
Name: disk[i].Name,
|
||||||
|
WritesCompleted: disk[i].WritesCompleted,
|
||||||
|
ReadsCompleted: disk[i].ReadsCompleted,
|
||||||
|
}
|
||||||
|
m.DiskMetrics = append(m.DiskMetrics, tmpM)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Metric) getNetworkMetrics() error {
|
||||||
|
network, err := network.Get()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Cannot get network(): %s\n", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, _ := range network {
|
||||||
|
tmpM := NetworkMetric{
|
||||||
|
Name: network[i].Name,
|
||||||
|
TxBytes: network[i].TxBytes,
|
||||||
|
RxBytes: network[i].RxBytes,
|
||||||
|
}
|
||||||
|
m.NetworkMetrics = append(m.NetworkMetrics, tmpM)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
77
struct.go
77
struct.go
@@ -16,29 +16,60 @@ type Test struct {
|
|||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LoadMetric struct {
|
||||||
|
Load1m float64 `json:"load1m"`
|
||||||
|
Load5m float64 `json:"load5m"`
|
||||||
|
Load15m float64 `json:"load15m"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MemMetric struct {
|
||||||
|
FreeMem uint64 `json:"freemem"`
|
||||||
|
TotalMem uint64 `json:"totalmem"`
|
||||||
|
UsedMem uint64 `json:"usedmem"`
|
||||||
|
BuffersMem uint64 `json:"buffersmem"`
|
||||||
|
CachedMem uint64 `json:"cachedmem"`
|
||||||
|
AvailableMem uint64 `json:"availablemem"`
|
||||||
|
ActiveMem uint64 `json:"activemem"`
|
||||||
|
InactiveMem uint64 `json:"inactivemem"`
|
||||||
|
SwapTotal uint64 `json:"swaptotal"`
|
||||||
|
SwapUsed uint64 `json:"swapused"`
|
||||||
|
SwapCached uint64 `json:"swapcached"`
|
||||||
|
SwapFree uint64 `json:"swapfree"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CpuMetric struct {
|
||||||
|
User uint64 `json:"user"`
|
||||||
|
Nice uint64 `json:"nice"`
|
||||||
|
System uint64 `json:"system"`
|
||||||
|
Idle uint64 `json:"idle"`
|
||||||
|
Iowait uint64 `json:"iowait"`
|
||||||
|
Irq uint64 `json:"irq"`
|
||||||
|
Softirq uint64 `json:"softirq"`
|
||||||
|
Steal uint64 `json:"steal"`
|
||||||
|
Guest uint64 `json:"guest"`
|
||||||
|
GuestNice uint64 `json:"guestnice"`
|
||||||
|
Total uint64 `json:"total"`
|
||||||
|
CPUCount int `json:"cpucount"`
|
||||||
|
StatCount int `json:"statcount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiskMetric struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
WritesCompleted uint64 `json:"writes_completed"`
|
||||||
|
ReadsCompleted uint64 `json:"reads_completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetworkMetric struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
RxBytes uint64 `json:"rx_bytes"`
|
||||||
|
TxBytes uint64 `json:"tx_bytes"`
|
||||||
|
}
|
||||||
|
|
||||||
type Metric struct {
|
type Metric struct {
|
||||||
|
LoadMetrics LoadMetric `json:"load_metrics"`
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
Load1m float64
|
MemMetrics MemMetric `json:"mem_metrics"`
|
||||||
Load5m float64
|
CPUMetrics CpuMetric `json:"cpu_metrics"`
|
||||||
Load15m float64
|
DiskMetrics []DiskMetric `json:"disk_metrics"`
|
||||||
FreeMem int
|
NetworkMetrics []NetworkMetric `json:"network_metrics"`
|
||||||
}
|
|
||||||
|
|
||||||
type CPUStats struct {
|
|
||||||
User float64
|
|
||||||
Kernel float64
|
|
||||||
Idle float64
|
|
||||||
IOWait float64
|
|
||||||
Swap float64
|
|
||||||
Nice float64
|
|
||||||
LoadMin1 float64
|
|
||||||
LoadMin5 float64
|
|
||||||
LoadMin15 float64
|
|
||||||
Period time.Duration
|
|
||||||
TimeTaken time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type Stat struct {
|
|
||||||
sync.Mutex
|
|
||||||
exitMessage chan bool
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user