Commit 7c59d398 authored by Miek Gieben's avatar Miek Gieben Committed by GitHub

middleware/metrics: survive restart (#542)

* middleware/metrics: survive restart

Keep the handler running during restart. Stopping and starting the
handler results in "address in use" - sometimes, meaning the reload
will be flaky. In turn this behavior means any changes to the monitor
stanza are not picked up.

* remove resync
parent 26242cef
...@@ -27,6 +27,7 @@ Extra labels used are: ...@@ -27,6 +27,7 @@ Extra labels used are:
If monitoring is enabled, queries that do not enter the middleware chain are exported under the fake If monitoring is enabled, queries that do not enter the middleware chain are exported under the fake
name "dropped" (without a closing dot - this is never a valid domain name). name "dropped" (without a closing dot - this is never a valid domain name).
## Syntax ## Syntax
~~~ ~~~
...@@ -45,3 +46,8 @@ Use an alternative address: ...@@ -45,3 +46,8 @@ Use an alternative address:
~~~ ~~~
prometheus localhost:9253 prometheus localhost:9253
~~~ ~~~
# Bugs
When reloading, we keep the handler running, meaning that any changes to the handler aren't picked
up. You'll need to restart CoreDNS for that to happen.
...@@ -13,13 +13,23 @@ import ( ...@@ -13,13 +13,23 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
func init() {
prometheus.MustRegister(vars.RequestCount)
prometheus.MustRegister(vars.RequestDuration)
prometheus.MustRegister(vars.RequestSize)
prometheus.MustRegister(vars.RequestDo)
prometheus.MustRegister(vars.RequestType)
prometheus.MustRegister(vars.ResponseSize)
prometheus.MustRegister(vars.ResponseRcode)
}
// Metrics holds the prometheus configuration. The metrics' path is fixed to be /metrics // Metrics holds the prometheus configuration. The metrics' path is fixed to be /metrics
type Metrics struct { type Metrics struct {
Next middleware.Handler Next middleware.Handler
Addr string Addr string
ln net.Listener ln net.Listener
mux *http.ServeMux mux *http.ServeMux
Once sync.Once
zoneNames []string zoneNames []string
zoneMap map[string]bool zoneMap map[string]bool
...@@ -52,38 +62,25 @@ func (m *Metrics) ZoneNames() []string { ...@@ -52,38 +62,25 @@ func (m *Metrics) ZoneNames() []string {
// OnStartup sets up the metrics on startup. // OnStartup sets up the metrics on startup.
func (m *Metrics) OnStartup() error { func (m *Metrics) OnStartup() error {
m.Once.Do(func() { ln, err := net.Listen("tcp", m.Addr)
if err != nil {
ln, err := net.Listen("tcp", m.Addr) log.Printf("[ERROR] Failed to start metrics handler: %s", err)
if err != nil { return err
log.Printf("[ERROR] Failed to start metrics handler: %s", err) }
return
}
m.ln = ln
ListenAddr = m.ln.Addr().String()
m.mux = http.NewServeMux()
prometheus.MustRegister(vars.RequestCount)
prometheus.MustRegister(vars.RequestDuration)
prometheus.MustRegister(vars.RequestSize)
prometheus.MustRegister(vars.RequestDo)
prometheus.MustRegister(vars.RequestType)
prometheus.MustRegister(vars.ResponseSize) m.ln = ln
prometheus.MustRegister(vars.ResponseRcode) ListenAddr = m.ln.Addr().String()
m.mux.Handle("/metrics", prometheus.Handler()) m.mux = http.NewServeMux()
m.mux.Handle("/metrics", prometheus.Handler())
go func() { go func() {
http.Serve(m.ln, m.mux) http.Serve(m.ln, m.mux)
}() }()
})
return nil return nil
} }
// OnShutdown tears down the metrics on shutdown. // OnShutdown tears down the metrics on shutdown and restart.
func (m *Metrics) OnShutdown() error { func (m *Metrics) OnShutdown() error {
if m.ln != nil { if m.ln != nil {
return m.ln.Close() return m.ln.Close()
......
...@@ -28,9 +28,10 @@ func setup(c *caddy.Controller) error { ...@@ -28,9 +28,10 @@ func setup(c *caddy.Controller) error {
return m return m
}) })
// During restarts we will keep this handler running.
metricsOnce.Do(func() { metricsOnce.Do(func() {
c.OnStartup(m.OnStartup) c.OncePerServerBlock(m.OnStartup)
c.OnShutdown(m.OnShutdown) c.OnFinalShutdown(m.OnShutdown)
}) })
return nil return nil
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment