提交 fd7b4cae 编写于 作者: J Julius Volz

Merge pull request #864 from prometheus/configurable-scheme

Consolidate external reachability flags into one.
......@@ -17,6 +17,7 @@ import (
"flag"
"fmt"
"net"
"net/url"
"os"
"strings"
"text/template"
......@@ -68,17 +69,13 @@ func init() {
)
// Web.
cfg.fs.StringVar(
&cfg.web.PathPrefix, "web.path-prefix", "",
"Prefix for all web paths.",
)
cfg.fs.StringVar(
&cfg.web.ListenAddress, "web.listen-address", ":9090",
"Address to listen on for the web interface, API, and telemetry.",
)
cfg.fs.StringVar(
&cfg.web.Hostname, "web.hostname", "",
"Hostname on which the server is available.",
&cfg.prometheusURL, "web.external-url", "",
"The URL under which Prometheus is externally reachable (for example, if Prometheus is served via a reverse proxy). Used for generating relative and absolute links back to Prometheus itself. If omitted, relevant URL components will be derived automatically.",
)
cfg.fs.StringVar(
&cfg.web.MetricsPath, "web.telemetry-path", "/metrics",
......@@ -98,7 +95,7 @@ func init() {
)
cfg.fs.StringVar(
&cfg.web.ConsoleTemplatesPath, "web.console.templates", "consoles",
"Path to the console template directory, available at /console.",
"Path to the console template directory, available at /consoles.",
)
cfg.fs.StringVar(
&cfg.web.ConsoleLibrariesPath, "web.console.libraries", "console_libraries",
......@@ -224,24 +221,29 @@ func parse(args []string) error {
return err
}
ppref := strings.TrimRight(cfg.web.PathPrefix, "/")
if ppref != "" && !strings.HasPrefix(ppref, "/") {
ppref = "/" + ppref
}
cfg.web.PathPrefix = ppref
if cfg.web.Hostname == "" {
cfg.web.Hostname, err = os.Hostname()
if cfg.prometheusURL == "" {
hostname, err := os.Hostname()
if err != nil {
return err
}
_, port, err := net.SplitHostPort(cfg.web.ListenAddress)
if err != nil {
return err
}
cfg.prometheusURL = fmt.Sprintf("http://%s:%s/", hostname, port)
}
_, port, err := net.SplitHostPort(cfg.web.ListenAddress)
promURL, err := url.Parse(cfg.prometheusURL)
if err != nil {
return err
}
cfg.prometheusURL = fmt.Sprintf("http://%s:%s%s/", cfg.web.Hostname, port, cfg.web.PathPrefix)
cfg.web.ExternalURL = promURL
ppref := strings.TrimRight(cfg.web.ExternalURL.Path, "/")
if ppref != "" && !strings.HasPrefix(ppref, "/") {
ppref = "/" + ppref
}
cfg.web.ExternalURL.Path = ppref
return nil
}
......
......@@ -75,8 +75,7 @@ func Main() int {
SampleAppender: sampleAppender,
NotificationHandler: notificationHandler,
QueryEngine: queryEngine,
PrometheusURL: cfg.prometheusURL,
PathPrefix: cfg.web.PathPrefix,
ExternalURL: cfg.web.ExternalURL,
})
flags := map[string]string{}
......
......@@ -16,8 +16,8 @@ package rules
import (
"fmt"
"io/ioutil"
"net/url"
"path/filepath"
"strings"
"sync"
"time"
......@@ -103,8 +103,7 @@ type Manager struct {
sampleAppender storage.SampleAppender
notificationHandler *notification.NotificationHandler
prometheusURL string
pathPrefix string
externalURL *url.URL
}
// ManagerOptions bundles options for the Manager.
......@@ -115,8 +114,7 @@ type ManagerOptions struct {
NotificationHandler *notification.NotificationHandler
SampleAppender storage.SampleAppender
PrometheusURL string
PathPrefix string
ExternalURL *url.URL
}
// NewManager returns an implementation of Manager, ready to be started
......@@ -130,7 +128,7 @@ func NewManager(o *ManagerOptions) *Manager {
sampleAppender: o.SampleAppender,
queryEngine: o.QueryEngine,
notificationHandler: o.NotificationHandler,
prometheusURL: o.PrometheusURL,
externalURL: o.ExternalURL,
}
return manager
}
......@@ -211,7 +209,7 @@ func (m *Manager) queueAlertNotifications(rule *AlertingRule, timestamp clientmo
defs := "{{$labels := .Labels}}{{$value := .Value}}"
expand := func(text string) string {
tmpl := template.NewTemplateExpander(defs+text, "__alert_"+rule.Name(), tmplData, timestamp, m.queryEngine, m.pathPrefix)
tmpl := template.NewTemplateExpander(defs+text, "__alert_"+rule.Name(), tmplData, timestamp, m.queryEngine, m.externalURL.Path)
result, err := tmpl.Expand()
if err != nil {
result = err.Error()
......@@ -230,7 +228,7 @@ func (m *Manager) queueAlertNotifications(rule *AlertingRule, timestamp clientmo
Value: aa.Value,
ActiveSince: aa.ActiveSince.Time(),
RuleString: rule.String(),
GeneratorURL: m.prometheusURL + strings.TrimLeft(strutil.GraphLinkForExpression(rule.vector.String()), "/"),
GeneratorURL: m.externalURL.String() + strutil.GraphLinkForExpression(rule.vector.String()),
})
}
m.notificationHandler.SubmitReqs(notifications)
......
此差异已折叠。
......@@ -33,7 +33,7 @@
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-left">
{{$consoles := getConsoles}}
{{$consoles := consolesPath}}
{{if $consoles}}
<li><a href="{{$consoles}}">Consoles</a></li>
{{ end }}
......
......@@ -18,12 +18,12 @@ import (
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"time"
......@@ -93,9 +93,8 @@ func (s *PrometheusStatus) ApplyConfig(conf *config.Config) bool {
// Options for the web Handler.
type Options struct {
PathPrefix string
ListenAddress string
Hostname string
ExternalURL *url.URL
MetricsPath string
UseLocalAssets bool
UserAssetsPath string
......@@ -131,12 +130,12 @@ func New(st local.Storage, qe *promql.Engine, rm *rules.Manager, status *Prometh
},
}
if o.PathPrefix != "" {
if o.ExternalURL.Path != "" {
// If the prefix is missing for the root path, prepend it.
router.Get("/", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, o.PathPrefix, http.StatusFound)
http.Redirect(w, r, o.ExternalURL.Path, http.StatusFound)
})
router = router.WithPrefix(o.PathPrefix)
router = router.WithPrefix(o.ExternalURL.Path)
}
instrf := prometheus.InstrumentHandlerFunc
......@@ -248,7 +247,7 @@ func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
Path: name,
}
tmpl := template.NewTemplateExpander(string(text), "__console_"+name, data, clientmodel.Now(), h.queryEngine, h.options.PathPrefix)
tmpl := template.NewTemplateExpander(string(text), "__console_"+name, data, clientmodel.Now(), h.queryEngine, h.options.ExternalURL.Path)
filenames, err := filepath.Glob(h.options.ConsoleLibrariesPath + "/*.lib")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
......@@ -308,13 +307,13 @@ func (h *Handler) getTemplateFile(name string) (string, error) {
return string(file), nil
}
func (h *Handler) getConsoles() string {
func (h *Handler) consolesPath() string {
if _, err := os.Stat(h.options.ConsoleTemplatesPath + "/index.html"); !os.IsNotExist(err) {
return h.options.PathPrefix + "/consoles/index.html"
return h.options.ExternalURL.Path + "/consoles/index.html"
}
if h.options.UserAssetsPath != "" {
if _, err := os.Stat(h.options.UserAssetsPath + "/index.html"); !os.IsNotExist(err) {
return h.options.PathPrefix + "/user/index.html"
return h.options.ExternalURL.Path + "/user/index.html"
}
}
return ""
......@@ -332,17 +331,11 @@ func (h *Handler) getTemplate(name string) (string, error) {
return baseTmpl + pageTmpl, nil
}
func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data interface{}) {
text, err := h.getTemplate(name)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
tmpl := template.NewTemplateExpander(text, name, data, clientmodel.Now(), h.queryEngine, h.options.PathPrefix)
tmpl.Funcs(template_text.FuncMap{
"since": time.Since,
"getConsoles": h.getConsoles,
"pathPrefix": func() string { return h.options.PathPrefix },
func tmplFuncs(consolesPath string, opts *Options) template_text.FuncMap {
return template_text.FuncMap{
"since": time.Since,
"consolesPath": func() string { return consolesPath },
"pathPrefix": func() string { return opts.ExternalURL.Path },
"stripLabels": func(lset clientmodel.LabelSet, labels ...clientmodel.LabelName) clientmodel.LabelSet {
for _, ln := range labels {
delete(lset, ln)
......@@ -350,9 +343,39 @@ func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data inter
return lset
},
"globalURL": func(u *url.URL) *url.URL {
host, port, err := net.SplitHostPort(u.Host)
if err != nil {
return u
}
for _, lhr := range localhostRepresentations {
if strings.HasPrefix(u.Host, lhr+":") {
u.Host = strings.Replace(u.Host, lhr+":", h.options.Hostname+":", 1)
if host == lhr {
_, ownPort, err := net.SplitHostPort(opts.ListenAddress)
if err != nil {
return u
}
if port == ownPort {
// Only in the case where the target is on localhost and its port is
// the same as the one we're listening on, we know for sure that
// we're monitoring our own process and that we need to change the
// scheme, hostname, and port to the externally reachable ones as
// well. We shouldn't need to touch the path at all, since if a
// path prefix is defined, the path under which we scrape ourselves
// should already contain the prefix.
u.Scheme = opts.ExternalURL.Scheme
u.Host = opts.ExternalURL.Host
} else {
// Otherwise, we only know that localhost is not reachable
// externally, so we replace only the hostname by the one in the
// external URL. It could be the wrong hostname for the service on
// this port, but it's still the best possible guess.
host, _, err := net.SplitHostPort(opts.ExternalURL.Host)
if err != nil {
return u
}
u.Host = host + ":" + port
}
break
}
}
return u
......@@ -379,7 +402,17 @@ func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data inter
panic("unknown alert state")
}
},
})
}
}
func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data interface{}) {
text, err := h.getTemplate(name)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
tmpl := template.NewTemplateExpander(text, name, data, clientmodel.Now(), h.queryEngine, h.options.ExternalURL.Path)
tmpl.Funcs(tmplFuncs(h.consolesPath(), h.options))
result, err := tmpl.ExpandHTML(nil)
if err != nil {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册