Commit 68171c7a authored by Miek Gieben's avatar Miek Gieben

A health middleware

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

documentation fixes for the prometheus middleware.
parent ecb53add
...@@ -45,6 +45,7 @@ var directiveOrder = []directive{ ...@@ -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},
......
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
}
...@@ -9,7 +9,7 @@ import ( ...@@ -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
......
# 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
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"
)
...@@ -9,9 +9,10 @@ The following metrics are exported: ...@@ -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 ...@@ -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
package metrics package metrics
import ( import (
"fmt" "log"
"net/http" "net/http"
"sync" "sync"
...@@ -39,8 +39,9 @@ func (m *Metrics) Start() error { ...@@ -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
......
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