From b3b5157ee16bc1cbe47d550e89f0ee4b8bfcdd61 Mon Sep 17 00:00:00 2001 From: Daniel Czerwonk Date: Mon, 26 Jun 2017 17:40:39 +0200 Subject: [PATCH] added up metrics --- host/host.go | 1 + host/host_collector.go | 35 +++++++++++++++++++++++++++++------ main.go | 2 +- statistic/mertic_retriever.go | 27 +++++++++------------------ vm/vm.go | 1 + vm/vm_collector.go | 34 +++++++++++++++++++++++++++++----- 6 files changed, 70 insertions(+), 30 deletions(-) diff --git a/host/host.go b/host/host.go index 6667829..a0d0f16 100644 --- a/host/host.go +++ b/host/host.go @@ -10,4 +10,5 @@ type Host struct { Cluster struct { Id string `xml:"id,attr"` } `xml:"cluster"` + Status string `xml:"status"` } diff --git a/host/host_collector.go b/host/host_collector.go index 3dd30b4..bd31408 100644 --- a/host/host_collector.go +++ b/host/host_collector.go @@ -10,6 +10,18 @@ import ( "github.com/prometheus/common/log" ) +const prefix = "ovirt_host_" + +var ( + upDesc *prometheus.Desc + labelNames []string +) + +func init() { + labelNames = []string{"name", "cluster"} + upDesc = prometheus.NewDesc(prefix+"up", "Host is running (1) or not (0)", labelNames, nil) +} + // HostCollector collects host statistics from oVirt type HostCollector struct { api *api.ApiClient @@ -21,8 +33,7 @@ type HostCollector struct { // NewCollector creates a new collector func NewCollector(api *api.ApiClient) prometheus.Collector { - l := []string{"cluster"} - r := statistic.NewStatisticMetricRetriever("host", api, l) + r := statistic.NewStatisticMetricRetriever("host", api, labelNames) c := cluster.NewRetriever(api) return &HostCollector{api: api, retriever: r, clusterRetriever: c} } @@ -54,20 +65,32 @@ func (c *HostCollector) getMetrics() []prometheus.Metric { } func (c *HostCollector) retrieveMetrics() { - ressources := make(map[string]string) + ids := make([]string, 0) labelValues := make(map[string][]string) + c.metrics = make([]prometheus.Metric, 0) for _, h := range c.getHosts() { + ids = append(ids, h.Id) cluster, err := c.clusterRetriever.Get(h.Cluster.Id) if err != nil { log.Error(err) } - ressources[h.Id] = h.Name - labelValues[h.Id] = []string{cluster.Name} + labelValues[h.Id] = []string{h.Name, cluster.Name} + + c.metrics = append(c.metrics, c.upMetric(&h, labelValues[h.Id])) + } + + c.metrics = append(c.metrics, c.retriever.RetrieveMetrics(ids, labelValues)...) +} + +func (c *HostCollector) upMetric(h *Host, labelValues []string) prometheus.Metric { + var up float64 + if h.Status == "up" { + up = 1 } - c.metrics = c.retriever.RetrieveMetrics(ressources, labelValues) + return prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, up, labelValues...) } func (c *HostCollector) getHosts() []Host { diff --git a/main.go b/main.go index 31f0e53..6c1a0c4 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ import ( "github.com/prometheus/common/log" ) -const version string = "0.2.0" +const version string = "0.3.0" var ( showVersion = flag.Bool("version", false, "Print version information.") diff --git a/statistic/mertic_retriever.go b/statistic/mertic_retriever.go index e358680..4683ca2 100644 --- a/statistic/mertic_retriever.go +++ b/statistic/mertic_retriever.go @@ -37,15 +37,15 @@ func NewStatisticMetricRetriever(ressource string, api *api.ApiClient, labelName return &StatisticMetricRetriever{ressource: ressource, api: api, labelNames: labelNames} } -func (m *StatisticMetricRetriever) RetrieveMetrics(ressources map[string]string, labelValues map[string][]string) []prometheus.Metric { +func (m *StatisticMetricRetriever) RetrieveMetrics(ids []string, labelValues map[string][]string) []prometheus.Metric { wg := &sync.WaitGroup{} - wg.Add(len(ressources)) + wg.Add(len(ids)) ch := make(chan prometheus.Metric) done := make(chan bool) - for id, name := range ressources { - go m.retrieveMetricsForId(id, name, ch, wg, labelValues) + for _, id := range ids { + go m.retrieveMetricsForId(id, ch, wg, labelValues) } go func() { @@ -65,7 +65,7 @@ func (m *StatisticMetricRetriever) RetrieveMetrics(ressources map[string]string, } } -func (m *StatisticMetricRetriever) retrieveMetricsForId(id string, name string, ch chan<- prometheus.Metric, +func (m *StatisticMetricRetriever) retrieveMetricsForId(id string, ch chan<- prometheus.Metric, wg *sync.WaitGroup, labelValues map[string][]string) { defer wg.Done() @@ -80,12 +80,12 @@ func (m *StatisticMetricRetriever) retrieveMetricsForId(id string, name string, for _, s := range stats.Statistic { if s.Kind == "gauge" { - ch <- m.convertToMetric(id, name, &s, labelValues) + ch <- m.convertToMetric(id, &s, labelValues) } } } -func (m *StatisticMetricRetriever) convertToMetric(id string, name string, s *Statistic, +func (m *StatisticMetricRetriever) convertToMetric(id string, s *Statistic, labelValues map[string][]string) prometheus.Metric { metricName := strings.Replace(s.Name, ".", "_", -1) @@ -94,16 +94,7 @@ func (m *StatisticMetricRetriever) convertToMetric(id string, name string, s *St } n := prometheus.BuildFQName("ovirt", m.ressource, metricName) + d := prometheus.NewDesc(n, s.Description, m.labelNames, nil) - labelNames := append([]string{"name"}, m.labelNames...) - d := prometheus.NewDesc(n, s.Description, labelNames, nil) - - lv := append([]string{name}, labelValues[id]...) - r, err := prometheus.NewConstMetric(d, prometheus.GaugeValue, s.Values.Value.Datum, lv...) - - if err != nil { - log.Errorln(err) - } - - return r + return prometheus.MustNewConstMetric(d, prometheus.GaugeValue, s.Values.Value.Datum, labelValues[id]...) } diff --git a/vm/vm.go b/vm/vm.go index cd4e010..9b73085 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -13,4 +13,5 @@ type Vm struct { Cluster struct { Id string `xml:"id,attr"` } `xml:"cluster,omitempty"` + Status string `xml:"status"` } diff --git a/vm/vm_collector.go b/vm/vm_collector.go index 2d510fb..28a5f54 100644 --- a/vm/vm_collector.go +++ b/vm/vm_collector.go @@ -11,6 +11,18 @@ import ( "github.com/prometheus/common/log" ) +const prefix = "ovirt_vm_" + +var ( + upDesc *prometheus.Desc + labelNames []string +) + +func init() { + labelNames = []string{"name", "host", "cluster"} + upDesc = prometheus.NewDesc(prefix+"up", "VM is running (1) or not (0)", labelNames, nil) +} + // VmCollector collects virtual machine statistics from oVirt type VmCollector struct { api *api.ApiClient @@ -23,7 +35,7 @@ type VmCollector struct { // NewCollector creates a new collector func NewCollector(api *api.ApiClient) prometheus.Collector { - r := statistic.NewStatisticMetricRetriever("vm", api, []string{"host", "cluster"}) + r := statistic.NewStatisticMetricRetriever("vm", api, labelNames) h := host.NewRetriever(api) c := cluster.NewRetriever(api) return &VmCollector{api: api, retriever: r, hostRetriever: h, clusterRetriever: c} @@ -56,15 +68,27 @@ func (c *VmCollector) getMetrics() []prometheus.Metric { } func (c *VmCollector) retrieveMetrics() { - ressources := make(map[string]string) + ids := make([]string, 0) labelValues := make(map[string][]string) + c.metrics = make([]prometheus.Metric, 0) for _, vm := range c.getVms() { - ressources[vm.Id] = vm.Name + ids = append(ids, vm.Id) labelValues[vm.Id] = c.getLabelValues(&vm) + + c.metrics = append(c.metrics, c.upMetric(&vm, labelValues[vm.Id])) + } + + c.metrics = append(c.metrics, c.retriever.RetrieveMetrics(ids, labelValues)...) +} + +func (c *VmCollector) upMetric(vm *Vm, labelValues []string) prometheus.Metric { + var up float64 + if vm.Status == "up" { + up = 1 } - c.metrics = c.retriever.RetrieveMetrics(ressources, labelValues) + return prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, up, labelValues...) } func (c *VmCollector) getLabelValues(vm *Vm) []string { @@ -83,7 +107,7 @@ func (c *VmCollector) getLabelValues(vm *Vm) []string { log.Error(err) } - return []string{h.Name, cl.Name} + return []string{vm.Name, h.Name, cl.Name} } func (c *VmCollector) getVms() []Vm {