diff --git a/cmd/kvmprofiler/main.go b/cmd/kvmprofiler/main.go index 5f3d7d0..421edfb 100644 --- a/cmd/kvmprofiler/main.go +++ b/cmd/kvmprofiler/main.go @@ -7,7 +7,6 @@ import ( "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/connector" - "github.com/cha87de/kvmtop/models" "github.com/cha87de/kvmtop/profiler" "github.com/cha87de/kvmtop/runners" ) @@ -25,11 +24,6 @@ func main() { os.Exit(1) } - // initialize host measureable - models.Collection.Host = &models.Host{ - Measurable: &models.Measurable{}, - } - // start lookup and collect runners var wg sync.WaitGroup wg.Add(1) // terminate when first thread terminates diff --git a/cmd/kvmtop/main.go b/cmd/kvmtop/main.go index 1a1aaea..2799887 100644 --- a/cmd/kvmtop/main.go +++ b/cmd/kvmtop/main.go @@ -49,11 +49,6 @@ func main() { os.Exit(1) } - // initialize host measureable - models.Collection.Host = &models.Host{ - Measurable: &models.Measurable{}, - } - // start runners runners.InitializeRunners() diff --git a/collectors/collectors.go b/collectors/collectors.go deleted file mode 100644 index 05a4d99..0000000 --- a/collectors/collectors.go +++ /dev/null @@ -1,87 +0,0 @@ -package collectors - -import ( - "bytes" - "encoding/gob" - "fmt" - - "github.com/cha87de/kvmtop/models" -) - -func GetMetricUint64(measurable *models.Measurable, metric string, measurementIndex int) string { - var output string - if metric, ok := measurable.GetMetric(metric); ok { - if len(metric.Values) > measurementIndex { - byteValue := metric.Values[measurementIndex].Value - reader := bytes.NewReader(byteValue) - decoder := gob.NewDecoder(reader) - var valuetype uint64 - decoder.Decode(&valuetype) - output = fmt.Sprintf("%d", valuetype) - } - } - return output -} - -func GetMetricFloat64(measurable *models.Measurable, metric string, measurementIndex int) string { - var output string - if metric, ok := measurable.GetMetric(metric); ok { - if len(metric.Values) > measurementIndex { - byteValue := metric.Values[measurementIndex].Value - reader := bytes.NewReader(byteValue) - decoder := gob.NewDecoder(reader) - var valuetype float64 - decoder.Decode(&valuetype) - output = fmt.Sprintf("%f", valuetype) - } - } - return output -} - -func GetMetricString(measurable *models.Measurable, metric string, measurementIndex int) string { - var output string - if metric, ok := measurable.GetMetric(metric); ok { - if len(metric.Values) > measurementIndex { - byteValue := metric.Values[measurementIndex].Value - reader := bytes.NewReader(byteValue) - decoder := gob.NewDecoder(reader) - var valuetype string - decoder.Decode(&valuetype) - output = fmt.Sprintf("%s", valuetype) - } - } - return output -} - -func GetMetricDiffUint64(measurable *models.Measurable, metric string, perTime bool) string { - var output string - if metric, ok := measurable.GetMetric(metric); ok { - if len(metric.Values) >= 2 { - // get first value - byteValue1 := metric.Values[0].Value - reader1 := bytes.NewReader(byteValue1) - decoder1 := gob.NewDecoder(reader1) - var value1 uint64 - decoder1.Decode(&value1) - - // get second value - byteValue2 := metric.Values[1].Value - reader2 := bytes.NewReader(byteValue2) - decoder2 := gob.NewDecoder(reader2) - var value2 uint64 - decoder2.Decode(&value2) - - // calculate value diff per time - value := float64(value1 - value2) - - // get time diff - if perTime { - timeDiff := metric.Values[0].Timestamp.Sub(metric.Values[1].Timestamp).Seconds() - value = value / timeDiff - } - - output = fmt.Sprintf("%.0f", value) - } - } - return output -} diff --git a/collectors/cpucollector/collector.go b/collectors/cpucollector/collector.go index cb4274d..2a54dd3 100644 --- a/collectors/cpucollector/collector.go +++ b/collectors/cpucollector/collector.go @@ -12,7 +12,7 @@ type Collector struct { // Lookup cpu collector data func (collector *Collector) Lookup() { - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) libvirtDomain, _ := models.Collection.LibvirtDomains.Load(uuid) @@ -21,13 +21,13 @@ func (collector *Collector) Lookup() { }) // lookup details for host - cpuLookupHost(models.Collection.Host) + cpuLookupHost(&models.Collection.Host) } // Collect cpu collector data func (collector *Collector) Collect() { // lookup for each domain - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { // uuid := key.(string) domain := value.(models.Domain) cpuCollect(&domain) @@ -35,7 +35,7 @@ func (collector *Collector) Collect() { }) // collect host measurements - cpuCollectHost(models.Collection.Host) + cpuCollectHost(&models.Collection.Host) } // Print returns the collectors measurements in a Printable struct @@ -68,7 +68,7 @@ func (collector *Collector) Print() models.Printable { // lookup for each domain printable.DomainValues = make(map[string][]string) - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) printable.DomainValues[uuid] = cpuPrint(&domain) @@ -76,7 +76,7 @@ func (collector *Collector) Print() models.Printable { }) // lookup for host - printable.HostValues = cpuPrintHost(models.Collection.Host) + printable.HostValues = cpuPrintHost(&models.Collection.Host) return printable } diff --git a/collectors/cpucollector/host.go b/collectors/cpucollector/host.go index 60efc88..19ab99a 100644 --- a/collectors/cpucollector/host.go +++ b/collectors/cpucollector/host.go @@ -1,7 +1,6 @@ package cpucollector import ( - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" @@ -39,10 +38,10 @@ func cpuCollectHost(host *models.Host) { } func cpuPrintHost(host *models.Host) []string { - cpuMinfreq := collectors.GetMetricFloat64(host.Measurable, "cpu_minfreq", 0) - cpuMaxfreq := collectors.GetMetricFloat64(host.Measurable, "cpu_maxfreq", 0) - cpuCurfreq := collectors.GetMetricFloat64(host.Measurable, "cpu_curfreq", 0) - cpuCores := collectors.GetMetricUint64(host.Measurable, "cpu_cores", 0) + cpuMinfreq := host.GetMetricFloat64("cpu_minfreq", 0) + cpuMaxfreq := host.GetMetricFloat64("cpu_maxfreq", 0) + cpuCurfreq := host.GetMetricFloat64("cpu_curfreq", 0) + cpuCores, _ := host.GetMetricUint64("cpu_cores", 0) // put results together result := append([]string{cpuCores}, cpuCurfreq) diff --git a/collectors/cpucollector/worker.go b/collectors/cpucollector/worker.go index 5d6080d..7bfc0d9 100644 --- a/collectors/cpucollector/worker.go +++ b/collectors/cpucollector/worker.go @@ -8,7 +8,6 @@ import ( "fmt" - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" "github.com/cha87de/kvmtop/util" @@ -104,7 +103,7 @@ func cpuCollectMeasurements(domain *models.Domain, metricName string, measuremen } func cpuPrint(domain *models.Domain) []string { - cores := collectors.GetMetricUint64(domain.Measurable, "cpu_cores", 0) + cores, _ := domain.GetMetricUint64("cpu_cores", 0) // cpu util for vcores cputimeAllCores := CpuPrintThreadMetric(domain, "cpu_threadIDs", "cpu_times") @@ -128,7 +127,7 @@ func CpuPrintThreadMetric(domain *models.Domain, lookupMetric string, metric str var measurementCount int for _, threadID := range threadIDs { metricName := fmt.Sprint(metric, "_", threadID) - measurementStr := collectors.GetMetricDiffUint64(domain.Measurable, metricName, true) + measurementStr := domain.GetMetricDiffUint64(metricName, true) if measurementStr == "" { continue } diff --git a/collectors/diskcollector/collector.go b/collectors/diskcollector/collector.go index 9fe6622..2ee3f4c 100644 --- a/collectors/diskcollector/collector.go +++ b/collectors/diskcollector/collector.go @@ -3,7 +3,6 @@ package diskcollector import ( "strings" - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" ) @@ -17,14 +16,14 @@ type Collector struct { func (collector *Collector) Lookup() { hostDiskSources := "" - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) libvirtDomain, _ := models.Collection.LibvirtDomains.Load(uuid) diskLookup(&domain, libvirtDomain) // merge sourcedir metrics from domains to one metric for host - disksources := strings.Split(collectors.GetMetricString(domain.Measurable, "disk_sources", 0), ",") + disksources := strings.Split(domain.GetMetricString("disk_sources", 0), ",") for _, disksource := range disksources { if !strings.Contains(hostDiskSources, disksource) { if hostDiskSources != "" { @@ -39,19 +38,19 @@ func (collector *Collector) Lookup() { models.Collection.Host.AddMetricMeasurement("disk_sources", models.CreateMeasurement(hostDiskSources)) - diskHostLookup(models.Collection.Host) + diskHostLookup(&models.Collection.Host) } // Collect disk collector data func (collector *Collector) Collect() { // lookup for each domain - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { // uuid := key.(string) domain := value.(models.Domain) diskCollect(&domain) return true }) - diskHostCollect(models.Collection.Host) + diskHostCollect(&models.Collection.Host) } // Print returns the collectors measurements in a Printable struct @@ -96,7 +95,7 @@ func (collector *Collector) Print() models.Printable { // lookup for each domain printable.DomainValues = make(map[string][]string) - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) printable.DomainValues[uuid] = diskPrint(&domain) @@ -104,7 +103,7 @@ func (collector *Collector) Print() models.Printable { }) // lookup for host - printable.HostValues = diskPrintHost(models.Collection.Host) + printable.HostValues = diskPrintHost(&models.Collection.Host) return printable } diff --git a/collectors/diskcollector/host-worker.go b/collectors/diskcollector/host-worker.go index 433e4af..f6b1a8f 100644 --- a/collectors/diskcollector/host-worker.go +++ b/collectors/diskcollector/host-worker.go @@ -1,7 +1,6 @@ package diskcollector import ( - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/util" @@ -14,7 +13,7 @@ func diskHostLookup(host *models.Host) { // find relevant devices devices := []string{} mounts := util.GetProcMounts() - diskSources := strings.Split(collectors.GetMetricString(host.Measurable, "disk_sources", 0), ",") + diskSources := strings.Split(host.GetMetricString("disk_sources", 0), ",") for _, source := range diskSources { // find best matching mountpoint var bestMount util.ProcMount @@ -99,17 +98,17 @@ func diskHostCollect(host *models.Host) { } func diskPrintHost(host *models.Host) []string { - diskDeviceReads := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_reads", true) - diskDeviceReadsmerged := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_readsmerged", true) - diskDeviceSectorsread := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_sectorsread", true) - diskDeviceTimereading := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_timereading", true) - diskDeviceWrites := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_writes", true) - diskDeviceWritesmerged := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_writesmerged", true) - diskDeviceSectorswritten := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_sectorswritten", true) - diskDeviceTimewriting := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_timewriting", true) - diskDeviceCurrentops := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_currentops", true) - diskDeviceTimeforops := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_timeforops", true) - diskDeviceWeightedtimeforops := collectors.GetMetricDiffUint64(host.Measurable, "disk_device_weightedtimeforops", true) + diskDeviceReads := host.GetMetricDiffUint64("disk_device_reads", true) + diskDeviceReadsmerged := host.GetMetricDiffUint64("disk_device_readsmerged", true) + diskDeviceSectorsread := host.GetMetricDiffUint64("disk_device_sectorsread", true) + diskDeviceTimereading := host.GetMetricDiffUint64("disk_device_timereading", true) + diskDeviceWrites := host.GetMetricDiffUint64("disk_device_writes", true) + diskDeviceWritesmerged := host.GetMetricDiffUint64("disk_device_writesmerged", true) + diskDeviceSectorswritten := host.GetMetricDiffUint64("disk_device_sectorswritten", true) + diskDeviceTimewriting := host.GetMetricDiffUint64("disk_device_timewriting", true) + diskDeviceCurrentops := host.GetMetricDiffUint64("disk_device_currentops", true) + diskDeviceTimeforops := host.GetMetricDiffUint64("disk_device_timeforops", true) + diskDeviceWeightedtimeforops := host.GetMetricDiffUint64("disk_device_weightedtimeforops", true) result := append([]string{diskDeviceReads}, diskDeviceWrites) if config.Options.Verbose { diff --git a/collectors/diskcollector/worker.go b/collectors/diskcollector/worker.go index 1053aab..ae98253 100644 --- a/collectors/diskcollector/worker.go +++ b/collectors/diskcollector/worker.go @@ -4,7 +4,6 @@ import ( "path/filepath" "strings" - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" "github.com/cha87de/kvmtop/util" @@ -158,21 +157,21 @@ func diskCollect(domain *models.Domain) { } func diskPrint(domain *models.Domain) []string { - capacity := collectors.GetMetricUint64(domain.Measurable, "disk_size_capacity", 0) - allocation := collectors.GetMetricUint64(domain.Measurable, "disk_size_allocation", 0) - physical := collectors.GetMetricUint64(domain.Measurable, "disk_size_physical", 0) - - // errs := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_errs", true) - flushreq := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_flushreq", true) - flushtotaltimes := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_flushtotaltimes", true) - rdbytes := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_rdbytes", true) - rdreq := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_rdreq", true) - rdtotaltimes := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_rdtotaltimes", true) - wrbytes := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_wrbytes", true) - wrreq := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_wrreq", true) - wrtotaltimes := collectors.GetMetricDiffUint64(domain.Measurable, "disk_stats_wrtotaltimes", true) - - delayblkio := collectors.GetMetricDiffUint64(domain.Measurable, "disk_delayblkio", true) + capacity,_ := domain.GetMetricUint64("disk_size_capacity", 0) + allocation,_ := domain.GetMetricUint64("disk_size_allocation", 0) + physical,_ := domain.GetMetricUint64("disk_size_physical", 0) + + // errs := domain.GetMetricDiffUint64("disk_stats_errs", true) + flushreq := domain.GetMetricDiffUint64("disk_stats_flushreq", true) + flushtotaltimes := domain.GetMetricDiffUint64("disk_stats_flushtotaltimes", true) + rdbytes := domain.GetMetricDiffUint64("disk_stats_rdbytes", true) + rdreq := domain.GetMetricDiffUint64("disk_stats_rdreq", true) + rdtotaltimes := domain.GetMetricDiffUint64("disk_stats_rdtotaltimes", true) + wrbytes := domain.GetMetricDiffUint64("disk_stats_wrbytes", true) + wrreq := domain.GetMetricDiffUint64("disk_stats_wrreq", true) + wrtotaltimes := domain.GetMetricDiffUint64("disk_stats_wrtotaltimes", true) + + delayblkio := domain.GetMetricDiffUint64("disk_delayblkio", true) result := append([]string{capacity}, allocation) if config.Options.Verbose { diff --git a/collectors/hostcollector/collector.go b/collectors/hostcollector/collector.go index 55ed208..81cc31c 100644 --- a/collectors/hostcollector/collector.go +++ b/collectors/hostcollector/collector.go @@ -12,26 +12,26 @@ type Collector struct { // Lookup host collector data func (collector *Collector) Lookup() { - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) libvirtDomain, _ := models.Collection.LibvirtDomains.Load(uuid) domainLookup(&domain, libvirtDomain) return true }) - hostLookup(models.Collection.Host) + hostLookup(&models.Collection.Host) } // Collect host collector data func (collector *Collector) Collect() { // lookup for each domain - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { // uuid := key.(string) domain := value.(models.Domain) domainCollect(&domain) return true }) - hostCollect(models.Collection.Host) + hostCollect(&models.Collection.Host) } // Print returns the collectors measurements in a Printable struct @@ -56,7 +56,7 @@ func (collector *Collector) Print() models.Printable { // lookup for each domain printable.DomainValues = make(map[string][]string) - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) printable.DomainValues[uuid] = domainPrint(&domain) @@ -64,7 +64,7 @@ func (collector *Collector) Print() models.Printable { }) // lookup for host - printable.HostValues = hostPrint(models.Collection.Host) + printable.HostValues = hostPrint(&models.Collection.Host) return printable } diff --git a/collectors/hostcollector/domainPrint.go b/collectors/hostcollector/domainPrint.go index 4d66bd3..bf1397f 100644 --- a/collectors/hostcollector/domainPrint.go +++ b/collectors/hostcollector/domainPrint.go @@ -1,12 +1,11 @@ package hostcollector import ( - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/models" ) func domainPrint(domain *models.Domain) []string { - host := collectors.GetMetricString(domain.Measurable, "host_name", 0) + host := domain.GetMetricString("host_name", 0) result := append([]string{host}) return result } diff --git a/collectors/hostcollector/hostPrint.go b/collectors/hostcollector/hostPrint.go index 0a96bfb..8d7c339 100644 --- a/collectors/hostcollector/hostPrint.go +++ b/collectors/hostcollector/hostPrint.go @@ -1,17 +1,16 @@ package hostcollector import ( - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" ) func hostPrint(host *models.Host) []string { - hostname := collectors.GetMetricString(host.Measurable, "host_name", 0) + hostname := host.GetMetricString("host_name", 0) result := []string{hostname} if config.Options.Verbose { - hostUUID := collectors.GetMetricString(host.Measurable, "host_uuid", 0) + hostUUID := host.GetMetricString("host_uuid", 0) result = append(result, hostUUID) } return result diff --git a/collectors/iocollector/collector.go b/collectors/iocollector/collector.go index 5e37aef..8c1bcae 100644 --- a/collectors/iocollector/collector.go +++ b/collectors/iocollector/collector.go @@ -12,7 +12,7 @@ type Collector struct { // Lookup io collector data func (collector *Collector) Lookup() { - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) libvirtDomain, _ := models.Collection.LibvirtDomains.Load(uuid) @@ -24,7 +24,7 @@ func (collector *Collector) Lookup() { // Collect io collector data func (collector *Collector) Collect() { // lookup for each domain - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { // uuid := key.(string) domain := value.(models.Domain) ioCollect(&domain) @@ -54,7 +54,7 @@ func (collector *Collector) Print() models.Printable { // lookup for each domain printable.DomainValues = make(map[string][]string) - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) printable.DomainValues[uuid] = ioPrint(&domain) diff --git a/collectors/iocollector/worker.go b/collectors/iocollector/worker.go index 67ed852..14f2cd5 100644 --- a/collectors/iocollector/worker.go +++ b/collectors/iocollector/worker.go @@ -1,7 +1,6 @@ package iocollector import ( - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" "github.com/cha87de/kvmtop/util" @@ -24,13 +23,13 @@ func ioCollect(domain *models.Domain) { } func ioPrint(domain *models.Domain) []string { - rchar := collectors.GetMetricDiffUint64(domain.Measurable, "io_rchar", true) - wchar := collectors.GetMetricDiffUint64(domain.Measurable, "io_wchar", true) - syscr := collectors.GetMetricDiffUint64(domain.Measurable, "io_syscr", true) - syscw := collectors.GetMetricDiffUint64(domain.Measurable, "io_syscw", true) - readBytes := collectors.GetMetricDiffUint64(domain.Measurable, "io_read_bytes", true) - writeBytes := collectors.GetMetricDiffUint64(domain.Measurable, "io_write_bytes", true) - cancelledWriteBytes := collectors.GetMetricDiffUint64(domain.Measurable, "io_cancelled_write_bytes", true) + rchar := domain.GetMetricDiffUint64("io_rchar", true) + wchar := domain.GetMetricDiffUint64("io_wchar", true) + syscr := domain.GetMetricDiffUint64("io_syscr", true) + syscw := domain.GetMetricDiffUint64("io_syscw", true) + readBytes := domain.GetMetricDiffUint64("io_read_bytes", true) + writeBytes := domain.GetMetricDiffUint64("io_write_bytes", true) + cancelledWriteBytes := domain.GetMetricDiffUint64("io_cancelled_write_bytes", true) result := append([]string{readBytes}, writeBytes) if config.Options.Verbose { diff --git a/collectors/memcollector/collector.go b/collectors/memcollector/collector.go index 46a526c..03d73e7 100644 --- a/collectors/memcollector/collector.go +++ b/collectors/memcollector/collector.go @@ -14,26 +14,26 @@ const pagesize = 4096 // Lookup memory collector data func (collector *Collector) Lookup() { - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) libvirtDomain, _ := models.Collection.LibvirtDomains.Load(uuid) domainLookup(&domain, libvirtDomain) return true }) - hostLookup(models.Collection.Host) + hostLookup(&models.Collection.Host) } // Collect memory collector data func (collector *Collector) Collect() { // lookup for each domain - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { // uuid := key.(string) domain := value.(models.Domain) domainCollect(&domain) return true }) - hostCollect(models.Collection.Host) + hostCollect(&models.Collection.Host) } // Print returns the collectors measurements in a Printable struct @@ -111,7 +111,7 @@ func (collector *Collector) Print() models.Printable { // lookup for each domain printable.DomainValues = make(map[string][]string) - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) printable.DomainValues[uuid] = domainPrint(&domain) @@ -119,7 +119,7 @@ func (collector *Collector) Print() models.Printable { }) // lookup for host - printable.HostValues = hostPrint(models.Collection.Host) + printable.HostValues = hostPrint(&models.Collection.Host) return printable } diff --git a/collectors/memcollector/domainPrint.go b/collectors/memcollector/domainPrint.go index 9729ca1..435e952 100644 --- a/collectors/memcollector/domainPrint.go +++ b/collectors/memcollector/domainPrint.go @@ -1,22 +1,21 @@ package memcollector import ( - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" ) func domainPrint(domain *models.Domain) []string { - total := collectors.GetMetricUint64(domain.Measurable, "ram_total", 0) - used := collectors.GetMetricUint64(domain.Measurable, "ram_used", 0) + total, _ := domain.GetMetricUint64("ram_total", 0) + used, _ := domain.GetMetricUint64("ram_used", 0) - vsize := collectors.GetMetricUint64(domain.Measurable, "ram_vsize", 0) - rss := collectors.GetMetricUint64(domain.Measurable, "ram_rss", 0) + vsize, _ := domain.GetMetricUint64("ram_vsize", 0) + rss, _ := domain.GetMetricUint64("ram_rss", 0) - minflt := collectors.GetMetricDiffUint64(domain.Measurable, "ram_minflt", false) - cminflt := collectors.GetMetricDiffUint64(domain.Measurable, "ram_cminflt", false) - majflt := collectors.GetMetricDiffUint64(domain.Measurable, "ram_majflt", false) - cmajflt := collectors.GetMetricDiffUint64(domain.Measurable, "ram_cmajflt", false) + minflt := domain.GetMetricDiffUint64("ram_minflt", false) + cminflt := domain.GetMetricDiffUint64("ram_cminflt", false) + majflt := domain.GetMetricDiffUint64("ram_majflt", false) + cmajflt := domain.GetMetricDiffUint64("ram_cmajflt", false) result := append([]string{total}, used) if config.Options.Verbose { diff --git a/collectors/memcollector/hostCollect.go b/collectors/memcollector/hostCollect.go index c7998e1..1e97c18 100644 --- a/collectors/memcollector/hostCollect.go +++ b/collectors/memcollector/hostCollect.go @@ -56,4 +56,6 @@ func hostCollect(host *models.Host) { host.AddMetricMeasurement("ram_DirectMap2M", models.CreateMeasurement(uint64(stats.DirectMap2M))) host.AddMetricMeasurement("ram_DirectMap1G", models.CreateMeasurement(uint64(stats.DirectMap1G))) + //fmt.Printf("collected these values: %+v\n\n", host.Dump()) + } diff --git a/collectors/memcollector/hostPrint.go b/collectors/memcollector/hostPrint.go index 6c6087e..b911d1c 100644 --- a/collectors/memcollector/hostPrint.go +++ b/collectors/memcollector/hostPrint.go @@ -1,60 +1,63 @@ package memcollector import ( - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" + "fmt" ) func hostPrint(host *models.Host) []string { - Total := collectors.GetMetricUint64(host.Measurable, "ram_Total", 0) - Free := collectors.GetMetricUint64(host.Measurable, "ram_Free", 0) - Available := collectors.GetMetricUint64(host.Measurable, "ram_Available", 0) - Buffers := collectors.GetMetricUint64(host.Measurable, "ram_Buffers", 0) - Cached := collectors.GetMetricUint64(host.Measurable, "ram_Cached", 0) - SwapCached := collectors.GetMetricUint64(host.Measurable, "ram_SwapCached", 0) - Active := collectors.GetMetricUint64(host.Measurable, "ram_Active", 0) - Inactive := collectors.GetMetricUint64(host.Measurable, "ram_Inactive", 0) - ActiveAanon := collectors.GetMetricUint64(host.Measurable, "ram_ActiveAanon", 0) - InactiveAanon := collectors.GetMetricUint64(host.Measurable, "ram_InactiveAanon", 0) - ActiveFile := collectors.GetMetricUint64(host.Measurable, "ram_ActiveFile", 0) - InactiveFile := collectors.GetMetricUint64(host.Measurable, "ram_InactiveFile", 0) - Unevictable := collectors.GetMetricUint64(host.Measurable, "ram_Unevictable", 0) - Mlocked := collectors.GetMetricUint64(host.Measurable, "ram_Mlocked", 0) - SwapTotal := collectors.GetMetricUint64(host.Measurable, "ram_SwapTotal", 0) - SwapFree := collectors.GetMetricUint64(host.Measurable, "ram_SwapFree", 0) - Dirty := collectors.GetMetricUint64(host.Measurable, "ram_Dirty", 0) - Writeback := collectors.GetMetricUint64(host.Measurable, "ram_Writeback", 0) - AnonPages := collectors.GetMetricUint64(host.Measurable, "ram_AnonPages", 0) - Mapped := collectors.GetMetricUint64(host.Measurable, "ram_Mapped", 0) - Shmem := collectors.GetMetricUint64(host.Measurable, "ram_Shmem", 0) - Slab := collectors.GetMetricUint64(host.Measurable, "ram_Slab", 0) - SReclaimable := collectors.GetMetricUint64(host.Measurable, "ram_SReclaimable", 0) - SUnreclaim := collectors.GetMetricUint64(host.Measurable, "ram_SUnreclaim", 0) - KernelStack := collectors.GetMetricUint64(host.Measurable, "ram_KernelStack", 0) - PageTables := collectors.GetMetricUint64(host.Measurable, "ram_PageTables", 0) - NFSUnstable := collectors.GetMetricUint64(host.Measurable, "ram_NFSUnstable", 0) - Bounce := collectors.GetMetricUint64(host.Measurable, "ram_Bounce", 0) - WritebackTmp := collectors.GetMetricUint64(host.Measurable, "ram_WritebackTmp", 0) - CommitLimit := collectors.GetMetricUint64(host.Measurable, "ram_CommitLimit", 0) - CommittedAS := collectors.GetMetricUint64(host.Measurable, "ram_CommittedAS", 0) - VmallocTotal := collectors.GetMetricUint64(host.Measurable, "ram_VmallocTotal", 0) - VmallocUsed := collectors.GetMetricUint64(host.Measurable, "ram_VmallocUsed", 0) - VmallocChunk := collectors.GetMetricUint64(host.Measurable, "ram_VmallocChunk", 0) - HardwareCorrupted := collectors.GetMetricUint64(host.Measurable, "ram_HardwareCorrupted", 0) - AnonHugePages := collectors.GetMetricUint64(host.Measurable, "ram_AnonHugePages", 0) - ShmemHugePages := collectors.GetMetricUint64(host.Measurable, "ram_ShmemHugePages", 0) - ShmemPmdMapped := collectors.GetMetricUint64(host.Measurable, "ram_ShmemPmdMapped", 0) - HugePagesTotal := collectors.GetMetricUint64(host.Measurable, "ram_HugePagesTotal", 0) - HugePagesFree := collectors.GetMetricUint64(host.Measurable, "ram_HugePagesFree", 0) - HugePagesRsvd := collectors.GetMetricUint64(host.Measurable, "ram_HugePagesRsvd", 0) - HugePagesSurp := collectors.GetMetricUint64(host.Measurable, "ram_HugePagesSurp", 0) - Hugepagesize := collectors.GetMetricUint64(host.Measurable, "ram_Hugepagesize", 0) - Hugetlb := collectors.GetMetricUint64(host.Measurable, "ram_Hugetlb", 0) - DirectMap4k := collectors.GetMetricUint64(host.Measurable, "ram_DirectMap4k", 0) - DirectMap2M := collectors.GetMetricUint64(host.Measurable, "ram_DirectMap2M", 0) - DirectMap1G := collectors.GetMetricUint64(host.Measurable, "ram_DirectMap1G", 0) + Total, err := host.GetMetricUint64("ram_Total", 0) + if err != nil { + fmt.Printf("error getting ram_total: %s\n", err) + } + Free, _ := host.GetMetricUint64("ram_Free", 0) + Available,_ := host.GetMetricUint64("ram_Available", 0) + Buffers,_ := host.GetMetricUint64("ram_Buffers", 0) + Cached,_ := host.GetMetricUint64("ram_Cached", 0) + SwapCached,_ := host.GetMetricUint64("ram_SwapCached", 0) + Active,_ := host.GetMetricUint64("ram_Active", 0) + Inactive,_ := host.GetMetricUint64("ram_Inactive", 0) + ActiveAanon,_ := host.GetMetricUint64("ram_ActiveAanon", 0) + InactiveAanon,_ := host.GetMetricUint64("ram_InactiveAanon", 0) + ActiveFile,_ := host.GetMetricUint64("ram_ActiveFile", 0) + InactiveFile,_ := host.GetMetricUint64("ram_InactiveFile", 0) + Unevictable,_ := host.GetMetricUint64("ram_Unevictable", 0) + Mlocked,_ := host.GetMetricUint64("ram_Mlocked", 0) + SwapTotal,_ := host.GetMetricUint64("ram_SwapTotal", 0) + SwapFree,_ := host.GetMetricUint64("ram_SwapFree", 0) + Dirty,_ := host.GetMetricUint64("ram_Dirty", 0) + Writeback,_ := host.GetMetricUint64("ram_Writeback", 0) + AnonPages,_ := host.GetMetricUint64("ram_AnonPages", 0) + Mapped,_ := host.GetMetricUint64("ram_Mapped", 0) + Shmem,_ := host.GetMetricUint64("ram_Shmem", 0) + Slab,_ := host.GetMetricUint64("ram_Slab", 0) + SReclaimable,_ := host.GetMetricUint64("ram_SReclaimable", 0) + SUnreclaim,_ := host.GetMetricUint64("ram_SUnreclaim", 0) + KernelStack,_ := host.GetMetricUint64("ram_KernelStack", 0) + PageTables,_ := host.GetMetricUint64("ram_PageTables", 0) + NFSUnstable,_ := host.GetMetricUint64("ram_NFSUnstable", 0) + Bounce,_ := host.GetMetricUint64("ram_Bounce", 0) + WritebackTmp,_ := host.GetMetricUint64("ram_WritebackTmp", 0) + CommitLimit,_ := host.GetMetricUint64("ram_CommitLimit", 0) + CommittedAS,_ := host.GetMetricUint64("ram_CommittedAS", 0) + VmallocTotal,_ := host.GetMetricUint64("ram_VmallocTotal", 0) + VmallocUsed,_ := host.GetMetricUint64("ram_VmallocUsed", 0) + VmallocChunk,_ := host.GetMetricUint64("ram_VmallocChunk", 0) + HardwareCorrupted,_ := host.GetMetricUint64("ram_HardwareCorrupted", 0) + AnonHugePages,_ := host.GetMetricUint64("ram_AnonHugePages", 0) + ShmemHugePages,_ := host.GetMetricUint64("ram_ShmemHugePages", 0) + ShmemPmdMapped,_ := host.GetMetricUint64("ram_ShmemPmdMapped", 0) + HugePagesTotal,_ := host.GetMetricUint64("ram_HugePagesTotal", 0) + HugePagesFree,_ := host.GetMetricUint64("ram_HugePagesFree", 0) + HugePagesRsvd,_ := host.GetMetricUint64("ram_HugePagesRsvd", 0) + HugePagesSurp,_ := host.GetMetricUint64("ram_HugePagesSurp", 0) + Hugepagesize,_ := host.GetMetricUint64("ram_Hugepagesize", 0) + Hugetlb,_ := host.GetMetricUint64("ram_Hugetlb", 0) + DirectMap4k,_ := host.GetMetricUint64("ram_DirectMap4k", 0) + DirectMap2M,_ := host.GetMetricUint64("ram_DirectMap2M", 0) + DirectMap1G,_ := host.GetMetricUint64("ram_DirectMap1G", 0) result := append([]string{Total}, Free, Available) if config.Options.Verbose { diff --git a/collectors/netcollector/collector.go b/collectors/netcollector/collector.go index 3eee7c3..3b0bd24 100644 --- a/collectors/netcollector/collector.go +++ b/collectors/netcollector/collector.go @@ -12,7 +12,7 @@ type Collector struct { // Lookup network collector data func (collector *Collector) Lookup() { - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) libvirtDomain, _ := models.Collection.LibvirtDomains.Load(uuid) @@ -20,19 +20,19 @@ func (collector *Collector) Lookup() { return true }) - hostLookup(models.Collection.Host) + hostLookup(&models.Collection.Host) } // Collect network collector data func (collector *Collector) Collect() { // lookup for each domain - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { // uuid := key.(string) domain := value.(models.Domain) domainCollect(&domain) return true }) - hostCollect(models.Collection.Host) + hostCollect(&models.Collection.Host) } // Print returns the collectors measurements in a Printable struct @@ -88,7 +88,7 @@ func (collector *Collector) Print() models.Printable { // lookup for each domain printable.DomainValues = make(map[string][]string) - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) printable.DomainValues[uuid] = domainPrint(&domain) @@ -96,7 +96,7 @@ func (collector *Collector) Print() models.Printable { }) // lookup for host - printable.HostValues = hostPrint(models.Collection.Host) + printable.HostValues = hostPrint(&models.Collection.Host) return printable } diff --git a/collectors/netcollector/domainPrint.go b/collectors/netcollector/domainPrint.go index 7507dc3..58892aa 100644 --- a/collectors/netcollector/domainPrint.go +++ b/collectors/netcollector/domainPrint.go @@ -3,28 +3,27 @@ package netcollector import ( "strings" - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" ) func domainPrint(domain *models.Domain) []string { - receivedBytes := collectors.GetMetricDiffUint64(domain.Measurable, "net_ReceivedBytes", true) - receivedPackets := collectors.GetMetricDiffUint64(domain.Measurable, "net_ReceivedPackets", true) - receivedErrs := collectors.GetMetricDiffUint64(domain.Measurable, "net_ReceivedErrs", true) - receivedDrop := collectors.GetMetricDiffUint64(domain.Measurable, "net_ReceivedDrop", true) - receivedFifo := collectors.GetMetricDiffUint64(domain.Measurable, "net_ReceivedFifo", true) - receivedFrame := collectors.GetMetricDiffUint64(domain.Measurable, "net_ReceivedFrame", true) - receivedCompressed := collectors.GetMetricDiffUint64(domain.Measurable, "net_ReceivedCompressed", true) - receivedMulticast := collectors.GetMetricDiffUint64(domain.Measurable, "net_ReceivedMulticast", true) - transmittedBytes := collectors.GetMetricDiffUint64(domain.Measurable, "net_TransmittedBytes", true) - transmittedPackets := collectors.GetMetricDiffUint64(domain.Measurable, "net_TransmittedPackets", true) - transmittedErrs := collectors.GetMetricDiffUint64(domain.Measurable, "net_TransmittedErrs", true) - transmittedDrop := collectors.GetMetricDiffUint64(domain.Measurable, "net_TransmittedDrop", true) - transmittedFifo := collectors.GetMetricDiffUint64(domain.Measurable, "net_TransmittedFifo", true) - transmittedColls := collectors.GetMetricDiffUint64(domain.Measurable, "net_TransmittedColls", true) - transmittedCarrier := collectors.GetMetricDiffUint64(domain.Measurable, "net_TransmittedCarrier", true) - transmittedCompressed := collectors.GetMetricDiffUint64(domain.Measurable, "net_TransmittedCompressed", true) + receivedBytes := domain.GetMetricDiffUint64("net_ReceivedBytes", true) + receivedPackets := domain.GetMetricDiffUint64("net_ReceivedPackets", true) + receivedErrs := domain.GetMetricDiffUint64("net_ReceivedErrs", true) + receivedDrop := domain.GetMetricDiffUint64("net_ReceivedDrop", true) + receivedFifo := domain.GetMetricDiffUint64("net_ReceivedFifo", true) + receivedFrame := domain.GetMetricDiffUint64("net_ReceivedFrame", true) + receivedCompressed := domain.GetMetricDiffUint64("net_ReceivedCompressed", true) + receivedMulticast := domain.GetMetricDiffUint64("net_ReceivedMulticast", true) + transmittedBytes := domain.GetMetricDiffUint64("net_TransmittedBytes", true) + transmittedPackets := domain.GetMetricDiffUint64("net_TransmittedPackets", true) + transmittedErrs := domain.GetMetricDiffUint64("net_TransmittedErrs", true) + transmittedDrop := domain.GetMetricDiffUint64("net_TransmittedDrop", true) + transmittedFifo := domain.GetMetricDiffUint64("net_TransmittedFifo", true) + transmittedColls := domain.GetMetricDiffUint64("net_TransmittedColls", true) + transmittedCarrier := domain.GetMetricDiffUint64("net_TransmittedCarrier", true) + transmittedCompressed := domain.GetMetricDiffUint64("net_TransmittedCompressed", true) ifsRaw := domain.GetMetricStringArray("net_interfaces") interfaces := strings.Join(ifsRaw, ";") diff --git a/collectors/netcollector/hostPrint.go b/collectors/netcollector/hostPrint.go index 75a3b68..3a094fd 100644 --- a/collectors/netcollector/hostPrint.go +++ b/collectors/netcollector/hostPrint.go @@ -1,30 +1,29 @@ package netcollector import ( - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/models" ) func hostPrint(host *models.Host) []string { - receivedBytes := collectors.GetMetricDiffUint64(host.Measurable, "net_host_ReceivedBytes", true) - receivedPackets := collectors.GetMetricDiffUint64(host.Measurable, "net_host_ReceivedPackets", true) - receivedErrs := collectors.GetMetricDiffUint64(host.Measurable, "net_host_ReceivedErrs", true) - receivedDrop := collectors.GetMetricDiffUint64(host.Measurable, "net_host_ReceivedDrop", true) - receivedFifo := collectors.GetMetricDiffUint64(host.Measurable, "net_host_ReceivedFifo", true) - receivedFrame := collectors.GetMetricDiffUint64(host.Measurable, "net_host_ReceivedFrame", true) - receivedCompressed := collectors.GetMetricDiffUint64(host.Measurable, "net_host_ReceivedCompressed", true) - receivedMulticast := collectors.GetMetricDiffUint64(host.Measurable, "net_host_ReceivedMulticast", true) - transmittedBytes := collectors.GetMetricDiffUint64(host.Measurable, "net_host_TransmittedBytes", true) - transmittedPackets := collectors.GetMetricDiffUint64(host.Measurable, "net_host_TransmittedPackets", true) - transmittedErrs := collectors.GetMetricDiffUint64(host.Measurable, "net_host_TransmittedErrs", true) - transmittedDrop := collectors.GetMetricDiffUint64(host.Measurable, "net_host_TransmittedDrop", true) - transmittedFifo := collectors.GetMetricDiffUint64(host.Measurable, "net_host_TransmittedFifo", true) - transmittedColls := collectors.GetMetricDiffUint64(host.Measurable, "net_host_TransmittedColls", true) - transmittedCarrier := collectors.GetMetricDiffUint64(host.Measurable, "net_host_TransmittedCarrier", true) - transmittedCompressed := collectors.GetMetricDiffUint64(host.Measurable, "net_host_TransmittedCompressed", true) + receivedBytes := host.GetMetricDiffUint64("net_host_ReceivedBytes", true) + receivedPackets := host.GetMetricDiffUint64("net_host_ReceivedPackets", true) + receivedErrs := host.GetMetricDiffUint64("net_host_ReceivedErrs", true) + receivedDrop := host.GetMetricDiffUint64("net_host_ReceivedDrop", true) + receivedFifo := host.GetMetricDiffUint64("net_host_ReceivedFifo", true) + receivedFrame := host.GetMetricDiffUint64("net_host_ReceivedFrame", true) + receivedCompressed := host.GetMetricDiffUint64("net_host_ReceivedCompressed", true) + receivedMulticast := host.GetMetricDiffUint64("net_host_ReceivedMulticast", true) + transmittedBytes := host.GetMetricDiffUint64("net_host_TransmittedBytes", true) + transmittedPackets := host.GetMetricDiffUint64("net_host_TransmittedPackets", true) + transmittedErrs := host.GetMetricDiffUint64("net_host_TransmittedErrs", true) + transmittedDrop := host.GetMetricDiffUint64("net_host_TransmittedDrop", true) + transmittedFifo := host.GetMetricDiffUint64("net_host_TransmittedFifo", true) + transmittedColls := host.GetMetricDiffUint64("net_host_TransmittedColls", true) + transmittedCarrier := host.GetMetricDiffUint64("net_host_TransmittedCarrier", true) + transmittedCompressed := host.GetMetricDiffUint64("net_host_TransmittedCompressed", true) - speed := collectors.GetMetricUint64(host.Measurable, "net_host_speed", 0) + speed, _ := host.GetMetricUint64("net_host_speed", 0) result := append([]string{receivedBytes}, transmittedBytes, speed) if config.Options.Verbose { diff --git a/collectors/psicollector/collector.go b/collectors/psicollector/collector.go index 579e14f..cc22420 100644 --- a/collectors/psicollector/collector.go +++ b/collectors/psicollector/collector.go @@ -12,12 +12,12 @@ type Collector struct { // Lookup disk collector data func (collector *Collector) Lookup() { - hostLookup(models.Collection.Host) + hostLookup(&models.Collection.Host) } // Collect disk collector data func (collector *Collector) Collect() { - hostCollect(models.Collection.Host) + hostCollect(&models.Collection.Host) } // Print returns the collectors measurements in a Printable struct @@ -66,7 +66,7 @@ func (collector *Collector) Print() models.Printable { } // lookup for host - printable.HostValues = printHost(models.Collection.Host) + printable.HostValues = printHost(&models.Collection.Host) return printable } diff --git a/collectors/psicollector/host-worker.go b/collectors/psicollector/host-worker.go index 6bc55d5..d8cd7e5 100644 --- a/collectors/psicollector/host-worker.go +++ b/collectors/psicollector/host-worker.go @@ -3,7 +3,6 @@ package psicollector import ( "fmt" - "github.com/cha87de/kvmtop/collectors" "github.com/cha87de/kvmtop/config" "github.com/cha87de/kvmtop/util" @@ -68,11 +67,12 @@ func printHostResource(host *models.Host, resource util.ProcPressureResource, qu for _, metric := range metrics { fieldPrefix := fmt.Sprintf("psi_%s_%s", metric, resource) - result = append(result, collectors.GetMetricFloat64(host.Measurable, fmt.Sprintf("%s_avg60", fieldPrefix), 0)) + result = append(result, host.GetMetricFloat64(fmt.Sprintf("%s_avg60", fieldPrefix), 0)) if verbose { - result = append(result, collectors.GetMetricFloat64(host.Measurable, fmt.Sprintf("%s_avg10", fieldPrefix), 0)) - result = append(result, collectors.GetMetricFloat64(host.Measurable, fmt.Sprintf("%s_avg300", fieldPrefix), 0)) - result = append(result, collectors.GetMetricUint64(host.Measurable, fmt.Sprintf("%s_total", fieldPrefix), 0)) + result = append(result, host.GetMetricFloat64(fmt.Sprintf("%s_avg10", fieldPrefix), 0)) + result = append(result, host.GetMetricFloat64(fmt.Sprintf("%s_avg300", fieldPrefix), 0)) + val, _ := host.GetMetricUint64(fmt.Sprintf("%s_total", fieldPrefix), 0) + result = append(result, val) } } return result diff --git a/models/collection.go b/models/collection.go index 0830234..b15b605 100644 --- a/models/collection.go +++ b/models/collection.go @@ -1,150 +1,19 @@ package models -import ( - "bytes" - "encoding/gob" - "sync" - "time" -) +func init() { + // initialize the collection variable + Collection.Domains = *NewDomains() + Collection.Collectors = *NewCollectors() + Collection.Host = Host{ + Measurable: NewMeasurable(), + } +} // Collection of domains and other stuff var Collection struct { - Host *Host + Host Host Domains Domains Collectors Collectors Printer Printer LibvirtDomains LibvirtDomains } - -// Measurable holds collector metrics in a sync.Map -type Measurable struct { - Metrics sync.Map -} - -// Domain defines a domain in libvirt -type Domain struct { - *Measurable - Name string - UUID string - PID int -} - -// Host defines the local host libvirt runs on -type Host struct { - *Measurable -} - -// Printable represents a set of fields and values to be printed -type Printable struct { - HostFields []string - DomainFields []string - HostValues []string - DomainValues map[string][]string -} - -// AddMetricMeasurement adds a metric measurement -func (measurable *Measurable) AddMetricMeasurement(metricName string, measurement Measurement) { - // create empty metric if not existent - if _, ok := measurable.Metrics.Load(metricName); !ok { - measurable.Metrics.Store(metricName, &Metric{ - Name: metricName, - Values: []Measurement{}, - }) - } - rawmetrics, _ := measurable.Metrics.Load(metricName) - metrics := rawmetrics.(*Metric) - - // add measurement as value to metric - end := len(metrics.Values) - 1 - if end <= 0 { - end = len(metrics.Values) - } - //domain.Metrics[metricName].Values = - metrics.Values = append([]Measurement{measurement}, metrics.Values[0:end]...) - - // store back - //domain.Metrics.Store(metricName, metrics) -} - -// DelMetricMeasurement removes a metric -func (measurable *Measurable) DelMetricMeasurement(metricName string) { - measurable.Metrics.Delete(metricName) -} - -// GetMetric reads and returns the metric values by metric name -func (measurable *Measurable) GetMetric(metricName string) (*Metric, bool) { - rawmetric, exists := measurable.Metrics.Load(metricName) - if !exists { - return &Metric{}, false - } - metric := rawmetric.(*Metric) - return metric, true -} - -// GetMetricIntArray reads and returns a metric int array by metric name -func (measurable *Measurable) GetMetricIntArray(metricName string) []int { - var array []int - if metric, ok := measurable.GetMetric(metricName); ok { - if len(metric.Values) > 0 { - byteValue := metric.Values[0].Value - reader := bytes.NewReader(byteValue) - dec := gob.NewDecoder(reader) - dec.Decode(&array) - } - } - return array -} - -// GetMetricStringArray reads and returns a metric string array by metric name -func (measurable *Measurable) GetMetricStringArray(metricName string) []string { - var array []string - if metric, ok := measurable.GetMetric(metricName); ok { - if len(metric.Values) > 0 { - byteValue := metric.Values[0].Value - reader := bytes.NewReader(byteValue) - dec := gob.NewDecoder(reader) - dec.Decode(&array) - } - } - return array -} - -// Collector defines a collector for a domain specific metric (e.g. CPU) -type Collector interface { - Lookup() - Collect() - Print() Printable -} - -// Metric contains a monitoring metric value with current and previous -type Metric struct { - Name string - Values []Measurement -} - -// Measurement represents one measurement value at a timestamp -type Measurement struct { - Value []byte - Timestamp time.Time -} - -// CreateMeasurement creates a new measurement with recent time and bytes from provided value -func CreateMeasurement(value interface{}) Measurement { - var buffer bytes.Buffer - enc := gob.NewEncoder(&buffer) - err := enc.Encode(value) - if err != nil { - return Measurement{} - } - return Measurement{ - Value: buffer.Bytes(), - Timestamp: time.Now(), - } -} - -// Printer defines a printer for output -type Printer interface { - Open() - Screen(Printable) - Close() -} diff --git a/models/collector.go b/models/collector.go new file mode 100644 index 0000000..cec608f --- /dev/null +++ b/models/collector.go @@ -0,0 +1,8 @@ +package models + +// Collector defines a collector for a domain specific metric (e.g. CPU) +type Collector interface { + Lookup() + Collect() + Print() Printable +} diff --git a/models/collectors.go b/models/collectors.go index f9caeef..4c0d60c 100644 --- a/models/collectors.go +++ b/models/collectors.go @@ -2,32 +2,57 @@ package models import "sync" -// Collectors holds the configured collectors in a sync.Map +// NewCollectors instantiates a new Collectors list +func NewCollectors() *Collectors { + return &Collectors{ + access: sync.Mutex{}, + collectors: make(map[interface{}]Collector), + } +} + +// Collectors holds the configured collectors in a Map type Collectors struct { - Map sync.Map + // Map sync.Map + collectors map[interface{}]Collector + access sync.Mutex } // Load returns the value stored as "key" identifier func (collectors *Collectors) Load(key interface{}) (Collector, bool) { - rawValue, ok := collectors.Map.Load(key) - if !ok { - return nil, ok + collectors.access.Lock() + defer collectors.access.Unlock() + Collector, exists := collectors.collectors[key] + if !exists { + return nil, false } - value := rawValue.(Collector) - return value, ok + return Collector, true } // Store writes the key value pair to the sync map func (collectors *Collectors) Store(key string, value Collector) { - collectors.Map.Store(key, value) + collectors.access.Lock() + defer collectors.access.Unlock() + //collectors.Map.Store(key, value) + collectors.collectors[key] = value } // Length returns the number of elements stored in the map func (collectors *Collectors) Length() int { - counter := 0 - collectors.Map.Range(func(_, _ interface{}) bool { - counter++ - return true - }) - return counter + return len(collectors.collectors) +} + +// Range loops over the items and executes the given function +func (collectors *Collectors) Range(f func(key interface{}, value Collector) bool) { + collectors.access.Lock() + defer collectors.access.Unlock() + for key, collector := range collectors.collectors { + f(key, collector) + } +} + +// Delete removes the element given by ke from the collectors list +func (collectors *Collectors) Delete(key string) { + collectors.access.Lock() + defer collectors.access.Unlock() + delete(collectors.collectors, key) } diff --git a/models/domain.go b/models/domain.go new file mode 100644 index 0000000..1ef0534 --- /dev/null +++ b/models/domain.go @@ -0,0 +1,9 @@ +package models + +// Domain defines a domain in libvirt +type Domain struct { + *Measurable + Name string + UUID string + PID int +} diff --git a/models/domains.go b/models/domains.go index 0d1ec19..7244cca 100644 --- a/models/domains.go +++ b/models/domains.go @@ -2,32 +2,57 @@ package models import "sync" -// Domains holds the collected Domains in a sync.Map +// NewDomains instantiates a new Domains list +func NewDomains() *Domains { + return &Domains{ + access: sync.Mutex{}, + domains: make(map[interface{}]Domain), + } +} + +// Domains holds the collected Domains in a map type Domains struct { - Map sync.Map + //Map sync.Map + access sync.Mutex + domains map[interface{}]Domain } // Load returns the value stored as "key" identifier func (domains *Domains) Load(key interface{}) (Domain, bool) { - rawValue, ok := domains.Map.Load(key) - if !ok { - return Domain{}, ok + domains.access.Lock() + defer domains.access.Unlock() + domain, exists := domains.domains[key] + if !exists { + return Domain{}, false } - value := rawValue.(Domain) - return value, ok + return domain, true } // Store writes the key value pair to the sync map func (domains *Domains) Store(key string, value Domain) { - domains.Map.Store(key, value) + domains.access.Lock() + defer domains.access.Unlock() + //domains.Map.Store(key, value) + domains.domains[key] = value } // Length returns the number of elements stored in the map func (domains *Domains) Length() int { - counter := 0 - domains.Map.Range(func(_, _ interface{}) bool { - counter++ - return true - }) - return counter + return len(domains.domains) +} + +// Range loops over the items and executes the given function +func (domains *Domains) Range(f func(key, value interface{}) bool) { + domains.access.Lock() + defer domains.access.Unlock() + for key, domain := range domains.domains { + f(key, domain) + } +} + +// Delete removes the element given by ke from the domains list +func (domains *Domains) Delete(key string) { + domains.access.Lock() + defer domains.access.Unlock() + delete(domains.domains, key) } diff --git a/models/host.go b/models/host.go new file mode 100644 index 0000000..adf5393 --- /dev/null +++ b/models/host.go @@ -0,0 +1,6 @@ +package models + +// Host defines the local host libvirt runs on +type Host struct { + *Measurable +} diff --git a/models/measurable.go b/models/measurable.go new file mode 100644 index 0000000..854a4fb --- /dev/null +++ b/models/measurable.go @@ -0,0 +1,189 @@ +package models + +import ( + "bytes" + "encoding/gob" + "fmt" + "sync" +) + +// NewMeasurable instantiates and returns a new Measurable +func NewMeasurable() *Measurable { + return &Measurable{ + //Metrics: sync.Map{}, + metrics: make(map[string]Metric), + access: sync.Mutex{}, + } +} + +// Measurable holds collector metrics in a map +type Measurable struct { + //Metrics sync.Map + access sync.Mutex + metrics map[string]Metric +} + +// AddMetricMeasurement adds a metric measurement +func (measurable *Measurable) AddMetricMeasurement(metricName string, measurement Measurement) { + measurable.access.Lock() + defer measurable.access.Unlock() + + // create empty metric if not existent + if _, ok := measurable.metrics[metricName]; !ok { + measurable.metrics[metricName] = Metric{ + Name: metricName, + Values: []Measurement{}, + } + } + + metric := measurable.metrics[metricName] + + // add measurement as value to metric + end := len(metric.Values) - 1 + if end <= 0 { + end = len(metric.Values) + } + metric.Values = append([]Measurement{measurement}, metric.Values[0:end]...) + + // store back + measurable.metrics[metricName] = metric +} + +// DelMetricMeasurement removes a metric +func (measurable *Measurable) DelMetricMeasurement(metricName string) { + measurable.access.Lock() + defer measurable.access.Unlock() + delete(measurable.metrics, metricName) +} + +// GetMetric reads and returns the metric values by metric name +func (measurable *Measurable) GetMetric(metricName string) (*Metric, bool) { + measurable.access.Lock() + defer measurable.access.Unlock() + var metric Metric + metric, exists := measurable.metrics[metricName] + if !exists { + return &Metric{}, false + } + return &metric, true +} + +// GetMetricString returns the given metric value at measurement index as string +func (measurable *Measurable) GetMetricString(metricName string, measurementIndex int) string { + var output string + if metric, ok := measurable.GetMetric(metricName); ok { + if len(metric.Values) > measurementIndex { + byteValue := metric.Values[measurementIndex].Value + reader := bytes.NewReader(byteValue) + decoder := gob.NewDecoder(reader) + var valuetype string + decoder.Decode(&valuetype) + output = fmt.Sprintf("%s", valuetype) + } + } + return output +} + +// GetMetricIntArray reads and returns a metric int array by metric name +func (measurable *Measurable) GetMetricIntArray(metricName string) []int { + var array []int + if metric, ok := measurable.GetMetric(metricName); ok { + if len(metric.Values) > 0 { + byteValue := metric.Values[0].Value + reader := bytes.NewReader(byteValue) + dec := gob.NewDecoder(reader) + dec.Decode(&array) + } + } + return array +} + +// GetMetricStringArray reads and returns a metric string array by metric name +func (measurable *Measurable) GetMetricStringArray(metricName string) []string { + var array []string + if metric, ok := measurable.GetMetric(metricName); ok { + if len(metric.Values) > 0 { + byteValue := metric.Values[0].Value + reader := bytes.NewReader(byteValue) + dec := gob.NewDecoder(reader) + dec.Decode(&array) + } + } + return array +} + +// Dump returns all the measurements as map +func (measurable *Measurable) Dump() map[string]Metric { + return measurable.metrics +} + +// GetMetricUint64 returns the given metric value at measurement index as string +func (measurable *Measurable) GetMetricUint64(metricName string, measurementIndex int) (string, error) { + var output string + if metric, ok := measurable.GetMetric(metricName); ok { + if len(metric.Values) > measurementIndex { + byteValue := metric.Values[measurementIndex].Value + reader := bytes.NewReader(byteValue) + decoder := gob.NewDecoder(reader) + var valuetype uint64 + decoder.Decode(&valuetype) + output = fmt.Sprintf("%d", valuetype) + } else { + return "", fmt.Errorf("metric %s has no index %d", metricName, measurementIndex) + } + } else { + // fmt.Printf("metric %s not found, dump: %+v\n", metricName, measurable.Dump()) + return "", fmt.Errorf("metric %s not found", metricName) + } + return output, nil +} + +// GetMetricFloat64 computes the diff as Float64 between the two measurements for given metric and returns it as string +func (measurable *Measurable) GetMetricFloat64(metricName string, measurementIndex int) string { + var output string + if metric, ok := measurable.GetMetric(metricName); ok { + if len(metric.Values) > measurementIndex { + byteValue := metric.Values[measurementIndex].Value + reader := bytes.NewReader(byteValue) + decoder := gob.NewDecoder(reader) + var valuetype float64 + decoder.Decode(&valuetype) + output = fmt.Sprintf("%f", valuetype) + } + } + return output +} + +// GetMetricDiffUint64 computes the diff as Uint64 between the two measurements for given metric and returns it as string +func (measurable *Measurable) GetMetricDiffUint64(metricName string, perTime bool) string { + var output string + if metric, ok := measurable.GetMetric(metricName); ok { + if len(metric.Values) >= 2 { + // get first value + byteValue1 := metric.Values[0].Value + reader1 := bytes.NewReader(byteValue1) + decoder1 := gob.NewDecoder(reader1) + var value1 uint64 + decoder1.Decode(&value1) + + // get second value + byteValue2 := metric.Values[1].Value + reader2 := bytes.NewReader(byteValue2) + decoder2 := gob.NewDecoder(reader2) + var value2 uint64 + decoder2.Decode(&value2) + + // calculate value diff per time + value := float64(value1 - value2) + + // get time diff + if perTime { + timeDiff := metric.Values[0].Timestamp.Sub(metric.Values[1].Timestamp).Seconds() + value = value / timeDiff + } + + output = fmt.Sprintf("%.0f", value) + } + } + return output +} diff --git a/models/measurement.go b/models/measurement.go new file mode 100644 index 0000000..2ef3836 --- /dev/null +++ b/models/measurement.go @@ -0,0 +1,27 @@ +package models + +import ( + "bytes" + "encoding/gob" + "time" +) + +// Measurement represents one measurement value at a timestamp +type Measurement struct { + Value []byte + Timestamp time.Time +} + +// CreateMeasurement creates a new measurement with recent time and bytes from provided value +func CreateMeasurement(value interface{}) Measurement { + var buffer bytes.Buffer + enc := gob.NewEncoder(&buffer) + err := enc.Encode(value) + if err != nil { + return Measurement{} + } + return Measurement{ + Value: buffer.Bytes(), + Timestamp: time.Now(), + } +} diff --git a/models/metric.go b/models/metric.go new file mode 100644 index 0000000..8b19b9e --- /dev/null +++ b/models/metric.go @@ -0,0 +1,7 @@ +package models + +// Metric contains a monitoring metric value with current and previous +type Metric struct { + Name string + Values []Measurement +} diff --git a/models/printable.go b/models/printable.go new file mode 100644 index 0000000..ba9234d --- /dev/null +++ b/models/printable.go @@ -0,0 +1,9 @@ +package models + +// Printable represents a set of fields and values to be printed +type Printable struct { + HostFields []string + DomainFields []string + HostValues []string + DomainValues map[string][]string +} diff --git a/models/printer.go b/models/printer.go new file mode 100644 index 0000000..0c38e60 --- /dev/null +++ b/models/printer.go @@ -0,0 +1,8 @@ +package models + +// Printer defines a printer for output +type Printer interface { + Open() + Screen(Printable) + Close() +} diff --git a/runners/collect.go b/runners/collect.go index ad3da54..e28edab 100644 --- a/runners/collect.go +++ b/runners/collect.go @@ -10,7 +10,7 @@ import ( func InitializeCollect(wg *sync.WaitGroup) { for { // wait with execution for lookup routine - _, ok := <-lookupDone + _, ok := <-initialLookupDone if !ok { wg.Done() return @@ -28,8 +28,7 @@ func Collect() { }*/ // run collectors - models.Collection.Collectors.Map.Range(func(_, collectorRaw interface{}) bool { - collector := collectorRaw.(models.Collector) + models.Collection.Collectors.Range(func(_ interface{}, collector models.Collector) bool { go collector.Collect() return true }) diff --git a/runners/lookup.go b/runners/lookup.go index 809c23f..3066b0d 100644 --- a/runners/lookup.go +++ b/runners/lookup.go @@ -14,16 +14,16 @@ import ( ) var processes []int -var lookupDone chan bool + // InitializeLookup starts the periodic lookup calls func InitializeLookup(wg *sync.WaitGroup) { - lookupDone = make(chan bool) + for n := -1; config.Options.Runs == -1 || n < config.Options.Runs; n++ { // execution, then sleep start := time.Now() Lookup() - lookupDone <- true + initialLookupDone <- true freq := float32(config.Options.Frequency) if n <= 1 { // first run, half frequency only @@ -32,7 +32,7 @@ func InitializeLookup(wg *sync.WaitGroup) { nextRun := start.Add(time.Duration(freq) * time.Second) time.Sleep(nextRun.Sub(time.Now())) } - close(lookupDone) + close(initialLookupDone) wg.Done() } @@ -48,7 +48,7 @@ func Lookup() { // create list of cached domains domIDs := make([]string, 0, models.Collection.Domains.Length()) - models.Collection.Domains.Map.Range(func(key, _ interface{}) bool { + models.Collection.Domains.Range(func(key, _ interface{}) bool { domIDs = append(domIDs, key.(string)) return true }) @@ -68,12 +68,11 @@ func Lookup() { // remove cached but not existent domains for _, id := range domIDs { - models.Collection.Domains.Map.Delete(id) + models.Collection.Domains.Delete(id) } // call collector lookup functions - models.Collection.Collectors.Map.Range(func(_, collectorRaw interface{}) bool { - collector := collectorRaw.(models.Collector) + models.Collection.Collectors.Range(func(_ interface{}, collector models.Collector) bool { collector.Lookup() return true }) @@ -98,9 +97,9 @@ func handleDomain(dom libvirt.Domain) (models.Domain, error) { domain.Name = name } else { domain = models.Domain{ + Measurable: models.NewMeasurable(), UUID: string(uuid), Name: name, - Measurable: &models.Measurable{}, } } diff --git a/runners/printer.go b/runners/printer.go index 8d36332..f00cb13 100644 --- a/runners/printer.go +++ b/runners/printer.go @@ -16,7 +16,7 @@ func InitializePrinter(wg *sync.WaitGroup) { models.Collection.Printer.Open() // define collectors and their order - models.Collection.Collectors.Map.Range(func(key, collectorRaw interface{}) bool { + models.Collection.Collectors.Range(func(key interface{}, collector models.Collector) bool { collectorName := key.(string) collectors = append(collectors, collectorName) return true @@ -46,7 +46,7 @@ func Print() { // add general domain fields first printable.DomainFields = []string{"UUID", "name"} printable.DomainValues = make(map[string][]string) - models.Collection.Domains.Map.Range(func(key, value interface{}) bool { + models.Collection.Domains.Range(func(key, value interface{}) bool { uuid := key.(string) domain := value.(models.Domain) printable.DomainValues[uuid] = []string{ @@ -57,7 +57,7 @@ func Print() { }) // collect fields for each collector and merge together - for _, collectorName := range collectors { // BUG: concurrent map iteration and map write + for _, collectorName := range collectors { collector, ok := models.Collection.Collectors.Load(collectorName) if !ok { continue diff --git a/runners/runners.go b/runners/runners.go index 3d2101e..b64e3b8 100644 --- a/runners/runners.go +++ b/runners/runners.go @@ -4,11 +4,15 @@ import ( "sync" ) +var initialLookupDone chan bool + // InitializeRunners starts necessary runners as threads func InitializeRunners() { var wg sync.WaitGroup wg.Add(3) // terminate when all threads terminate + initialLookupDone = make(chan bool, 1) + go InitializeLookup(&wg) go InitializeCollect(&wg) go InitializePrinter(&wg)