| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | package metrics | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-10-04 11:05:04 +01:00
										 |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-21 22:51:47 -08:00
										 |  |  | 	"github.com/coredns/coredns/core/dnsserver" | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/middleware" | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/mholt/caddy" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init() { | 
					
						
							|  |  |  | 	caddy.RegisterPlugin("prometheus", caddy.Plugin{ | 
					
						
							|  |  |  | 		ServerType: "dns", | 
					
						
							|  |  |  | 		Action:     setup, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2017-04-12 10:10:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	uniqAddr = addrs{a: make(map[string]int)} | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func setup(c *caddy.Controller) error { | 
					
						
							|  |  |  | 	m, err := prometheusParse(c) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-09-10 09:16:25 +01:00
										 |  |  | 		return middleware.Error("prometheus", err) | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-19 11:26:00 +01:00
										 |  |  | 	dnsserver.GetConfig(c).AddMiddleware(func(next middleware.Handler) middleware.Handler { | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 		m.Next = next | 
					
						
							|  |  |  | 		return m | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 10:10:57 +00:00
										 |  |  | 	for a, v := range uniqAddr.a { | 
					
						
							|  |  |  | 		if v == todo { | 
					
						
							|  |  |  | 			// During restarts we will keep this handler running, BUG. | 
					
						
							|  |  |  | 			c.OncePerServerBlock(m.OnStartup) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		uniqAddr.a[a] = done | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	c.OnFinalShutdown(m.OnShutdown) | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 11:05:04 +01:00
										 |  |  | func prometheusParse(c *caddy.Controller) (*Metrics, error) { | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2016-10-28 12:57:10 +01:00
										 |  |  | 		met = &Metrics{Addr: addr, zoneMap: make(map[string]bool)} | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 		err error | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 10:10:57 +00:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		uniqAddr.SetAddress(met.Addr) | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 	for c.Next() { | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 		if len(met.ZoneNames()) > 0 { | 
					
						
							|  |  |  | 			return met, c.Err("can only have one metrics module per server") | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for _, z := range c.ServerBlockKeys { | 
					
						
							|  |  |  | 			met.AddZone(middleware.Host(z).Normalize()) | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		args := c.RemainingArgs() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch len(args) { | 
					
						
							|  |  |  | 		case 0: | 
					
						
							|  |  |  | 		case 1: | 
					
						
							|  |  |  | 			met.Addr = args[0] | 
					
						
							| 
									
										
										
										
											2016-10-04 11:05:04 +01:00
										 |  |  | 			_, _, e := net.SplitHostPort(met.Addr) | 
					
						
							|  |  |  | 			if e != nil { | 
					
						
							|  |  |  | 				return met, e | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2016-10-04 11:05:04 +01:00
										 |  |  | 			return met, c.ArgErr() | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return met, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-12 10:10:57 +00:00
										 |  |  | var uniqAddr addrs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Keep track on which addrs we listen, so we only start one listener. | 
					
						
							|  |  |  | type addrs struct { | 
					
						
							|  |  |  | 	a map[string]int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (a *addrs) SetAddress(addr string) { | 
					
						
							|  |  |  | 	// If already there and set to done, we've already started this listener. | 
					
						
							|  |  |  | 	if a.a[addr] == done { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	a.a[addr] = todo | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-08-19 17:14:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-27 11:48:37 +00:00
										 |  |  | // Addr is the address the where the metrics are exported by default. | 
					
						
							| 
									
										
										
										
											2016-10-28 12:57:10 +01:00
										 |  |  | const addr = "localhost:9153" | 
					
						
							| 
									
										
										
										
											2017-04-12 10:10:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							|  |  |  | 	todo = 1 | 
					
						
							|  |  |  | 	done = 2 | 
					
						
							|  |  |  | ) |