A health middleware

Start http handler on port 8080 and return OK. Also add some

documentation fixes for the prometheus middleware.
This commit is contained in:
Miek Gieben
2016-04-06 09:21:46 +01:00
parent ecb53addd6
commit 68171c7a63
7 changed files with 103 additions and 8 deletions

View File

@@ -45,6 +45,7 @@ var directiveOrder = []directive{
{"root", setup.Root}, {"root", setup.Root},
{"bind", setup.BindHost}, {"bind", setup.BindHost},
{"tls", https.Setup}, {"tls", https.Setup},
{"health", setup.Health},
// Other directives that don't create HTTP handlers // Other directives that don't create HTTP handlers
{"startup", setup.Startup}, {"startup", setup.Startup},

33
core/setup/health.go Normal file
View File

@@ -0,0 +1,33 @@
package setup
import (
"github.com/miekg/coredns/middleware"
"github.com/miekg/coredns/middleware/health"
)
func Health(c *Controller) (middleware.Middleware, error) {
addr, err := parseHealth(c)
if err != nil {
return nil, err
}
h := health.Health{Addr: addr}
c.Startup = append(c.Startup, h.ListenAndServe)
return nil, nil
}
func parseHealth(c *Controller) (string, error) {
addr := ""
for c.Next() {
args := c.RemainingArgs()
switch len(args) {
case 0:
case 1:
addr = args[0]
default:
return "", c.ArgErr()
}
}
return addr, nil
}

View File

@@ -9,7 +9,7 @@ import (
const ( const (
path = "/metrics" path = "/metrics"
addr = "localhost:9135" // 9153 is occopied by bind_exporter addr = "localhost:9135" // 9153 is occupied by bind_exporter
) )
var once sync.Once var once sync.Once

View File

@@ -0,0 +1,21 @@
# health
This module enables a simple health check.
By default it will listen on port 9180.
Restarting CoreDNS will stop the health checking. This is a bug. Also [this upstream
Caddy bug](https://github.com/mholt/caddy/issues/675).
## Syntax
~~~
health
~~~
It optionally takes an address, the default is `:8080`. The health path is fixed to `/health`. It
will just return "OK", when CoreDNS is healthy.
This middleware only needs to be enabled once.
## Examples

View File

@@ -0,0 +1,38 @@
package health
import (
"io"
"log"
"net/http"
"sync"
)
var once sync.Once
type Health struct {
Addr string
}
func health(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, ok)
}
func (h Health) ListenAndServe() error {
if h.Addr == "" {
h.Addr = defAddr
}
once.Do(func() {
http.HandleFunc("/health", health)
go func() {
if err := http.ListenAndServe(h.Addr, nil); err != nil {
log.Printf("[ERROR] Failed to start health handler: %s", err)
}
}()
})
return nil
}
const (
ok = "OK"
defAddr = ":8080"
)

View File

@@ -9,9 +9,10 @@ The following metrics are exported:
* coredns_dns_response_size_bytes * coredns_dns_response_size_bytes
* coredns_dns_response_rcode_count_total * coredns_dns_response_rcode_count_total
Each counter has a label `zone` which is the zonename used for the request/response. Each counter has a label `zone` which is the zonename used for the request/response,
The `request_count` metrics has an extra label `qtype` which holds the qtype. And and a label `qtype` which old the query type.
`rcode_count` has an extra label which has the rcode. The `response_rcode_count_total` has an extra label `rcode` which holds the rcode
of the response.
Restarting CoreDNS will stop the monitoring. This is a bug. Also [this upstream Restarting CoreDNS will stop the monitoring. This is a bug. Also [this upstream
Caddy bug](https://github.com/mholt/caddy/issues/675). Caddy bug](https://github.com/mholt/caddy/issues/675).
@@ -25,6 +26,6 @@ prometheus
For each zone that you want to see metrics for. For each zone that you want to see metrics for.
It optionally takes an address where the metrics are exported, the default It optionally takes an address where the metrics are exported, the default
is `localhost:9154`. The metrics path is fixed to `/metrics`. is `localhost:9135`. The metrics path is fixed to `/metrics`.
## Examples ## Examples

View File

@@ -1,7 +1,7 @@
package metrics package metrics
import ( import (
"fmt" "log"
"net/http" "net/http"
"sync" "sync"
@@ -39,8 +39,9 @@ func (m *Metrics) Start() error {
http.Handle(path, prometheus.Handler()) http.Handle(path, prometheus.Handler())
go func() { go func() {
// TODO(miek): Logging here? if err := http.ListenAndServe(m.Addr, nil); err != nil {
fmt.Errorf("%s", http.ListenAndServe(m.Addr, nil)) log.Printf("[ERROR] Failed to start prometheus handler: %s", err)
}
}() }()
}) })
return nil return nil