From 38b28b7a1eefe30a15fa140d254e1f74c8cd3f28 Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Mon, 27 Mar 2017 22:20:39 +0200 Subject: [PATCH] Added basic prometheus export for global fastd statistics --- fastd-exporter.go | 104 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 20 deletions(-) diff --git a/fastd-exporter.go b/fastd-exporter.go index 4921831..5b6f676 100644 --- a/fastd-exporter.go +++ b/fastd-exporter.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "errors" "flag" "fmt" "io/ioutil" @@ -9,12 +10,11 @@ import ( "net" "net/http" "regexp" - "strings" "time" - "errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" + "strings" ) var ( @@ -38,7 +38,7 @@ type Statistics struct { } type Message struct { - Uptime float64 `json:"uptime"` + Uptime float64 `json:"uptime"` Interface string `json:"interface"` Statistics Statistics `json:"statistics"` Peers map[string]Peer `json:"peers"` @@ -55,16 +55,85 @@ type Peer struct { MAC []string `json:"mac_addresses"` } - func init() { // register metrics } -func Update(sock string) { - data := data_from_sock(sock) +type PrometheusExporter struct { + SocketName string + + uptime *prometheus.Desc + + rxPackets *prometheus.Desc + rxBytes *prometheus.Desc + + rxReorderedPackets *prometheus.Desc + rxReorderedBytes *prometheus.Desc + + txPackets *prometheus.Desc + txBytes *prometheus.Desc + + txDroppedPackets *prometheus.Desc + txDroppedBytes *prometheus.Desc + + txErrorPackets *prometheus.Desc + txErrorBytes *prometheus.Desc +} + + +func c(parts... string) string { + parts = append([]string{"fastd"}, parts...) + return strings.Join(parts, "_") +} + +func NewPrometheusExporter(instanceName string, sockName string) PrometheusExporter { + + l := prometheus.Labels{"fastd_instance": instanceName} + + return PrometheusExporter{ + SocketName: sockName, + uptime: prometheus.NewDesc(c(instanceName ,"uptime"), "uptime of the prometheus exporter", nil, l), + + rxPackets: prometheus.NewDesc(c("rx_packets"), "rx packet count", nil, l), + rxBytes: prometheus.NewDesc(c("rx_bytes"), "rx byte count", nil, l), + rxReorderedPackets: prometheus.NewDesc(c("rx_reordered_packets"), "rx reordered packets", nil, l), + rxReorderedBytes: prometheus.NewDesc(c("rx_reordered_bytes"), "rx reordered packets", nil, l), + + txPackets: prometheus.NewDesc(c("tx_packets"), "tx packet count", nil, l), + txBytes: prometheus.NewDesc(c("tx_bytes"), "tx byte count", nil, l), + txDroppedPackets: prometheus.NewDesc(c("tx_dropped_packets"), "tx dropped packets", nil, l), + txDroppedBytes: prometheus.NewDesc(c("tx_dropped_bytes"), "tx dropped packets", nil, l), + } +} + +func (e PrometheusExporter) Describe(c chan<- *prometheus.Desc) { + c <- e.uptime + + c <- e.rxPackets + c <- e.rxBytes + c <- e.rxReorderedPackets + c <- e.rxReorderedBytes + c <- e.txPackets + c <- e.txBytes + c <- e.txDroppedPackets + c <- e.txDroppedBytes +} + +func (e PrometheusExporter) Collect(c chan<- prometheus.Metric) { + data := data_from_sock(e.SocketName) + + c <- prometheus.MustNewConstMetric(e.uptime, prometheus.GaugeValue, data.Uptime) + + c <- prometheus.MustNewConstMetric(e.rxPackets, prometheus.CounterValue, float64(data.Statistics.RX.Count)) + c <- prometheus.MustNewConstMetric(e.rxBytes, prometheus.CounterValue, float64(data.Statistics.RX.Bytes)) + c <- prometheus.MustNewConstMetric(e.rxReorderedPackets, prometheus.CounterValue, float64(data.Statistics.RX_Reordered.Count)) + c <- prometheus.MustNewConstMetric(e.rxReorderedBytes, prometheus.CounterValue, float64(data.Statistics.RX_Reordered.Bytes)) + + c <- prometheus.MustNewConstMetric(e.txPackets, prometheus.CounterValue, float64(data.Statistics.TX.Count)) + c <- prometheus.MustNewConstMetric(e.txBytes, prometheus.CounterValue, float64(data.Statistics.TX.Bytes)) + c <- prometheus.MustNewConstMetric(e.txDroppedPackets, prometheus.CounterValue, float64(data.Statistics.TX.Count)) + c <- prometheus.MustNewConstMetric(e.txDroppedBytes, prometheus.CounterValue, float64(data.Statistics.TX_Dropped.Bytes)) - // TODO: continue here mapping json data to metrics - // prometheus.MustNewConstMetric(, , data.Uptime) } func data_from_sock(sock string) Message { @@ -113,19 +182,14 @@ func main() { log.Fatal("No instance given, exiting.") } - instances := strings.Split(*instances, ",") - for i := 0; i < len(instances); i++ { - sock, err := sock_from_instance(instances[i]) - if err != nil { - log.Fatal(err) - } - go func() { - for { - Update(sock) - time.Sleep(time.Duration(15 * time.Second)) - } - }() + sock, err := sock_from_instance(*instances) + if err != nil { + log.Fatal(err) } + log.Printf("Reading fastd data from %v", sock) + exp := NewPrometheusExporter(*instances, sock) + + prometheus.MustRegister(exp) // Expose the registered metrics via HTTP. http.Handle("/metrics", promhttp.Handler())