SebastianCzoch/lxc-exporter

View on GitHub
service/service.go

Summary

Maintainability
A
0 mins
Test Coverage
package service

import (
    "net/http"
    "sync"
    "time"

    "github.com/SebastianCzoch/lxc-exporter/collector"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/common/log"
)

var (
    collectors          = make(map[string]collector.Collector)
    collectorLabelNames = []string{"collector", "result"}

    scrapeDurations = prometheus.NewSummaryVec(
        prometheus.SummaryOpts{
            Namespace: collector.Namespace,
            Subsystem: "exporter",
            Name:      "scrape_duration_seconds",
            Help:      "lxc_exporter: Duration of a scrape job.",
        },
        collectorLabelNames,
    )
)

// LXCCollector implements the prometheus.Collector interface.
type LXCCollector struct {
    collectors map[string]collector.Collector
}

// StartServer is a method which starts HTTP server
func StartServer(addr *string) {
    http.Handle("/metrics", prometheus.Handler())
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte(`<html>
            <head><title>LXC Exporter</title></head>
            <body>
            <h1>LXC Exporter</h1>
            <p><a href="/metrics">Metrics</a></p>
            </body>
            </html>`))
    })

    if err := http.ListenAndServe(*addr, nil); err != nil {
        log.Fatalf("Error starting HTTP server: %s", err)
    }
}

// StartColectors is a function which load all available containers
func StartColectors() {
    loadCollectors()
    for name, c := range collectors {
        err := c.Init()
        if err != nil {
            delete(collectors, name)
            log.Errorf("collector %s disabled, because: %s", name, err.Error())
        }
    }

    prometheus.MustRegister(LXCCollector{collectors: collectors})
}

// Describe implements the prometheus.Collector interface.
func (n LXCCollector) Describe(ch chan<- *prometheus.Desc) {
    scrapeDurations.Describe(ch)
}

// Collect implements the prometheus.Collector interface.
func (n LXCCollector) Collect(ch chan<- prometheus.Metric) {
    wg := sync.WaitGroup{}
    wg.Add(len(n.collectors))
    for name, c := range n.collectors {
        go func(name string, c collector.Collector) {
            execute(name, c, ch)
            wg.Done()
        }(name, c)
    }
    wg.Wait()
    scrapeDurations.Collect(ch)
}

func execute(name string, c collector.Collector, ch chan<- prometheus.Metric) {
    begin := time.Now()
    err := c.Update(ch)
    duration := time.Since(begin)

    if err != nil {
        log.Errorf("ERROR: %s collector failed after %fs: %s", name, duration.Seconds(), err)
        scrapeDurations.WithLabelValues(name, "error").Observe(duration.Seconds())
        return
    }

    scrapeDurations.WithLabelValues(name, "success").Observe(duration.Seconds())
}

func loadCollectors() {
    collectors["lxc_cpu"] = collector.NewCPUStatCollector()
    collectors["lxc_mem"] = collector.NewMemStatCollector()
}