Skip to content

Commit

Permalink
middleware/metrics: survive restart (#542)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
miekg committed Feb 21, 2017
1 parent 26242ce commit 7c59d39
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 29 deletions.
6 changes: 6 additions & 0 deletions middleware/metrics/README.md
Expand Up @@ -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
name "dropped" (without a closing dot - this is never a valid domain name).


## Syntax

~~~
Expand All @@ -45,3 +46,8 @@ Use an alternative address:
~~~
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.
51 changes: 24 additions & 27 deletions middleware/metrics/metrics.go
Expand Up @@ -13,13 +13,23 @@ import (
"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
type Metrics struct {
Next middleware.Handler
Addr string
ln net.Listener
mux *http.ServeMux
Once sync.Once

zoneNames []string
zoneMap map[string]bool
Expand Down Expand Up @@ -52,38 +62,25 @@ func (m *Metrics) ZoneNames() []string {

// OnStartup sets up the metrics on startup.
func (m *Metrics) OnStartup() error {
m.Once.Do(func() {

ln, err := net.Listen("tcp", m.Addr)
if err != nil {
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)
ln, err := net.Listen("tcp", m.Addr)
if err != nil {
log.Printf("[ERROR] Failed to start metrics handler: %s", err)
return err
}

prometheus.MustRegister(vars.ResponseSize)
prometheus.MustRegister(vars.ResponseRcode)
m.ln = ln
ListenAddr = m.ln.Addr().String()

m.mux.Handle("/metrics", prometheus.Handler())
m.mux = http.NewServeMux()
m.mux.Handle("/metrics", prometheus.Handler())

go func() {
http.Serve(m.ln, m.mux)
}()
})
go func() {
http.Serve(m.ln, m.mux)
}()
return nil
}

// OnShutdown tears down the metrics on shutdown.
// OnShutdown tears down the metrics on shutdown and restart.
func (m *Metrics) OnShutdown() error {
if m.ln != nil {
return m.ln.Close()
Expand Down
5 changes: 3 additions & 2 deletions middleware/metrics/setup.go
Expand Up @@ -28,9 +28,10 @@ func setup(c *caddy.Controller) error {
return m
})

// During restarts we will keep this handler running.
metricsOnce.Do(func() {
c.OnStartup(m.OnStartup)
c.OnShutdown(m.OnShutdown)
c.OncePerServerBlock(m.OnStartup)
c.OnFinalShutdown(m.OnShutdown)
})

return nil
Expand Down

0 comments on commit 7c59d39

Please sign in to comment.