mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 05:04:05 -08:00
web: cleanup initialization of web service.
This commit is contained in:
parent
3247052563
commit
78047326b4
12
main.go
12
main.go
|
@ -81,6 +81,7 @@ type prometheus struct {
|
|||
ruleManager *rules.Manager
|
||||
targetManager *retrieval.TargetManager
|
||||
notificationHandler *notification.NotificationHandler
|
||||
statusHandler *web.PrometheusStatusHandler
|
||||
storage local.Storage
|
||||
remoteStorageQueues []*remote.StorageQueueManager
|
||||
|
||||
|
@ -189,25 +190,26 @@ func NewPrometheus() *prometheus {
|
|||
QueryEngine: queryEngine,
|
||||
}
|
||||
|
||||
webService := &web.WebService{
|
||||
webService := web.NewWebService(&web.WebServiceOptions{
|
||||
PathPrefix: *pathPrefix,
|
||||
StatusHandler: prometheusStatus,
|
||||
MetricsHandler: metricsService,
|
||||
ConsolesHandler: consolesHandler,
|
||||
AlertsHandler: alertsHandler,
|
||||
GraphsHandler: graphsHandler,
|
||||
}
|
||||
})
|
||||
|
||||
p := &prometheus{
|
||||
queryEngine: queryEngine,
|
||||
ruleManager: ruleManager,
|
||||
targetManager: targetManager,
|
||||
notificationHandler: notificationHandler,
|
||||
statusHandler: prometheusStatus,
|
||||
storage: memStorage,
|
||||
remoteStorageQueues: remoteStorageQueues,
|
||||
|
||||
webService: webService,
|
||||
}
|
||||
webService.QuitChan = make(chan struct{})
|
||||
|
||||
if !p.reloadConfig() {
|
||||
os.Exit(1)
|
||||
|
@ -227,7 +229,7 @@ func (p *prometheus) reloadConfig() bool {
|
|||
}
|
||||
success := true
|
||||
|
||||
success = success && p.webService.StatusHandler.ApplyConfig(conf)
|
||||
success = success && p.statusHandler.ApplyConfig(conf)
|
||||
success = success && p.targetManager.ApplyConfig(conf)
|
||||
success = success && p.ruleManager.ApplyConfig(conf)
|
||||
|
||||
|
@ -268,7 +270,7 @@ func (p *prometheus) Serve() {
|
|||
|
||||
defer p.queryEngine.Stop()
|
||||
|
||||
go p.webService.ServeForever(*pathPrefix)
|
||||
go p.webService.Run()
|
||||
|
||||
// Wait for reload or termination signals.
|
||||
hup := make(chan os.Signal)
|
||||
|
|
|
@ -33,19 +33,19 @@ type MetricsService struct {
|
|||
}
|
||||
|
||||
// RegisterHandler registers the handler for the various endpoints below /api.
|
||||
func (msrv *MetricsService) RegisterHandler(pathPrefix string) {
|
||||
func (msrv *MetricsService) RegisterHandler(mux *http.ServeMux, pathPrefix string) {
|
||||
handler := func(h func(http.ResponseWriter, *http.Request)) http.Handler {
|
||||
return httputil.CompressionHandler{
|
||||
Handler: http.HandlerFunc(h),
|
||||
}
|
||||
}
|
||||
http.Handle(pathPrefix+"/api/query", prometheus.InstrumentHandler(
|
||||
mux.Handle(pathPrefix+"/api/query", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/api/query", handler(msrv.Query),
|
||||
))
|
||||
http.Handle(pathPrefix+"/api/query_range", prometheus.InstrumentHandler(
|
||||
mux.Handle(pathPrefix+"/api/query_range", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/api/query_range", handler(msrv.QueryRange),
|
||||
))
|
||||
http.Handle(pathPrefix+"/api/metrics", prometheus.InstrumentHandler(
|
||||
mux.Handle(pathPrefix+"/api/metrics", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/api/metrics", handler(msrv.Metrics),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ func TestQuery(t *testing.T) {
|
|||
Storage: storage,
|
||||
QueryEngine: promql.NewEngine(storage),
|
||||
}
|
||||
api.RegisterHandler("")
|
||||
api.RegisterHandler(http.DefaultServeMux, "")
|
||||
|
||||
server := httptest.NewServer(http.DefaultServeMux)
|
||||
defer server.Close()
|
||||
|
|
77
web/web.go
77
web/web.go
|
@ -49,77 +49,88 @@ var (
|
|||
|
||||
// WebService handles the HTTP endpoints with the exception of /api.
|
||||
type WebService struct {
|
||||
QuitChan chan struct{}
|
||||
mux *http.ServeMux
|
||||
}
|
||||
|
||||
type WebServiceOptions struct {
|
||||
PathPrefix string
|
||||
StatusHandler *PrometheusStatusHandler
|
||||
MetricsHandler *api.MetricsService
|
||||
AlertsHandler *AlertsHandler
|
||||
ConsolesHandler *ConsolesHandler
|
||||
GraphsHandler *GraphsHandler
|
||||
|
||||
QuitChan chan struct{}
|
||||
}
|
||||
|
||||
// ServeForever serves the HTTP endpoints and only returns upon errors.
|
||||
func (ws WebService) ServeForever(pathPrefix string) {
|
||||
// NewWebService returns a new WebService.
|
||||
func NewWebService(o *WebServiceOptions) *WebService {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
http.Handle("/favicon.ico", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "", 404)
|
||||
}))
|
||||
ws := &WebService{
|
||||
mux: mux,
|
||||
QuitChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
http.HandleFunc("/", prometheus.InstrumentHandlerFunc(pathPrefix, func(rw http.ResponseWriter, req *http.Request) {
|
||||
mux.HandleFunc("/", prometheus.InstrumentHandlerFunc(o.PathPrefix, func(rw http.ResponseWriter, req *http.Request) {
|
||||
// The "/" pattern matches everything, so we need to check
|
||||
// that we're at the root here.
|
||||
if req.URL.Path == pathPrefix+"/" {
|
||||
ws.StatusHandler.ServeHTTP(rw, req)
|
||||
} else if req.URL.Path == pathPrefix {
|
||||
http.Redirect(rw, req, pathPrefix+"/", http.StatusFound)
|
||||
} else if !strings.HasPrefix(req.URL.Path, pathPrefix+"/") {
|
||||
if req.URL.Path == o.PathPrefix+"/" {
|
||||
o.StatusHandler.ServeHTTP(rw, req)
|
||||
} else if req.URL.Path == o.PathPrefix {
|
||||
http.Redirect(rw, req, o.PathPrefix+"/", http.StatusFound)
|
||||
} else if !strings.HasPrefix(req.URL.Path, o.PathPrefix+"/") {
|
||||
// We're running under a prefix but the user requested something
|
||||
// outside of it. Let's see if this page exists under the prefix.
|
||||
http.Redirect(rw, req, pathPrefix+req.URL.Path, http.StatusFound)
|
||||
http.Redirect(rw, req, o.PathPrefix+req.URL.Path, http.StatusFound)
|
||||
} else {
|
||||
http.NotFound(rw, req)
|
||||
}
|
||||
}))
|
||||
http.Handle(pathPrefix+"/alerts", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/alerts", ws.AlertsHandler,
|
||||
mux.Handle(o.PathPrefix+"/alerts", prometheus.InstrumentHandler(
|
||||
o.PathPrefix+"/alerts", o.AlertsHandler,
|
||||
))
|
||||
http.Handle(pathPrefix+"/consoles/", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/consoles/", http.StripPrefix(pathPrefix+"/consoles/", ws.ConsolesHandler),
|
||||
mux.Handle(o.PathPrefix+"/consoles/", prometheus.InstrumentHandler(
|
||||
o.PathPrefix+"/consoles/", http.StripPrefix(o.PathPrefix+"/consoles/", o.ConsolesHandler),
|
||||
))
|
||||
http.Handle(pathPrefix+"/graph", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/graph", ws.GraphsHandler,
|
||||
mux.Handle(o.PathPrefix+"/graph", prometheus.InstrumentHandler(
|
||||
o.PathPrefix+"/graph", o.GraphsHandler,
|
||||
))
|
||||
http.Handle(pathPrefix+"/heap", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/heap", http.HandlerFunc(dumpHeap),
|
||||
mux.Handle(o.PathPrefix+"/heap", prometheus.InstrumentHandler(
|
||||
o.PathPrefix+"/heap", http.HandlerFunc(dumpHeap),
|
||||
))
|
||||
|
||||
ws.MetricsHandler.RegisterHandler(pathPrefix)
|
||||
http.Handle(pathPrefix+*metricsPath, prometheus.Handler())
|
||||
o.MetricsHandler.RegisterHandler(mux, o.PathPrefix)
|
||||
mux.Handle(o.PathPrefix+*metricsPath, prometheus.Handler())
|
||||
if *useLocalAssets {
|
||||
http.Handle(pathPrefix+"/static/", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/static/", http.StripPrefix(pathPrefix+"/static/", http.FileServer(http.Dir("web/static"))),
|
||||
mux.Handle(o.PathPrefix+"/static/", prometheus.InstrumentHandler(
|
||||
o.PathPrefix+"/static/", http.StripPrefix(o.PathPrefix+"/static/", http.FileServer(http.Dir("web/static"))),
|
||||
))
|
||||
} else {
|
||||
http.Handle(pathPrefix+"/static/", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/static/", http.StripPrefix(pathPrefix+"/static/", new(blob.Handler)),
|
||||
mux.Handle(o.PathPrefix+"/static/", prometheus.InstrumentHandler(
|
||||
o.PathPrefix+"/static/", http.StripPrefix(o.PathPrefix+"/static/", new(blob.Handler)),
|
||||
))
|
||||
}
|
||||
|
||||
if *userAssetsPath != "" {
|
||||
http.Handle(pathPrefix+"/user/", prometheus.InstrumentHandler(
|
||||
pathPrefix+"/user/", http.StripPrefix(pathPrefix+"/user/", http.FileServer(http.Dir(*userAssetsPath))),
|
||||
mux.Handle(o.PathPrefix+"/user/", prometheus.InstrumentHandler(
|
||||
o.PathPrefix+"/user/", http.StripPrefix(o.PathPrefix+"/user/", http.FileServer(http.Dir(*userAssetsPath))),
|
||||
))
|
||||
}
|
||||
|
||||
if *enableQuit {
|
||||
http.Handle(pathPrefix+"/-/quit", http.HandlerFunc(ws.quitHandler))
|
||||
mux.Handle(o.PathPrefix+"/-/quit", http.HandlerFunc(ws.quitHandler))
|
||||
}
|
||||
|
||||
return ws
|
||||
}
|
||||
|
||||
// Run serves the HTTP endpoints.
|
||||
func (ws *WebService) Run() {
|
||||
log.Infof("Listening on %s", *listenAddress)
|
||||
|
||||
// If we cannot bind to a port, retry after 30 seconds.
|
||||
for {
|
||||
err := http.ListenAndServe(*listenAddress, nil)
|
||||
err := http.ListenAndServe(*listenAddress, ws.mux)
|
||||
if err != nil {
|
||||
log.Errorf("Could not listen on %s: %s", *listenAddress, err)
|
||||
}
|
||||
|
@ -127,7 +138,7 @@ func (ws WebService) ServeForever(pathPrefix string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (ws WebService) quitHandler(w http.ResponseWriter, r *http.Request) {
|
||||
func (ws *WebService) quitHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
w.Header().Add("Allow", "POST")
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
|
|
Loading…
Reference in a new issue