diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8a15901 --- /dev/null +++ b/go.mod @@ -0,0 +1,17 @@ +module github.com/krak3n/healthcheck + +go 1.12 + +require ( + github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a + github.com/davecgh/go-spew v1.1.0 + github.com/golang/protobuf v1.0.0 + github.com/matttproud/golang_protobuf_extensions v1.0.0 + github.com/pmezard/go-difflib v1.0.0 + github.com/prometheus/client_golang v0.0.0-20180223144718-c3324c1198cf + github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5 + github.com/prometheus/common v0.0.0-20180228092548-6fb6fce6f8b7 + github.com/prometheus/procfs v0.0.0-20180306113821-7186fbf4eb22 + github.com/stretchr/testify v1.2.1 + gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3eef734 --- /dev/null +++ b/go.sum @@ -0,0 +1,22 @@ +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a h1:BtpsbiV638WQZwhA98cEZw2BsbnQJrbd0BI7tsy0W1c= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.0.0 h1:lsek0oXi8iFE9L+EXARyHIjU5rlWIhhTkjDz3vHhWWQ= +github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/matttproud/golang_protobuf_extensions v1.0.0 h1:YNOwxxSJzSUARoD9KRZLzM9Y858MNGCOACTvCW9TSAc= +github.com/matttproud/golang_protobuf_extensions v1.0.0/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.0.0-20180223144718-c3324c1198cf h1:YtiXRsgYGXlAj+EHLMjLfsk5jrMpY/E3nmhIyUijV4E= +github.com/prometheus/client_golang v0.0.0-20180223144718-c3324c1198cf/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5 h1:cLL6NowurKLMfCeQy4tIeph12XNQWgANCNvdyrOYKV4= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20180228092548-6fb6fce6f8b7 h1:M7FNIWkkGynttTfTsqQSWnhqzNS5ubqaXSJT7oGDfgI= +github.com/prometheus/common v0.0.0-20180228092548-6fb6fce6f8b7/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20180306113821-7186fbf4eb22 h1:jDQlbutSgD69Ul07voXv2yCaFilf4/jjNoUhmOIrR1k= +github.com/prometheus/procfs v0.0.0-20180306113821-7186fbf4eb22/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY= +gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= diff --git a/handler.go b/handler.go index 6ea9740..747fd0d 100644 --- a/handler.go +++ b/handler.go @@ -20,6 +20,35 @@ import ( "sync" ) +// default configuration +var defaultConfig = config{ + LivenessPath: "/live", + ReadinessPath: "/ready", +} + +// handler configuration +type config struct { + LivenessPath string + ReadinessPath string +} + +// A HandlerOption function can configure the healthcheck handler +type HandlerOption func(c *config) + +// WithLivenessPath configures the liveness URL path +func WithLivenessPath(p string) HandlerOption { + return func(c *config) { + c.LivenessPath = p + } +} + +// WithReadinessPath configures the readiness URL path +func WithReadinessPath(p string) HandlerOption { + return func(c *config) { + c.ReadinessPath = p + } +} + // basicHandler is a basic Handler implementation. type basicHandler struct { http.ServeMux @@ -29,13 +58,19 @@ type basicHandler struct { } // NewHandler creates a new basic Handler -func NewHandler() Handler { +func NewHandler(opts ...HandlerOption) Handler { h := &basicHandler{ livenessChecks: make(map[string]Check), readinessChecks: make(map[string]Check), } - h.Handle("/live", http.HandlerFunc(h.LiveEndpoint)) - h.Handle("/ready", http.HandlerFunc(h.ReadyEndpoint)) + + cfg := defaultConfig + for _, opt := range opts { + opt(&cfg) + } + + h.Handle(cfg.LivenessPath, http.HandlerFunc(h.LiveEndpoint)) + h.Handle(cfg.ReadinessPath, http.HandlerFunc(h.ReadyEndpoint)) return h } diff --git a/handler_test.go b/handler_test.go index 2e894b4..757b0da 100644 --- a/handler_test.go +++ b/handler_test.go @@ -28,6 +28,7 @@ func TestNewHandler(t *testing.T) { name string method string path string + opts []HandlerOption live bool ready bool expect int @@ -120,10 +121,33 @@ func TestNewHandler(t *testing.T) { expect: http.StatusServiceUnavailable, expectBody: "{}\n", }, + { + name: "with custom live path should succeed", + method: "GET", + path: "/_live", + opts: []HandlerOption{WithLivenessPath("/_live")}, + live: true, + ready: true, + expect: http.StatusOK, + expectBody: "{}\n", + }, + { + name: "with custom ready path should succeed", + method: "GET", + path: "/_readiness", + opts: []HandlerOption{WithReadinessPath("/_readiness")}, + live: true, + ready: true, + expect: http.StatusOK, + expectBody: "{}\n", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { h := NewHandler() + if tt.opts != nil { + h = NewHandler(tt.opts...) + } if !tt.live { h.AddLivenessCheck("test-liveness-check", func() error {