diff --git a/ROADMAP.md b/ROADMAP.md index 119809e4e..47bda7e68 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,8 @@ # /træfɪk/ +* Providers recovery +* Use Negroni middlewares for metrics, grace, logs +* tls client verification * Default configuration values * Retry with streams * Licence @@ -24,3 +27,4 @@ * ~~Logs~~ * ~~SSL frontend support~~ * ~~Static files~~ +* ~~Metrics~~ diff --git a/docker.go b/docker.go index e77532697..04ace100f 100644 --- a/docker.go +++ b/docker.go @@ -77,6 +77,9 @@ func (provider *DockerProvider) Provide(configurationChan chan <- *Configuration go func() { for { event := <-dockerEvents + if (event == nil){ + log.Fatalf("Docker connection error %+v", err) + } if(event.Status == "start" || event.Status == "die"){ log.Debug("Docker event receveived %+v", event) configuration := provider.loadDockerConfig() diff --git a/traefik.go b/traefik.go index 8a16f5a07..e2ee2b5a2 100644 --- a/traefik.go +++ b/traefik.go @@ -17,12 +17,14 @@ import ( "github.com/gorilla/handlers" "github.com/unrolled/render" "gopkg.in/alecthomas/kingpin.v2" + "github.com/thoas/stats" ) var ( globalConfigFile = kingpin.Arg("conf", "Main configration file.").Default("traefik.toml").String() currentConfiguration = new(Configuration) + metrics = stats.New() log = logging.MustGetLogger("traefik") templatesRenderer = render.New(render.Options{ Directory: "templates", @@ -138,7 +140,7 @@ func main() { Server: &http.Server{ 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 { log.Debug("Creating route %s", routeName) fwd, _ := forward.New() - newRoutes := []*mux.Route{} + newRoute := router.NewRoute() for ruleName, rule := range route.Rules { log.Debug("Creating rule %s", ruleName) - newRouteReflect := Invoke(router.NewRoute(), rule.Category, rule.Value) - newRoute := newRouteReflect[0].Interface().(*mux.Route) - newRoutes = append(newRoutes, newRoute) + newRouteReflect := Invoke(newRoute, rule.Category, rule.Value) + newRoute = newRouteReflect[0].Interface().(*mux.Route) } if (backends[route.Backend] ==nil) { log.Debug("Creating backend %s", route.Backend) @@ -208,20 +209,18 @@ func LoadConfig(configuration *Configuration, gloablConfiguration *GlobalConfigu }else { log.Debug("Reusing backend %s", route.Backend) } - for _, muxRoute := range newRoutes { - if (len(gloablConfiguration.AccessLogsFile) > 0 ) { - 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 (len(gloablConfiguration.AccessLogsFile) > 0 ) { + fi, err := os.OpenFile(gloablConfiguration.AccessLogsFile, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666) 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 diff --git a/web.go b/web.go index da72c595c..cd434d760 100644 --- a/web.go +++ b/web.go @@ -20,6 +20,7 @@ type Page struct { func (provider *WebProvider) Provide(configurationChan chan <- *Configuration) { systemRouter := mux.NewRouter() 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("POST").PathPrefix("/api/").Handler(http.HandlerFunc( 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) { templatesRenderer.HTML(response, http.StatusOK, "configuration", Page{Configuration:*currentConfiguration}) } + +func GetStatsHandler(rw http.ResponseWriter, r *http.Request) { + templatesRenderer.JSON(rw, http.StatusOK, metrics.Data()) +}