mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 02:03:20 -04:00 
			
		
		
		
	plugin/health: Poll localhost by default (#5934)
defaulting to localhost makes things explicit in CoreDNS code, and will give us valid URIs in the logs Signed-off-by: W. Trevor King <wking@tremily.us>
This commit is contained in:
		| @@ -6,6 +6,7 @@ import ( | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"time" | ||||
|  | ||||
| 	clog "github.com/coredns/coredns/plugin/pkg/log" | ||||
| @@ -16,8 +17,9 @@ var log = clog.NewWithPlugin("health") | ||||
|  | ||||
| // Health implements healthchecks by exporting a HTTP endpoint. | ||||
| type health struct { | ||||
| 	Addr     string | ||||
| 	lameduck time.Duration | ||||
| 	Addr      string | ||||
| 	lameduck  time.Duration | ||||
| 	healthURI *url.URL | ||||
|  | ||||
| 	ln      net.Listener | ||||
| 	nlSetup bool | ||||
| @@ -30,6 +32,19 @@ func (h *health) OnStartup() error { | ||||
| 	if h.Addr == "" { | ||||
| 		h.Addr = ":8080" | ||||
| 	} | ||||
|  | ||||
| 	var err error | ||||
| 	h.healthURI, err = url.Parse("http://" + h.Addr) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	h.healthURI.Path = "/health" | ||||
| 	if h.healthURI.Host == "" { | ||||
| 		// while we can listen on multiple network interfaces, we need to pick one to poll | ||||
| 		h.healthURI.Host = "localhost" | ||||
| 	} | ||||
|  | ||||
| 	ln, err := reuseport.Listen("tcp", h.Addr) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| @@ -39,7 +54,7 @@ func (h *health) OnStartup() error { | ||||
| 	h.mux = http.NewServeMux() | ||||
| 	h.nlSetup = true | ||||
|  | ||||
| 	h.mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { | ||||
| 	h.mux.HandleFunc(h.healthURI.Path, func(w http.ResponseWriter, r *http.Request) { | ||||
| 		// We're always healthy. | ||||
| 		w.WriteHeader(http.StatusOK) | ||||
| 		io.WriteString(w, http.StatusText(http.StatusOK)) | ||||
|   | ||||
| @@ -32,8 +32,7 @@ func (h *health) overloaded(ctx context.Context) { | ||||
| 		Transport: bypassProxy, | ||||
| 	} | ||||
|  | ||||
| 	url := "http://" + h.Addr + "/health" | ||||
| 	req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) | ||||
| 	req, _ := http.NewRequestWithContext(ctx, http.MethodGet, h.healthURI.String(), nil) | ||||
| 	tick := time.NewTicker(1 * time.Second) | ||||
| 	defer tick.Stop() | ||||
|  | ||||
| @@ -49,14 +48,14 @@ func (h *health) overloaded(ctx context.Context) { | ||||
| 			if err != nil { | ||||
| 				HealthDuration.Observe(time.Since(start).Seconds()) | ||||
| 				HealthFailures.Inc() | ||||
| 				log.Warningf("Local health request to %q failed: %s", url, err) | ||||
| 				log.Warningf("Local health request to %q failed: %s", req.URL.String(), err) | ||||
| 				continue | ||||
| 			} | ||||
| 			resp.Body.Close() | ||||
| 			elapsed := time.Since(start) | ||||
| 			HealthDuration.Observe(elapsed.Seconds()) | ||||
| 			if elapsed > time.Second { // 1s is pretty random, but a *local* scrape taking that long isn't good | ||||
| 				log.Warningf("Local health request to %q took more than 1s: %s", url, elapsed) | ||||
| 				log.Warningf("Local health request to %q took more than 1s: %s", req.URL.String(), elapsed) | ||||
| 			} | ||||
|  | ||||
| 		case <-ctx.Done(): | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import ( | ||||
| 	"context" | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"net/url" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
| @@ -22,6 +23,13 @@ func Test_health_overloaded_cancellation(t *testing.T) { | ||||
| 		stop: cancel, | ||||
| 	} | ||||
|  | ||||
| 	var err error | ||||
| 	h.healthURI, err = url.Parse(ts.URL) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	h.healthURI.Path = "/health" | ||||
|  | ||||
| 	stopped := make(chan struct{}) | ||||
| 	go func() { | ||||
| 		h.overloaded(ctx) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user