summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean E. Russell <ser@ser1.net>2020-02-27 18:51:28 -0600
committerSean E. Russell <ser@ser1.net>2020-02-28 07:06:51 -0600
commit7a89225d729d4c54c5bc95b21979f48f9cd046b1 (patch)
tree10bf143324cf553765d7002d0eb82abc21c72bb1
parent4fce1654c5c263797205997e7635c7d06c393a85 (diff)
Abstracts CPU & mem devices.
Finishes device refactoring: temps Refactoring to allow updating maps. Simpler, and optimizable.
-rw-r--r--devices/cpu.go50
-rw-r--r--devices/cpu_cpu.go25
-rw-r--r--devices/include/smc.c (renamed from widgets/include/smc.c)0
-rw-r--r--devices/include/smc.h (renamed from widgets/include/smc.h)0
-rw-r--r--devices/mem.go26
-rw-r--r--devices/mem_mem.go21
-rw-r--r--devices/mem_swap_freebsd.go44
-rw-r--r--devices/mem_swap_other.go23
-rw-r--r--devices/temp.go22
-rw-r--r--devices/temp_darwin.go (renamed from widgets/temp_darwin.go)40
-rw-r--r--devices/temp_freebsd.go45
-rw-r--r--devices/temp_linux.go (renamed from widgets/temp_linux.go)21
-rw-r--r--devices/temp_openbsd.go (renamed from widgets/temp_openbsd.go)66
-rw-r--r--devices/temp_windows.go24
-rw-r--r--go.mod11
-rw-r--r--go.sum124
-rw-r--r--layout/layout.go7
-rwxr-xr-xmake.sh1
-rw-r--r--widgets/cpu.go110
-rw-r--r--widgets/mem.go105
-rw-r--r--widgets/mem_freebsd.go67
-rw-r--r--widgets/mem_other.go25
-rw-r--r--widgets/temp.go13
-rw-r--r--widgets/temp_freebsd.go124
-rw-r--r--widgets/temp_windows.go29
25 files changed, 406 insertions, 617 deletions
diff --git a/devices/cpu.go b/devices/cpu.go
index b35bdd3..21d21b6 100644
--- a/devices/cpu.go
+++ b/devices/cpu.go
@@ -1,44 +1,34 @@
package devices
import (
+ "log"
"time"
)
-var deviceCounts []func(bool) (int, error)
-var devicePercents []func(time.Duration, bool) ([]float64, error)
-var numDevices int
+var cpuFuncs []func(map[string]float64, time.Duration, bool) map[string]error
-// Counts returns the number of CPUs registered.
+// RegisterCPU adds a new CPU device to the CPU widget. labels returns the
+// names of the devices; they should be as short as possible, and the indexes
+// of the returned slice should align with the values returned by the percents
+// function. The percents function should return the percent CPU usage of the
+// device(s), sliced over the time duration supplied. If the bool argument to
+// percents is true, it is expected that the return slice
//
-// logical tells Counts to count the logical cores; this may be ignored for
-// some devices.
-func Counts(logical bool) (int, error) {
- var rv int
- var re error
- for _, d := range deviceCounts {
- r, err := d(logical)
- if err != nil {
- return rv, re
- }
- rv += r
- }
- return rv, re
+// labels may be called once and the value cached. This means the number of
+// cores should not change dynamically.
+func RegisterCPU(f func(map[string]float64, time.Duration, bool) map[string]error) {
+ cpuFuncs = append(cpuFuncs, f)
}
-// Percent calculates the percentage of cpu used either per CPU or combined.
+// CPUPercent calculates the percentage of cpu used either per CPU or combined.
// Returns one value per cpu, or a single value if percpu is set to false.
-func Percent(interval time.Duration, combined bool) ([]float64, error) {
- var rvs []float64
- rvs = make([]float64, 0, numDevices)
- for _, f := range devicePercents {
- vs, err := f(interval, combined)
- if err != nil {
- return rvs, err
- }
- for _, v := range vs {
- rvs = append(rvs, v)
+func UpdateCPU(cpus map[string]float64, interval time.Duration, logical bool) {
+ for _, f := range cpuFuncs {
+ errs := f(cpus, interval, logical)
+ if errs != nil {
+ for k, e := range errs {
+ log.Printf("%s: %s", k, e)
+ }
}
}
- numDevices = len(rvs)
- return rvs, nil
}
diff --git a/devices/cpu_cpu.go b/devices/cpu_cpu.go
index f5e6956..e18b51d 100644
--- a/devices/cpu_cpu.go
+++ b/devices/cpu_cpu.go
@@ -1,10 +1,31 @@
package devices
import (
+ "fmt"
+ "time"
+
psCpu "github.com/shirou/gopsutil/cpu"
)
func init() {
- deviceCounts = append(deviceCounts, psCpu.Counts)
- devicePercents = append(devicePercents, psCpu.Percent)
+ f := func(cpus map[string]float64, iv time.Duration, l bool) map[string]error {
+ cpuCount, err := psCpu.Counts(l)
+ if err != nil {
+ return nil
+ }
+ formatString := "CPU%1d"
+ if cpuCount > 10 {
+ formatString = "CPU%02d"
+ }
+ vals, err := psCpu.Percent(iv, l)
+ if err != nil {
+ return map[string]error{"gopsutil": err}
+ }
+ for i := 0; i < len(vals); i++ {
+ key := fmt.Sprintf(formatString, i)
+ cpus[key] = vals[i]
+ }
+ return nil
+ }
+ RegisterCPU(f)
}
diff --git a/widgets/include/smc.c b/devices/include/smc.c
index 0c200d6..0c200d6 100644
--- a/widgets/include/smc.c
+++ b/devices/include/smc.c
diff --git a/widgets/include/smc.h b/devices/include/smc.h
index d837e11..d837e11 100644
--- a/widgets/include/smc.h
+++ b/devices/include/smc.h
diff --git a/devices/mem.go b/devices/mem.go
new file mode 100644
index 0000000..defb01f
--- /dev/null
+++ b/devices/mem.go
@@ -0,0 +1,26 @@
+package devices
+
+import "log"
+
+var memFuncs []func(map[string]MemoryInfo) map[string]error
+
+type MemoryInfo struct {
+ Total uint64
+ Used uint64
+ UsedPercent float64
+}
+
+func RegisterMem(f func(map[string]MemoryInfo) map[string]error) {
+ memFuncs = append(memFuncs, f)
+}
+
+func UpdateMem(mem map[string]MemoryInfo) {
+ for _, f := range memFuncs {
+ errs := f(mem)
+ if errs != nil {
+ for k, e := range errs {
+ log.Printf("%s: %s", k, e)
+ }
+ }
+ }
+}
diff --git a/devices/mem_mem.go b/devices/mem_mem.go
new file mode 100644
index 0000000..53e5721
--- /dev/null
+++ b/devices/mem_mem.go
@@ -0,0 +1,21 @@
+package devices
+
+import (
+ psMem "github.com/shirou/gopsutil/mem"
+)
+
+func init() {
+ mf := func(mems map[string]MemoryInfo) map[string]error {
+ mainMemory, err := psMem.VirtualMemory()
+ if err != nil {
+ return map[string]error{"Main": err}
+ }
+ mems["Main"] = MemoryInfo{
+ Total: mainMemory.Total,
+ Used: mainMemory.Used,
+ UsedPercent: mainMemory.UsedPercent,
+ }
+ return nil
+ }
+ RegisterMem(mf)
+}
diff --git a/devices/mem_swap_freebsd.go b/devices/mem_swap_freebsd.go
new file mode 100644
index 0000000..3a95aa9
--- /dev/null
+++ b/devices/mem_swap_freebsd.go
@@ -0,0 +1,44 @@
+// +build freebsd
+
+package devices
+
+import (
+ "os/exec"
+ "strconv"
+ "strings"
+)
+
+func init() {
+ mf := func(mems map[string]MemoryInfo) map[string]error {
+ cmd := "swapinfo -k|sed -n '1!p'|awk '{print $2,$3,$5}'"
+ output, err := exec.Command("sh", "-c", cmd).Output()
+ if err != nil {
+ return map[string]error{"swapinfo": err}
+ }
+
+ s := strings.TrimSuffix(string(output), "\n")
+ s = strings.ReplaceAll(s, "\n", " ")
+ ss := strings.Split(s, " ")
+ ss = ss[((len(ss)/3)-1)*3:]
+
+ errors := make(map[string]error)
+ mem := MemoryInfo{}
+ mem.Total, err = strconv.ParseUint(ss[0], 10, 64)
+ if err != nil {
+ errors["swap total"] = err
+ }
+
+ mem.Used, err = strconv.ParseUint(ss[1], 10, 64)
+ if err != nil {
+ errors["swap used"] = err
+ }
+
+ mem.UsedPercent, err = strconv.ParseFloat(strings.TrimSuffix(ss[2], "%"), 64)
+ if err != nil {
+ errors["swap percent"] = err
+ }
+ mems["Swap"] = mem
+ return errors
+ }
+ RegisterMem(mf)
+}
diff --git a/devices/mem_swap_other.go b/devices/mem_swap_other.go
new file mode 100644
index 0000000..fb16705
--- /dev/null
+++ b/devices/mem_swap_other.go
@@ -0,0 +1,23 @@
+// +build !freebsd
+
+package devices
+
+import (
+ psMem "github.com/shirou/gopsutil/mem"
+)
+
+func init() {
+ mf := func(mems map[string]MemoryInfo) map[string]error {
+ memory, err := psMem.SwapMemory()
+ if err != nil {
+ return map[string]error{"Swap": err}
+ }
+ mems["Swap"] = MemoryInfo{
+ Total: memory.Total,
+ Used: memory.Used,
+ UsedPercent: memory.UsedPercent,
+ }
+ return nil
+ }
+ RegisterMem(mf)
+}
diff --git a/devices/temp.go b/devices/temp.go
new file mode 100644
index 0000000..010e7ad
--- /dev/null
+++ b/devices/temp.go
@@ -0,0 +1,22 @@
+package devices
+
+import (
+ "log"
+)
+
+var tempUpdates []func(map[string]int) map[string]error
+
+func RegisterTemp(update func(map[string]int) map[string]error) {
+ tempUpdates = append(tempUpdates, update)
+}
+
+func UpdateTemps(temps map[string]int) {
+ for _, f := range tempUpdates {
+ errs := f(temps)
+ if errs != nil {
+ for k, e := range errs {
+ log.Printf("error updating temp for %s: %s", k, e)
+ }
+ }
+ }
+}
diff --git a/widgets/temp_darwin.go b/devices/temp_darwin.go
index d0e512b..e60b4be 100644
--- a/widgets/temp_darwin.go
+++ b/devices/temp_darwin.go
@@ -1,22 +1,16 @@
// +build darwin
-package widgets
+package devices
// #cgo LDFLAGS: -framework IOKit
// #include "include/smc.c"
import "C"
-import (
- "log"
- "github.com/xxxserxxx/gotop/utils"
-)
-
-type TemperatureStat struct {
- SensorKey string `json:"sensorKey"`
- Temperature float64 `json:"sensorTemperature"`
+func init() {
+ RegisterTemp(update)
}
-func SensorsTemperatures() ([]TemperatureStat, error) {
+func update(temps map[string]int) map[string]error {
temperatureKeys := map[string]string{
C.AMBIENT_AIR_0: "ambient_air_0",
C.AMBIENT_AIR_1: "ambient_air_1",
@@ -41,34 +35,12 @@ func SensorsTemperatures() ([]TemperatureStat, error) {
C.WIRELESS_MODULE: "wireless_module",
}
- var temperatures []TemperatureStat
-
C.open_smc()
defer C.close_smc()
for key, val := range temperatureKeys {
- temperatures = append(temperatures, TemperatureStat{
- SensorKey: val,
- Temperature: float64(C.get_tmp(C.CString(key), C.CELSIUS)),
- })
+ temps[val] = int(C.get_tmp(C.CString(key), C.CELSIUS))
}
- return temperatures, nil
-}
-func (self *TempWidget) update() {
- sensors, err := SensorsTemperatures()
- if err != nil {
- log.Printf("failed to get sensors from CGO: %v", err)
- return
- }
- for _, sensor := range sensors {
- if sensor.Temperature != 0 {
- switch self.TempScale {
- case Fahrenheit:
- self.Data[sensor.SensorKey] = utils.CelsiusToFahrenheit(int(sensor.Temperature))
- case Celsius:
- self.Data[sensor.SensorKey] = int(sensor.Temperature)
- }
- }
- }
+ return nil
}
diff --git a/devices/temp_freebsd.go b/devices/temp_freebsd.go
new file mode 100644
index 0000000..ba47474
--- /dev/null
+++ b/devices/temp_freebsd.go
@@ -0,0 +1,45 @@
+// +build freebsd
+
+package devices
+
+import (
+ "os/exec"
+ "strconv"
+ "strings"
+
+ "github.com/xxxserxxx/gotop/utils"
+)
+
+func init() {
+ RegisterTemp(update)
+}
+
+var sensorOIDS = map[string]string{
+ "dev.cpu.0.temperature": "CPU 0 ",
+ "hw.acpi.thermal.tz0.temperature": "Thermal zone 0",
+}
+
+func update(temps map[string]int) map[string]error {
+ var errors map[string]error
+
+ for k, v := range sensorOIDS {
+ output, err := exec.Command("sysctl", "-n", k).Output()
+ if err != nil {
+ errors[v] = err
+ continue
+ }
+
+ s1 := strings.Replace(string(output), "C", "", 1)
+ s2 := strings.TrimSuffix(s1, "\n")
+ convertedOutput := utils.ConvertLocalizedString(s2)
+ value, err := strconv.ParseFloat(convertedOutput, 64)
+ if err != nil {
+ errors[v] = err
+ continue
+ }
+
+ temps[v] = int(value)
+ }
+
+ return errors
+}
diff --git a/widgets/temp_linux.go b/devices/temp_linux.go
index 1460007..ec4ff95 100644
--- a/widgets/temp_linux.go
+++ b/devices/temp_linux.go
@@ -1,32 +1,29 @@
// +build linux
-package widgets
+package devices
import (
- "log"
"strings"
psHost "github.com/shirou/gopsutil/host"
-
- "github.com/xxxserxxx/gotop/utils"
)
-func (self *TempWidget) update() {
+func init() {
+ RegisterTemp(getTemps)
+}
+
+func getTemps(temps map[string]int) map[string]error {
sensors, err := psHost.SensorsTemperatures()
if err != nil {
- log.Printf("error received from gopsutil: %v", err)
+ return map[string]error{"psHost": err}
}
for _, sensor := range sensors {
// only sensors with input in their name are giving us live temp info
if strings.Contains(sensor.SensorKey, "input") && sensor.Temperature != 0 {
// removes '_input' from the end of the sensor name
label := sensor.SensorKey[:strings.Index(sensor.SensorKey, "_input")]
- switch self.TempScale {
- case Fahrenheit:
- self.Data[label] = utils.CelsiusToFahrenheit(int(sensor.Temperature))
- case Celsius:
- self.Data[label] = int(sensor.Temperature)
- }
+ temps[label] = int(sensor.Temperature)
}
}
+ return nil
}
diff --git a/widgets/temp_openbsd.go b/devices/temp_openbsd.go
index 0d4a24a..410cc4a 100644
--- a/widgets/temp_openbsd.go
+++ b/devices/temp_openbsd.go
@@ -1,6 +1,6 @@
// +build openbsd
-package widgets
+package devices
// loosely based on https://github.com/openbsd/src/blob/master/sbin/sysctl/sysctl.c#L2517
@@ -13,42 +13,13 @@ import (
"strconv"
"syscall"
"unsafe"
-
- "github.com/xxxserxxx/gotop/utils"
)
-func (self *TempWidget) getTemp(mib []C.int, mlen int, snsrdev *C.struct_sensordev, index int) {
- switch mlen {
- case 4:
- k := mib[3]
- var numt C.int
- for numt = 0; numt < snsrdev.maxnumt[k]; numt++ {
- mib[4] = numt
- self.getTemp(mib, mlen+1, snsrdev, int(numt))
- }
- case 5:
- var snsr C.struct_sensor
- var slen C.size_t = C.sizeof_struct_sensor
-
- if v, _ := C.sysctl(&mib[0], 5, unsafe.Pointer(&snsr), &slen, nil, 0); v == -1 {
- return
- }
-
- if slen > 0 && (snsr.flags&C.SENSOR_FINVALID) == 0 {
- key := C.GoString(&snsrdev.xname[0]) + ".temp" + strconv.Itoa(index)
- temp := int((snsr.value - 273150000.0) / 1000000.0)
-
- switch self.TempScale {
- case Fahrenheit:
- self.Data[key] = utils.CelsiusToFahrenheit(temp)
- case Celsius:
- self.Data[key] = temp
- }
- }
- }
+func init() {
+ RegisterTemp(update)
}
-func (self *TempWidget) update() {
+func update(temps map[string]int) map[string]error {
mib := []C.int{0, 1, 2, 3, 4}
var snsrdev C.struct_sensordev
@@ -69,6 +40,33 @@ func (self *TempWidget) update() {
break
}
}
- self.getTemp(mib, 4, &snsrdev, 0)
+ getTemp(temps, mib, 4, &snsrdev, 0)
+ }
+ return nil
+}
+
+func getTemp(temps map[string]int, mib []C.int, mlen int, snsrdev *C.struct_sensordev, index int) {
+ switch mlen {
+ case 4:
+ k := mib[3]
+ var numt C.int
+ for numt = 0; numt < snsrdev.maxnumt[k]; numt++ {
+ mib[4] = numt
+ getTemp(temps, mib, mlen+1, snsrdev, int(numt))
+ }
+ case 5:
+ var snsr C.struct_sensor
+ var slen C.size_t = C.sizeof_struct_sensor
+
+ if v, _ := C.sysctl(&mib[0], 5, unsafe.Pointer(&snsr), &slen, nil, 0); v == -1 {
+ return
+ }
+
+ if slen > 0 && (snsr.flags&C.SENSOR_FINVALID) == 0 {
+ key := C.GoString(&snsrdev.xname[0]) + ".temp" + strconv.Itoa(index)
+ temp := int((snsr.value - 273150000.0) / 1000000.0)
+
+ temps[key] = temp
+ }
}
}
diff --git a/devices/temp_windows.go b/devices/temp_windows.go
new file mode 100644
index 0000000..230e902
--- /dev/null
+++ b/devices/temp_windows.go
@@ -0,0 +1,24 @@
+// +build windows
+
+package devices
+
+import (
+ psHost "github.com/shirou/gopsutil/host"
+)
+
+func init() {
+ RegisterTemp(update)
+}
+
+func update(temps map[string]int) map[string]error {
+ sensors, err := psHost.SensorsTemperatures()
+ if err != nil {
+ return map[string]error{"gopsutil": err}
+ }
+ for _, sensor := range sensors {
+ if sensor.Temperature != 0 {
+ temps[sensor.SensorKey] = int(sensor.Temperature)
+ }
+ }
+ return nil
+}
diff --git a/go.mod b/go.mod
index 01d66ea..6058002 100644
--- a/go.mod
+++ b/go.mod
@@ -1,27 +1,18 @@
module github.com/xxxserxxx/gotop
require (
- github.com/GeertJohan/go.rice v1.0.0 // indirect
- github.com/NVIDIA/gpu-monitoring-tools v0.0.0-20200116003318-021662a21098
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/distatus/battery v0.9.0
github.com/docopt/docopt.go v0.0.0-20180111231733-ee0de3bc6815
- github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
github.com/gizak/termui/v3 v3.0.0
github.com/go-ole/go-ole v1.2.1 // indirect
- github.com/k0kubun/pp v3.0.1+incompatible // indirect
- github.com/mailru/easyjson v0.7.1 // indirect
github.com/mattn/go-runewidth v0.0.4
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/prometheus/client_golang v1.4.1
- github.com/rai-project/config v0.0.0-20190926180509-3bd01e698aad // indirect
- github.com/rai-project/logger v0.0.0-20190701163301-49978a80bf96 // indirect
- github.com/rai-project/nvidia-smi v0.0.0-20190730061239-864eb441c9ae
- github.com/rai-project/tegra v0.0.0-20181119122707-1d9901ca382b // indirect
github.com/shirou/gopsutil v2.18.11+incompatible
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
github.com/stretchr/testify v1.4.0
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
)
-go 1.12
+go 1.13
diff --git a/go.sum b/go.sum
index dea0dac..3cf7498 100644
--- a/go.sum
+++ b/go.sum
@@ -1,19 +1,9 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/GeertJohan/go-sourcepath v0.0.0-20150925135350-83e8b8723a9b/go.mod h1:X/dh6iyBHZUR+NSNoO9isIl7cRw4n09jwjK5tfr+Rno=
-github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
-github.com/GeertJohan/go.rice v0.0.0-20170420135705-c02ca9a983da/go.mod h1:DgrzXonpdQbfN3uYaGz1EG4Sbhyum/MMIn6Cphlh2bw=
-github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
-github.com/NVIDIA/gpu-monitoring-tools v0.0.0-20200116003318-021662a21098 h1:9qTpKR5TnUxu+ViqhxkpANee27meaoHYwV0f1SnRqgI=
-github.com/NVIDIA/gpu-monitoring-tools v0.0.0-20200116003318-021662a21098/go.mod h1:nMOvShGpWaf0bXwXmeu4k+O4uziuaEI8pWzIj3BUrOA=
+github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
-github.com/Unknwon/com v0.0.0-20151008135407-28b053d5a292/go.mod h1:KYCjqMOeHpNuTOiFQU6WEcTG7poCJrUs0YgyHNtn1no=
-github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -22,106 +12,63 @@ github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd h1:XtfPmj9tQRilnrEmI1HjQhxXWRhEM+m8CACtaMJE/kM=
github.com/cjbassi/drawille-go v0.0.0-20190126131713-27dc511fe6fd/go.mod h1:vjcQJUZJYD3MeVGhtZXSMnCHfUNZxsyYzJt90eCYxK4=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
-github.com/coreos/etcd v3.3.8+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/daaku/go.zipexe v0.0.0-20150329023125-a5fe2436ffcb/go.mod h1:U0vRfAucUOohvdCxt5MWLF+TePIL0xbCkbKIiV8TQCE=
-github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/distatus/battery v0.9.0 h1:8NS5o00/j3Oh2xgocA6pQROTp5guoR+s8CZlWzHC4QM=
github.com/distatus/battery v0.9.0/go.mod h1:gGO7GxHTi1zlRT+cAj8uGG0/8HFiqAeH0TJvoipnuPs=
github.com/docopt/docopt.go v0.0.0-20180111231733-ee0de3bc6815 h1:HMAfwOa33y82IaQEKQDfUCiwNlxtM1iw7HLM9ru0RNc=
github.com/docopt/docopt.go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:l7JNRynTRuqe45tpIyItHNqZWTxywYjp87MWTOnU5cg=
-github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
-github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gizak/termui/v3 v3.0.0 h1:NYTUG6ig/sJK05O5FyhWemwlVPO8ilNpvS/PgRtrKAE=
github.com/gizak/termui/v3 v3.0.0/go.mod h1:uinu2dMdtMI+FTIdEFUJQT5y+KShnhQRshvPblXq3lY=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
-github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
-github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
-github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
-github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
-github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/mitchellh/go-homedir v0.0.0-20180523094522-3864e76763d9/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
-github.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.1 h1:FFSuS004yOQEtDdTq+TAOLP5xUq63KqAFYyOi8zA+Y8=
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
@@ -129,98 +76,53 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
-github.com/rai-project/config v0.0.0-20190926180509-3bd01e698aad/go.mod h1:NGYIJHnNhNRYvFYWqSCbPqsnwJ6uLC4q2eddpInHgVk=
-github.com/rai-project/godotenv v0.0.0-20180619160704-a501614c3b8d/go.mod h1:91keR8FKb9xXErPghO6kMay+2MQb4g+gIZey/W/vv8w=
-github.com/rai-project/logger v0.0.0-20190701163301-49978a80bf96/go.mod h1:aFDuHWECvho4yTAOeAgPjuLIeGiYrURMS16V//PDmi8=
-github.com/ra