diff --git a/cmd/gqgmcd/main.go b/cmd/gqgmcd/main.go index 0e2d09a6edaf2829fce4df61da08bfe71b7901a7..0ab09850a09b216d0f4f07293f327d30f3e60af0 100644 --- a/cmd/gqgmcd/main.go +++ b/cmd/gqgmcd/main.go @@ -13,7 +13,9 @@ import ( "log" "net/http" "path" + "time" + "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "gitlab.com/lyda/gqgmc/devices/geiger" ) @@ -30,6 +32,7 @@ type indexPage struct { Serial string Volts int16 CPM uint16 + CPS uint16 } var gc geiger.Counter @@ -50,18 +53,98 @@ func staticHandler(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, staticFile) } +// Metrics collects the metrics. +type Metrics struct { + CPM, + CPS, + Volts, + Errors *prometheus.HistogramVec +} + +var metrics = &Metrics{ + CPM: prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "gqgmc", + Subsystem: "geiger", + Name: "cpm", + Help: "CPM readings", + Buckets: []float64{50, 99, 999, 1999}, + }, []string{"serial"}), + CPS: prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "gqgmc", + Subsystem: "geiger", + Name: "cps", + Help: "CPS readings", + Buckets: []float64{1, 2, 16, 33}, + }, []string{"serial"}), + Volts: prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "gqgmc", + Subsystem: "power", + Name: "volts", + Help: "Voltage readings", + Buckets: []float64{22, 27, 42, 50}, + }, []string{"serial"}), + Errors: prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: "gqgmc", + Subsystem: "sys", + Name: "errors", + Help: "Error counts", + Buckets: []float64{1, 10, 100}, + }, []string{"serial"}), +} + +func gatherMetrics() { + var ( + cpm, cps uint16 + volts int16 + errCt float64 + err error + ) + + for { + if cpm, err = gc.GetCPM(); err != nil { + log.Printf("gc.GetCPM error: %s\n", err) + errCt++ + } else { + metrics.CPM.WithLabelValues(gc.Version()).Observe(float64(cpm)) + } + if cps, err = gc.GetCPS(); err != nil { + log.Printf("gc.GetCPS error: %s\n", err) + errCt++ + } else { + metrics.CPS.WithLabelValues(gc.Version()).Observe(float64(cps)) + } + if volts, err = gc.Volts(); err != nil { + log.Printf("gc.Volts error: %s\n", err) + errCt++ + } else { + metrics.Volts.WithLabelValues(gc.Version()).Observe(float64(volts)) + } + metrics.Errors.WithLabelValues(gc.Version()).Observe(errCt) + time.Sleep(5 * time.Second) + } +} + func main() { flag.Parse() gc, _ = geiger.New(geiger.Config{Model: *model, Device: *device}) + indexPg.Model = gc.Model() indexPg.Version = gc.Version() indexPg.Serial = gc.Serial() + + prometheus.MustRegister(metrics.CPM) + prometheus.MustRegister(metrics.CPS) + prometheus.MustRegister(metrics.Volts) + prometheus.MustRegister(metrics.Errors) + http.HandleFunc("/", indexHandler) http.HandleFunc("/favicon.ico", staticHandler) http.HandleFunc("/robots.txt", staticHandler) http.HandleFunc("/humans.txt", staticHandler) http.Handle("/metrics", promhttp.Handler()) http.Handle("/static", http.StripPrefix("/static/", http.FileServer(http.Dir(*staticDir)))) + + go gatherMetrics() log.Fatal(http.ListenAndServe(*addr, nil)) }