diff --git a/console_libraries/menu.lib b/console_libraries/menu.lib index a6acc51e62..dc0678895c 100644 --- a/console_libraries/menu.lib +++ b/console_libraries/menu.lib @@ -12,12 +12,12 @@ - Prometheus + Prometheus
diff --git a/console_libraries/prom.lib b/console_libraries/prom.lib index ac8638f7f6..f80ea58b73 100644 --- a/console_libraries/prom.lib +++ b/console_libraries/prom.lib @@ -1,15 +1,17 @@ {{/* vim: set ft=html: */}} {{/* Load Prometheus console library JS/CSS. Should go in */}} {{ define "prom_console_head" }} - - - - - - - - - + + + + + + + + + + + {{ end }} {{/* Top of all pages. */}} diff --git a/main.go b/main.go index 19e3557441..50e6aa0616 100644 --- a/main.go +++ b/main.go @@ -20,6 +20,7 @@ import ( "os/signal" "sync" "syscall" + "strings" "time" "github.com/golang/glog" @@ -65,6 +66,8 @@ var ( storageDirty = flag.Bool("storage.local.dirty", false, "If set, the local storage layer will perform crash recovery even if the last shutdown appears to be clean.") storagePedanticChecks = flag.Bool("storage.local.pedantic-checks", false, "If set, a crash recovery will perform checks on each series file. This might take a very long time.") + pathPrefix = flag.String("web.path-prefix", "/", "Prefix for all web paths.") + printVersion = flag.Bool("version", false, "Print version information.") ) @@ -140,7 +143,8 @@ func NewPrometheus() *prometheus { NotificationHandler: notificationHandler, EvaluationInterval: conf.EvaluationInterval(), Storage: memStorage, - PrometheusURL: web.MustBuildServerURL(), + PrometheusURL: web.MustBuildServerURL(*pathPrefix), + PathPrefix: *pathPrefix, }) if err := ruleManager.AddRulesFromConfig(conf); err != nil { glog.Fatal("Error loading rule files: ", err) @@ -157,14 +161,21 @@ func NewPrometheus() *prometheus { TargetPools: targetManager.Pools(), Flags: flags, Birth: time.Now(), + PathPrefix: *pathPrefix, } alertsHandler := &web.AlertsHandler{ RuleManager: ruleManager, + PathPrefix: *pathPrefix, } consolesHandler := &web.ConsolesHandler{ Storage: memStorage, + PathPrefix: *pathPrefix, + } + + graphsHandler := &web.GraphsHandler{ + PathPrefix: *pathPrefix, } metricsService := &api.MetricsService{ @@ -177,6 +188,7 @@ func NewPrometheus() *prometheus { MetricsHandler: metricsService, ConsolesHandler: consolesHandler, AlertsHandler: alertsHandler, + GraphsHandler: graphsHandler, } p := &prometheus{ @@ -205,7 +217,7 @@ func (p *prometheus) Serve() { p.storage.Start() go func() { - err := p.webService.ServeForever() + err := p.webService.ServeForever(*pathPrefix) if err != nil { glog.Fatal(err) } @@ -255,6 +267,14 @@ func (p *prometheus) Collect(ch chan<- registry.Metric) { func main() { flag.Parse() + + if !strings.HasPrefix(*pathPrefix, "/") { + *pathPrefix = "/" + *pathPrefix + } + if !strings.HasSuffix(*pathPrefix, "/") { + *pathPrefix = *pathPrefix + "/" + } + versionInfoTmpl.Execute(os.Stdout, BuildInfo) if *printVersion { diff --git a/rules/manager/manager.go b/rules/manager/manager.go index 8dfdc561a7..0b1a386a5c 100644 --- a/rules/manager/manager.go +++ b/rules/manager/manager.go @@ -99,6 +99,7 @@ type ruleManager struct { notificationHandler *notification.NotificationHandler prometheusURL string + pathPrefix string } // RuleManagerOptions bundles options for the RuleManager. @@ -110,6 +111,7 @@ type RuleManagerOptions struct { SampleAppender storage.SampleAppender PrometheusURL string + PathPrefix string } // NewRuleManager returns an implementation of RuleManager, ready to be started @@ -190,7 +192,7 @@ func (m *ruleManager) queueAlertNotifications(rule *rules.AlertingRule, timestam defs := "{{$labels := .Labels}}{{$value := .Value}}" expand := func(text string) string { - template := templates.NewTemplateExpander(defs+text, "__alert_"+rule.Name(), tmplData, timestamp, m.storage) + template := templates.NewTemplateExpander(defs+text, "__alert_"+rule.Name(), tmplData, timestamp, m.storage, m.pathPrefix) result, err := template.Expand() if err != nil { result = err.Error() diff --git a/templates/templates.go b/templates/templates.go index 2bbb70f256..b072584827 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -92,7 +92,7 @@ type templateExpander struct { } // NewTemplateExpander returns a template expander ready to use. -func NewTemplateExpander(text string, name string, data interface{}, timestamp clientmodel.Timestamp, storage local.Storage) *templateExpander { +func NewTemplateExpander(text string, name string, data interface{}, timestamp clientmodel.Timestamp, storage local.Storage, pathPrefix string) *templateExpander { return &templateExpander{ text: text, name: name, @@ -218,6 +218,9 @@ func NewTemplateExpander(text string, name string, data interface{}, timestamp c } return fmt.Sprintf("%.4g%ss", v, prefix) }, + "pathPrefix": func() string { + return pathPrefix; + }, }, } } diff --git a/templates/templates_test.go b/templates/templates_test.go index 9caa148973..f4c769b503 100644 --- a/templates/templates_test.go +++ b/templates/templates_test.go @@ -178,7 +178,7 @@ func TestTemplateExpansion(t *testing.T) { for i, s := range scenarios { var result string var err error - expander := NewTemplateExpander(s.text, "test", s.input, time, storage) + expander := NewTemplateExpander(s.text, "test", s.input, time, storage, "/") if s.html { result, err = expander.ExpandHTML(nil) } else { diff --git a/web/alerts.go b/web/alerts.go index 77eb9d49b5..864e289fe7 100644 --- a/web/alerts.go +++ b/web/alerts.go @@ -47,9 +47,9 @@ func (s byAlertStateSorter) Swap(i, j int) { // AlertsHandler implements http.Handler. type AlertsHandler struct { + mutex sync.Mutex RuleManager manager.RuleManager - - mutex sync.Mutex + PathPrefix string } func (h *AlertsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -68,5 +68,5 @@ func (h *AlertsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { rules.Firing: "danger", }, } - executeTemplate(w, "alerts", alertStatus) + executeTemplate(w, "alerts", alertStatus, h.PathPrefix) } diff --git a/web/api/api.go b/web/api/api.go index 0ab6576c98..90d1c1453d 100644 --- a/web/api/api.go +++ b/web/api/api.go @@ -31,19 +31,19 @@ type MetricsService struct { } // RegisterHandler registers the handler for the various endpoints below /api. -func (msrv *MetricsService) RegisterHandler() { +func (msrv *MetricsService) RegisterHandler(pathPrefix string) { handler := func(h func(http.ResponseWriter, *http.Request)) http.Handler { return httputils.CompressionHandler{ Handler: http.HandlerFunc(h), } } - http.Handle("/api/query", prometheus.InstrumentHandler( - "/api/query", handler(msrv.Query), + http.Handle(pathPrefix + "api/query", prometheus.InstrumentHandler( + pathPrefix + "api/query", handler(msrv.Query), )) - http.Handle("/api/query_range", prometheus.InstrumentHandler( - "/api/query_range", handler(msrv.QueryRange), + http.Handle(pathPrefix + "api/query_range", prometheus.InstrumentHandler( + pathPrefix + "api/query_range", handler(msrv.QueryRange), )) - http.Handle("/api/metrics", prometheus.InstrumentHandler( - "/api/metrics", handler(msrv.Metrics), + http.Handle(pathPrefix + "api/metrics", prometheus.InstrumentHandler( + pathPrefix + "api/metrics", handler(msrv.Metrics), )) } diff --git a/web/api/api_test.go b/web/api/api_test.go index d76f9f7f14..e185fbb9dd 100644 --- a/web/api/api_test.go +++ b/web/api/api_test.go @@ -95,7 +95,7 @@ func TestQuery(t *testing.T) { Now: testNow, Storage: storage, } - api.RegisterHandler() + api.RegisterHandler("/") server := httptest.NewServer(http.DefaultServeMux) defer server.Close() diff --git a/web/consoles.go b/web/consoles.go index 6e0fd00da2..d8874aaae0 100644 --- a/web/consoles.go +++ b/web/consoles.go @@ -34,6 +34,7 @@ var ( // ConsolesHandler implements http.Handler. type ConsolesHandler struct { Storage local.Storage + PathPrefix string } func (h *ConsolesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -69,7 +70,7 @@ func (h *ConsolesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { Path: r.URL.Path, } - template := templates.NewTemplateExpander(string(text), "__console_"+r.URL.Path, data, clientmodel.Now(), h.Storage) + template := templates.NewTemplateExpander(string(text), "__console_"+r.URL.Path, data, clientmodel.Now(), h.Storage, h.PathPrefix) filenames, err := filepath.Glob(*consoleLibrariesPath + "/*.lib") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/web/handler.go b/web/handler.go index ba46993c02..c4a070a1b9 100644 --- a/web/handler.go +++ b/web/handler.go @@ -17,6 +17,11 @@ import ( "net/http" ) -func graphHandler(w http.ResponseWriter, r *http.Request) { - executeTemplate(w, "graph", nil) +// GraphsHandler implements http.Handler. +type GraphsHandler struct { + PathPrefix string +} + +func (h *GraphsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + executeTemplate(w, "graph", nil, h.PathPrefix) } diff --git a/web/static/js/graph.js b/web/static/js/graph.js index 3a87ace499..73caf02046 100644 --- a/web/static/js/graph.js +++ b/web/static/js/graph.js @@ -4,6 +4,8 @@ var graphTemplate; var SECOND = 1000; +Handlebars.registerHelper('pathPrefix', function() { return PATH_PREFIX; }); + Prometheus.Graph = function(element, options) { this.el = element; this.options = options; @@ -158,7 +160,7 @@ Prometheus.Graph.prototype.populateInsertableMetrics = function() { var self = this; $.ajax({ method: "GET", - url: "/api/metrics", + url: PATH_PREFIX + "api/metrics", dataType: "json", success: function(json, textStatus) { var availableMetrics = []; @@ -310,7 +312,7 @@ Prometheus.Graph.prototype.submitQuery = function() { url = self.queryForm.attr("action"); success = function(json, textStatus) { self.handleGraphResponse(json, textStatus); }; } else { - url = "/api/query"; + url = PATH_PREFIX + "api/query"; success = function(text, textStatus) { self.handleConsoleResponse(text, textStatus); }; } @@ -609,7 +611,7 @@ function init() { }); $.ajax({ - url: "/static/js/graph_template.handlebar", + url: PATH_PREFIX + "static/js/graph_template.handlebar", success: function(data) { graphTemplate = Handlebars.compile(data); var options = parseGraphOptionsFromURL(); diff --git a/web/static/js/graph_template.handlebar b/web/static/js/graph_template.handlebar index 6f7326e6f6..70b8d5f3ba 100644 --- a/web/static/js/graph_template.handlebar +++ b/web/static/js/graph_template.handlebar @@ -1,5 +1,5 @@