diff options
Diffstat (limited to 'middleware/metrics/metrics.go')
-rw-r--r-- | middleware/metrics/metrics.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/middleware/metrics/metrics.go b/middleware/metrics/metrics.go new file mode 100644 index 000000000..7a3c46f2e --- /dev/null +++ b/middleware/metrics/metrics.go @@ -0,0 +1,86 @@ +package metrics + +import ( + "log" + "net/http" + "sync" + + "github.com/miekg/coredns/middleware" + "github.com/prometheus/client_golang/prometheus" +) + +const namespace = "coredns" + +var ( + requestCount *prometheus.CounterVec + requestDuration *prometheus.HistogramVec + responseSize *prometheus.HistogramVec + responseRcode *prometheus.CounterVec +) + +const path = "/metrics" + +// Metrics holds the prometheus configuration. The metrics' path is fixed to be /metrics +type Metrics struct { + Next middleware.Handler + Addr string // where to we listen + Once sync.Once + ZoneNames []string +} + +func (m *Metrics) Start() error { + m.Once.Do(func() { + define("") + + prometheus.MustRegister(requestCount) + prometheus.MustRegister(requestDuration) + prometheus.MustRegister(responseSize) + prometheus.MustRegister(responseRcode) + + http.Handle(path, prometheus.Handler()) + go func() { + if err := http.ListenAndServe(m.Addr, nil); err != nil { + log.Printf("[ERROR] Failed to start prometheus handler: %s", err) + } + }() + }) + return nil +} + +func define(subsystem string) { + if subsystem == "" { + subsystem = "dns" + } + requestCount = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_count_total", + Help: "Counter of DNS requests made per zone and type and opcode.", + }, []string{"zone", "qtype"}) + + requestDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "request_duration_seconds", + Buckets: append([]float64{.0001, .0005, .001, .0025}, prometheus.DefBuckets...), + Help: "Histogram of the time (in seconds) each request took.", + }, []string{"zone", "qtype"}) + + responseSize = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "response_size_bytes", + Help: "Size of the returns response in bytes.", + Buckets: []float64{0, 100, 200, 300, 400, 511, 1023, 2047, 4095, 8291, 16e3, 32e3, 48e3, 64e3}, + }, []string{"zone", "qtype"}) + + responseRcode = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "response_rcode_count_total", + Help: "Counter of response status codes.", + }, []string{"zone", "rcode", "qtype"}) +} + +// Dropped indicates we dropped the query before any handling. It has no closing dot, so it can not be a valid zone. +const Dropped = "dropped" |