Add healthcheck command

This commit is contained in:
Emile Vauge 2017-08-21 23:18:02 +02:00 committed by Traefiker
parent eda679776e
commit 396449c07f
3 changed files with 65 additions and 5 deletions

View file

@ -1,9 +1,11 @@
package main package main
import ( import (
"crypto/tls"
"encoding/json" "encoding/json"
"fmt" "fmt"
fmtlog "log" fmtlog "log"
"net/http"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
@ -97,6 +99,43 @@ Complete documentation is available at https://traefik.io`,
}, },
} }
healthcheckCmd := &flaeg.Command{
Name: "healthcheck",
Description: `Calls traefik /ping to check health (web provider must be enabled)`,
Config: traefikConfiguration,
DefaultPointersConfig: traefikPointersConfiguration,
Run: func() error {
if traefikConfiguration.Web == nil {
fmt.Println("Please enable the web provider to use healtcheck.")
os.Exit(1)
}
client := &http.Client{Timeout: 5 * time.Second}
protocol := "http"
if len(traefikConfiguration.Web.CertFile) > 0 {
protocol = "https"
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client.Transport = tr
}
resp, err := client.Head(protocol + "://" + traefikConfiguration.Web.Address + "/ping")
if err != nil {
fmt.Printf("Error calling healthcheck: %s\n", err)
os.Exit(1)
}
if resp.StatusCode != http.StatusOK {
fmt.Printf("Bad healthcheck status: %s\n", resp.Status)
os.Exit(1)
}
fmt.Printf("OK: %s\n", resp.Request.URL)
os.Exit(0)
return nil
},
Metadata: map[string]string{
"parseAllSources": "true",
},
}
//init flaeg source //init flaeg source
f := flaeg.New(traefikCmd, os.Args[1:]) f := flaeg.New(traefikCmd, os.Args[1:])
//add custom parsers //add custom parsers
@ -112,6 +151,7 @@ Complete documentation is available at https://traefik.io`,
f.AddCommand(newVersionCmd()) f.AddCommand(newVersionCmd())
f.AddCommand(newBugCmd(traefikConfiguration, traefikPointersConfiguration)) f.AddCommand(newBugCmd(traefikConfiguration, traefikPointersConfiguration))
f.AddCommand(storeconfigCmd) f.AddCommand(storeconfigCmd)
f.AddCommand(healthcheckCmd)
usedCmd, err := f.GetCommand() usedCmd, err := f.GetCommand()
if err != nil { if err != nil {

View file

@ -514,6 +514,7 @@ List of Træfik available commands with description :             
- `version` : Print version  - `version` : Print version 
- `storeconfig` : Store the static traefik configuration into a Key-value stores. Please refer to the [Store Træfik configuration](/user-guide/kv-config/#store-trfk-configuration) section to get documentation on it. - `storeconfig` : Store the static traefik configuration into a Key-value stores. Please refer to the [Store Træfik configuration](/user-guide/kv-config/#store-trfk-configuration) section to get documentation on it.
- `bug`: The easiest way to submit a pre-filled issue. - `bug`: The easiest way to submit a pre-filled issue.
- `healthcheck`: Calls traefik `/ping` to check health.
Each command may have related flags. Each command may have related flags.
All those related flags will be displayed with : All those related flags will be displayed with :
@ -538,6 +539,18 @@ $ traefik bug
See https://www.youtube.com/watch?v=Lyz62L8m93I. See https://www.youtube.com/watch?v=Lyz62L8m93I.
## Command: healthcheck
This command allows to check the health of Traefik. Its exit status is `0` if Traefik is healthy and `1` if it is unhealthy.
This can be used with Docker [HEALTHCHECK](https://docs.docker.com/engine/reference/builder/#healthcheck) instruction or any other health check orchestration mechanism.
Note: the `web` provider must be enabled to allow `/ping` calls by the `healthcheck` command.
```bash
$ traefik healthcheck
OK: http://:8082/ping
```
# Log Rotation # Log Rotation
Traefik will close and reopen its log files, assuming they're configured, on receipt of a USR1 signal. This allows the logs Traefik will close and reopen its log files, assuming they're configured, on receipt of a USR1 signal. This allows the logs

View file

@ -136,20 +136,27 @@ func (provider *WebProvider) Provide(configurationChan chan<- types.ConfigMessag
safe.Go(func() { safe.Go(func() {
var err error var err error
var negroni = negroni.New() var negroniInstance = negroni.New()
if provider.Auth != nil { if provider.Auth != nil {
authMiddleware, err := middlewares.NewAuthenticator(provider.Auth) authMiddleware, err := middlewares.NewAuthenticator(provider.Auth)
if err != nil { if err != nil {
log.Fatal("Error creating Auth: ", err) log.Fatal("Error creating Auth: ", err)
} }
negroni.Use(authMiddleware) authMiddlewareWrapper := negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
if r.URL.Path == "/ping" {
next.ServeHTTP(w, r)
} else {
authMiddleware.ServeHTTP(w, r, next)
}
})
negroniInstance.Use(authMiddlewareWrapper)
} }
negroni.UseHandler(systemRouter) negroniInstance.UseHandler(systemRouter)
if len(provider.CertFile) > 0 && len(provider.KeyFile) > 0 { if len(provider.CertFile) > 0 && len(provider.KeyFile) > 0 {
err = http.ListenAndServeTLS(provider.Address, provider.CertFile, provider.KeyFile, negroni) err = http.ListenAndServeTLS(provider.Address, provider.CertFile, provider.KeyFile, negroniInstance)
} else { } else {
err = http.ListenAndServe(provider.Address, negroni) err = http.ListenAndServe(provider.Address, negroniInstance)
} }
if err != nil { if err != nil {