| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | package metrics | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-04-06 09:21:46 +01:00
										 |  |  | 	"log" | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"sync" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/miekg/coredns/middleware" | 
					
						
							|  |  |  | 	"github.com/prometheus/client_golang/prometheus" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-03 09:15:55 +01:00
										 |  |  | const namespace = "coredns" | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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() { | 
					
						
							| 
									
										
										
										
											2016-04-06 09:21:46 +01:00
										 |  |  | 			if err := http.ListenAndServe(m.Addr, nil); err != nil { | 
					
						
							|  |  |  | 				log.Printf("[ERROR] Failed to start prometheus handler: %s", err) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | 		}() | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func define(subsystem string) { | 
					
						
							|  |  |  | 	if subsystem == "" { | 
					
						
							|  |  |  | 		subsystem = "dns" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	requestCount = prometheus.NewCounterVec(prometheus.CounterOpts{ | 
					
						
							|  |  |  | 		Namespace: namespace, | 
					
						
							|  |  |  | 		Subsystem: subsystem, | 
					
						
							|  |  |  | 		Name:      "request_count_total", | 
					
						
							| 
									
										
										
										
											2016-04-09 17:42:31 +01:00
										 |  |  | 		Help:      "Counter of DNS requests made per zone and protocol.", | 
					
						
							|  |  |  | 	}, []string{"zone", "proto"}) | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	requestDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ | 
					
						
							|  |  |  | 		Namespace: namespace, | 
					
						
							|  |  |  | 		Subsystem: subsystem, | 
					
						
							|  |  |  | 		Name:      "request_duration_seconds", | 
					
						
							| 
									
										
										
										
											2016-04-06 13:42:56 +01:00
										 |  |  | 		Buckets:   append([]float64{.0001, .0005, .001, .0025}, prometheus.DefBuckets...), | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | 		Help:      "Histogram of the time (in seconds) each request took.", | 
					
						
							| 
									
										
										
										
											2016-04-09 17:42:31 +01:00
										 |  |  | 	}, []string{"zone"}) | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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}, | 
					
						
							| 
									
										
										
										
											2016-04-09 17:42:31 +01:00
										 |  |  | 	}, []string{"zone"}) | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	responseRcode = prometheus.NewCounterVec(prometheus.CounterOpts{ | 
					
						
							|  |  |  | 		Namespace: namespace, | 
					
						
							|  |  |  | 		Subsystem: subsystem, | 
					
						
							| 
									
										
										
										
											2016-04-03 09:15:55 +01:00
										 |  |  | 		Name:      "response_rcode_count_total", | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | 		Help:      "Counter of response status codes.", | 
					
						
							| 
									
										
										
										
											2016-04-09 17:42:31 +01:00
										 |  |  | 	}, []string{"zone", "rcode"}) | 
					
						
							| 
									
										
										
										
											2016-03-18 20:57:35 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-09 16:17:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // 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" |