Skip to content

Commit

Permalink
Add experimental healthcheck support
Browse files Browse the repository at this point in the history
  • Loading branch information
tshak committed Jun 22, 2024
1 parent 49d020b commit 5611a87
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 3 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ The following environment variables can be used to configure the service.
| Name | Default | Description
| -| -| -
| `TESTDUMMY_BIND_ADDRESS` | `:8000` | The address to bind the service to
| `TESTDUMMY_ENABLE_ENV` | `false` | Enable the `/env` endpoint which dumps env vars. :warning: This can be a security risk so enable with caution
| `TESTDUMMY_ENABLE_REQUEST_LOGGING` | `false` | Logs all requests to stdout
| `TESTDUMMY_HEALTHY` | `true` | Boolean. When `true` `/health` returns an HTTP 200 response. When `false` `/health` returns an empty HTTP 500 response.
| `TESTDUMMY_HEALTHY_AFTER_SECONDS` | | When set, sets the health status to `false` (regardless of `TESTDUMMY_HEALTHY`) until the specified number of seconds. This is useful for testing post deployment "warmup" scenarios.
| `TESTDUMMY_HEALTHCHECK_PG_DSN` | | When set, adds a healthcheck for the specified Postgres DSN (e.g. postgres://test:test@0.0.0.0:5432/test?sslmode=disable)
| `TESTDUMMY_PANIC_SECONDS` | | When set, specifies the number of seconds to wait before panicking. This is useful for testing crash recovery scenarios.
| `TESTDUMMY_ENABLE_REQUEST_LOGGING` | `false` | Logs all requests to stdout
| `TESTDUMMY_ENABLE_ENV` | `false` | Enable the `/env` endpoint which dumps env vars. :warning: This can be a security risk so enable with caution
| `TESTDUMMY_ROOT_PATH` | `/` | The root path for all routes
| `TESTDUMMY_STRESS_CPU_DURATION` | `0s` | Ping endpoints will perform a naive CPU stress test on all cores for the supplied duration



## API

| Path | Description
Expand All @@ -34,6 +36,7 @@ The following environment variables can be used to configure the service.
| `/env` | Returns all environment variables in the format `NAME=VALUE`, one per line.
| `/exit?code={exitCode}` | Causes the process to exit with a default exit code of `1`. Use the `code` parameter to customize the exit code.
| <code>/health?healthy={true&#124;false}</code> | Returns an empty HTTP 200 if healthy, otherwise an empty HTTP 500. The healthy status can be changed using the optional `healthy` query parameter. This status persists for the lifetime of the process. See the [Environment Variables](#environment-variables) section for related options.
| `/healthcheck` | Runs specific healthchecks as configured via the `TESTDUMMY_HEALTHCHECK_*` environment variables.
| `/status?status={statusCode}` | Returns the supplied HTTP status code
| `/version` | Returns the testdummy version

7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@ require (
github.com/stretchr/testify v1.9.0
)

require (
github.com/lib/pq v1.10.9 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hellofresh/health-go/v5 v5.5.3
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hellofresh/health-go/v5 v5.5.3 h1:i+mfJcA8te/QhBzrBZxOw344XgIvHrc9IQzrEyn3OUQ=
github.com/hellofresh/health-go/v5 v5.5.3/go.mod h1:maWprKoK7N9zno7l2ubFEGVF2SDmTHq5D9sV+lCFmGs=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
27 changes: 26 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import (

"github.com/kelseyhightower/envconfig"
"github.com/pkg/errors"

"github.com/hellofresh/health-go/v5"
healthPg "github.com/hellofresh/health-go/v5/checks/postgres"
)

// versionString is overwritten using compiler ldflags
Expand All @@ -32,6 +35,7 @@ type RuntimeConfig struct {
EnableEnv bool `split_words:"true" default:"false"`
RootPath string `split_words:"true" default:"/"`
StressCpuDuration string `split_words:"true" default:"0s"`
HealthcheckPgDsn string `split_words:"true"`
}

func main() {
Expand Down Expand Up @@ -62,7 +66,7 @@ func main() {
Handler: logging(rc, logger)(mux),
}

addRoute := func(path string, handler func(http.ResponseWriter, *http.Request)) {
addRoute := func(path string, handler http.HandlerFunc) {
mux.HandleFunc(filepath.Join(rc.RootPath, path), handler)
}

Expand All @@ -73,9 +77,11 @@ func main() {
addRoute("ping", func(w http.ResponseWriter, r *http.Request) { pingHandler(w, r, stressDuration) })
addRoute("echo", echoHandler)
addRoute("health", healthHandler)
addRoute("healthcheck", createHealthcheckHandlerFunc(rc))
addRoute("version", versionHandler)
addRoute("exit", exitHandler)
addRoute("status", statusHandler)

if rc.EnableEnv {
logger.Println("WARNING: /env is enabled. This may expose sensitive information.")
addRoute("env", envHandler)
Expand Down Expand Up @@ -216,3 +222,22 @@ func logging(rc RuntimeConfig, logger *log.Logger) func(http.Handler) http.Handl
})
}
}

func createHealthcheckHandlerFunc(rc RuntimeConfig) http.HandlerFunc {
healthChecker, err := health.New()
LogIfErr(err, "Error creating health checker")

if rc.HealthcheckPgDsn != "" {
err = healthChecker.Register(health.Config{
Name: "postgres",
Timeout: time.Second * 2,
SkipOnErr: false,
Check: healthPg.New(healthPg.Config{
DSN: rc.HealthcheckPgDsn,
}),
})
LogIfErr(err, "Error registering Postgres health check")
}

return healthChecker.HandlerFunc
}

0 comments on commit 5611a87

Please sign in to comment.