Metrics, rules join, docker partial recovery

This commit is contained in:
emile 2015-09-12 13:20:54 +02:00
parent a9886eb80b
commit d209467b5a
4 changed files with 28 additions and 17 deletions

View file

@ -1,5 +1,8 @@
# /træfɪk/ # /træfɪk/
* Providers recovery
* Use Negroni middlewares for metrics, grace, logs
* tls client verification
* Default configuration values * Default configuration values
* Retry with streams * Retry with streams
* Licence * Licence
@ -24,3 +27,4 @@
* ~~Logs~~ * ~~Logs~~
* ~~SSL frontend support~~ * ~~SSL frontend support~~
* ~~Static files~~ * ~~Static files~~
* ~~Metrics~~

View file

@ -77,6 +77,9 @@ func (provider *DockerProvider) Provide(configurationChan chan <- *Configuration
go func() { go func() {
for { for {
event := <-dockerEvents event := <-dockerEvents
if (event == nil){
log.Fatalf("Docker connection error %+v", err)
}
if(event.Status == "start" || event.Status == "die"){ if(event.Status == "start" || event.Status == "die"){
log.Debug("Docker event receveived %+v", event) log.Debug("Docker event receveived %+v", event)
configuration := provider.loadDockerConfig() configuration := provider.loadDockerConfig()

View file

@ -17,12 +17,14 @@ import (
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/unrolled/render" "github.com/unrolled/render"
"gopkg.in/alecthomas/kingpin.v2" "gopkg.in/alecthomas/kingpin.v2"
"github.com/thoas/stats"
) )
var ( var (
globalConfigFile = kingpin.Arg("conf", "Main configration file.").Default("traefik.toml").String() globalConfigFile = kingpin.Arg("conf", "Main configration file.").Default("traefik.toml").String()
currentConfiguration = new(Configuration) currentConfiguration = new(Configuration)
metrics = stats.New()
log = logging.MustGetLogger("traefik") log = logging.MustGetLogger("traefik")
templatesRenderer = render.New(render.Options{ templatesRenderer = render.New(render.Options{
Directory: "templates", Directory: "templates",
@ -138,7 +140,7 @@ func main() {
Server: &http.Server{ Server: &http.Server{
Addr: gloablConfiguration.Port, Addr: gloablConfiguration.Port,
Handler: configurationRouter, Handler: metrics.Handler(configurationRouter),
}, },
} }
@ -188,12 +190,11 @@ func LoadConfig(configuration *Configuration, gloablConfiguration *GlobalConfigu
for routeName, route := range configuration.Routes { for routeName, route := range configuration.Routes {
log.Debug("Creating route %s", routeName) log.Debug("Creating route %s", routeName)
fwd, _ := forward.New() fwd, _ := forward.New()
newRoutes := []*mux.Route{} newRoute := router.NewRoute()
for ruleName, rule := range route.Rules { for ruleName, rule := range route.Rules {
log.Debug("Creating rule %s", ruleName) log.Debug("Creating rule %s", ruleName)
newRouteReflect := Invoke(router.NewRoute(), rule.Category, rule.Value) newRouteReflect := Invoke(newRoute, rule.Category, rule.Value)
newRoute := newRouteReflect[0].Interface().(*mux.Route) newRoute = newRouteReflect[0].Interface().(*mux.Route)
newRoutes = append(newRoutes, newRoute)
} }
if (backends[route.Backend] ==nil) { if (backends[route.Backend] ==nil) {
log.Debug("Creating backend %s", route.Backend) log.Debug("Creating backend %s", route.Backend)
@ -208,20 +209,18 @@ func LoadConfig(configuration *Configuration, gloablConfiguration *GlobalConfigu
}else { }else {
log.Debug("Reusing backend %s", route.Backend) log.Debug("Reusing backend %s", route.Backend)
} }
for _, muxRoute := range newRoutes { if (len(gloablConfiguration.AccessLogsFile) > 0 ) {
if (len(gloablConfiguration.AccessLogsFile) > 0 ) { fi, err := os.OpenFile(gloablConfiguration.AccessLogsFile, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
fi, err := os.OpenFile(gloablConfiguration.AccessLogsFile, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
log.Fatal("Error opening file ", err)
}
muxRoute.Handler(handlers.CombinedLoggingHandler(fi, backends[route.Backend]))
}else {
muxRoute.Handler(backends[route.Backend])
}
err := muxRoute.GetError()
if err != nil { if err != nil {
log.Error("Error building route ", err) log.Fatal("Error opening file ", err)
} }
newRoute.Handler(handlers.CombinedLoggingHandler(fi, backends[route.Backend]))
}else {
newRoute.Handler(backends[route.Backend])
}
err := newRoute.GetError()
if err != nil {
log.Error("Error building route ", err)
} }
} }
return router return router

5
web.go
View file

@ -20,6 +20,7 @@ type Page struct {
func (provider *WebProvider) Provide(configurationChan chan <- *Configuration) { func (provider *WebProvider) Provide(configurationChan chan <- *Configuration) {
systemRouter := mux.NewRouter() systemRouter := mux.NewRouter()
systemRouter.Methods("GET").PathPrefix("/web/").Handler(http.HandlerFunc(GetHtmlConfigHandler)) systemRouter.Methods("GET").PathPrefix("/web/").Handler(http.HandlerFunc(GetHtmlConfigHandler))
systemRouter.Methods("GET").PathPrefix("/metrics/").Handler(http.HandlerFunc(GetStatsHandler))
systemRouter.Methods("GET").PathPrefix("/api/").Handler(http.HandlerFunc(GetConfigHandler)) systemRouter.Methods("GET").PathPrefix("/api/").Handler(http.HandlerFunc(GetConfigHandler))
systemRouter.Methods("POST").PathPrefix("/api/").Handler(http.HandlerFunc( systemRouter.Methods("POST").PathPrefix("/api/").Handler(http.HandlerFunc(
func(rw http.ResponseWriter, r *http.Request) { func(rw http.ResponseWriter, r *http.Request) {
@ -46,3 +47,7 @@ func GetConfigHandler(rw http.ResponseWriter, r *http.Request) {
func GetHtmlConfigHandler(response http.ResponseWriter, request *http.Request) { func GetHtmlConfigHandler(response http.ResponseWriter, request *http.Request) {
templatesRenderer.HTML(response, http.StatusOK, "configuration", Page{Configuration:*currentConfiguration}) templatesRenderer.HTML(response, http.StatusOK, "configuration", Page{Configuration:*currentConfiguration})
} }
func GetStatsHandler(rw http.ResponseWriter, r *http.Request) {
templatesRenderer.JSON(rw, http.StatusOK, metrics.Data())
}