mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-10 07:34:04 -08:00
Merge pull request #1208 from prometheus/assets
Simplify asset handling
This commit is contained in:
commit
307d9fad46
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -21,11 +21,8 @@
|
|||
.idea
|
||||
|
||||
.DS_Store
|
||||
._*
|
||||
.nfs.*
|
||||
/.git
|
||||
[568a].out
|
||||
_cgo_*
|
||||
core
|
||||
|
||||
*-stamp
|
||||
|
@ -38,6 +35,5 @@ benchmark.txt
|
|||
.#*
|
||||
command-line-arguments.test
|
||||
*BACKUP*
|
||||
*BASE*
|
||||
*LOCAL*
|
||||
*REMOTE*
|
||||
|
|
10
Makefile
10
Makefile
|
@ -14,7 +14,12 @@
|
|||
GO := GO15VENDOREXPERIMENT=1 go
|
||||
pkgs = $(shell $(GO) list ./... | grep -v /vendor/)
|
||||
|
||||
all: format build test
|
||||
ifdef DEBUG
|
||||
bindata_flags = -debug
|
||||
endif
|
||||
|
||||
|
||||
all: assets format build test
|
||||
|
||||
test:
|
||||
@echo ">> running tests"
|
||||
|
@ -38,8 +43,7 @@ docker:
|
|||
assets:
|
||||
@echo ">> writing assets"
|
||||
@$(GO) get -u github.com/jteeuwen/go-bindata/...
|
||||
@$(GO) generate ./web/blob
|
||||
@$(GO) fmt ./web/blob >/dev/null
|
||||
@go-bindata $(bindata_flags) -pkg ui -o web/ui/bindata.go -ignore '(.*\.map|bootstrap\.js|bootstrap-theme\.css|bootstrap\.css)' web/ui/templates/... web/ui/static/...
|
||||
|
||||
|
||||
.PHONY: all format build test vet docker assets
|
||||
|
|
|
@ -82,10 +82,6 @@ func init() {
|
|||
&cfg.web.MetricsPath, "web.telemetry-path", "/metrics",
|
||||
"Path under which to expose metrics.",
|
||||
)
|
||||
cfg.fs.BoolVar(
|
||||
&cfg.web.UseLocalAssets, "web.use-local-assets", false,
|
||||
"Read assets/templates from file instead of binary.",
|
||||
)
|
||||
cfg.fs.StringVar(
|
||||
&cfg.web.UserAssetsPath, "web.user-assets", "",
|
||||
"Path to static asset directory, available at /user.",
|
||||
|
|
1
web/blob/.gitignore
vendored
1
web/blob/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
protocol_buffer.descriptor
|
|
@ -1,63 +0,0 @@
|
|||
package blob
|
||||
|
||||
//go:generate go-bindata -pkg blob -o files.go -ignore '(.*\.map|bootstrap\.js|bootstrap-theme\.css|bootstrap\.css)' templates/... static/...
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/common/log"
|
||||
"github.com/prometheus/common/route"
|
||||
)
|
||||
|
||||
// Sub-directories for templates and static content.
|
||||
const (
|
||||
TemplateFiles = "templates"
|
||||
StaticFiles = "static"
|
||||
)
|
||||
|
||||
var mimeMap = map[string]string{
|
||||
"css": "text/css",
|
||||
"js": "text/javascript",
|
||||
"descriptor": "application/vnd.google.protobuf;proto=google.protobuf.FileDescriptorSet",
|
||||
}
|
||||
|
||||
// GetFile retrieves the content of an embedded file.
|
||||
func GetFile(bucket string, name string) ([]byte, error) {
|
||||
data, err := Asset(fmt.Sprintf("%s/%s", bucket, name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// Handler implements http.Handler.
|
||||
type Handler struct{}
|
||||
|
||||
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := route.Context(r)
|
||||
|
||||
name := strings.Trim(route.Param(ctx, "filepath"), "/")
|
||||
if name == "" {
|
||||
name = "index.html"
|
||||
}
|
||||
|
||||
file, err := GetFile(StaticFiles, name)
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
log.Warn("Could not get file: ", err)
|
||||
}
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
contentType := http.DetectContentType(file)
|
||||
if strings.Contains(contentType, "text/plain") || strings.Contains(contentType, "application/octet-stream") {
|
||||
parts := strings.Split(name, ".")
|
||||
contentType = mimeMap[parts[len(parts)-1]]
|
||||
}
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
w.Header().Set("Cache-Control", "public, max-age=259200")
|
||||
w.Write(file)
|
||||
}
|
1093
web/blob/files.go
1093
web/blob/files.go
File diff suppressed because one or more lines are too long
982
web/ui/bindata.go
Normal file
982
web/ui/bindata.go
Normal file
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 847 B After Width: | Height: | Size: 847 B |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
78
web/web.go
78
web/web.go
|
@ -14,6 +14,7 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -46,7 +47,7 @@ import (
|
|||
"github.com/prometheus/prometheus/version"
|
||||
"github.com/prometheus/prometheus/web/api/legacy"
|
||||
"github.com/prometheus/prometheus/web/api/v1"
|
||||
"github.com/prometheus/prometheus/web/blob"
|
||||
"github.com/prometheus/prometheus/web/ui"
|
||||
)
|
||||
|
||||
var localhostRepresentations = []string{"127.0.0.1", "localhost"}
|
||||
|
@ -181,11 +182,7 @@ func New(st local.Storage, qe *promql.Engine, rm *rules.Manager, status *Prometh
|
|||
|
||||
router.Get("/consoles/*filepath", instrf("consoles", h.consoles))
|
||||
|
||||
if o.UseLocalAssets {
|
||||
router.Get("/static/*filepath", instrf("static", route.FileServe("web/blob/static")))
|
||||
} else {
|
||||
router.Get("/static/*filepath", instrh("static", blob.Handler{}))
|
||||
}
|
||||
router.Get("/static/*filepath", instrf("static", serveStaticAsset))
|
||||
|
||||
if o.UserAssetsPath != "" {
|
||||
router.Get("/user/*filepath", instrf("user", route.FileServe(o.UserAssetsPath)))
|
||||
|
@ -203,6 +200,28 @@ func New(st local.Storage, qe *promql.Engine, rm *rules.Manager, status *Prometh
|
|||
return h
|
||||
}
|
||||
|
||||
func serveStaticAsset(w http.ResponseWriter, req *http.Request) {
|
||||
fp := route.Param(route.Context(req), "filepath")
|
||||
fp = filepath.Join("web/ui/static", fp)
|
||||
|
||||
info, err := ui.AssetInfo(fp)
|
||||
if err != nil {
|
||||
log.With("file", fp).Warn("Could not get file info: ", err)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
file, err := ui.Asset(fp)
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
log.With("file", fp).Warn("Could not get file: ", err)
|
||||
}
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
http.ServeContent(w, req, info.Name(), info.ModTime(), bytes.NewReader(file))
|
||||
}
|
||||
|
||||
// ListenError returns the receive-only channel that signals errors while starting the web server.
|
||||
func (h *Handler) ListenError() <-chan error {
|
||||
return h.listenErrCh
|
||||
|
@ -237,7 +256,7 @@ func (h *Handler) alerts(w http.ResponseWriter, r *http.Request) {
|
|||
rules.StateFiring: "danger",
|
||||
},
|
||||
}
|
||||
h.executeTemplate(w, "alerts", alertStatus)
|
||||
h.executeTemplate(w, "alerts.html", alertStatus)
|
||||
}
|
||||
|
||||
func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -291,14 +310,14 @@ func (h *Handler) consoles(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
func (h *Handler) graph(w http.ResponseWriter, r *http.Request) {
|
||||
h.executeTemplate(w, "graph", nil)
|
||||
h.executeTemplate(w, "graph.html", nil)
|
||||
}
|
||||
|
||||
func (h *Handler) status(w http.ResponseWriter, r *http.Request) {
|
||||
h.statusInfo.mu.RLock()
|
||||
defer h.statusInfo.mu.RUnlock()
|
||||
|
||||
h.executeTemplate(w, "status", struct {
|
||||
h.executeTemplate(w, "status.html", struct {
|
||||
Status *PrometheusStatus
|
||||
Info map[string]string
|
||||
}{
|
||||
|
@ -324,23 +343,6 @@ func (h *Handler) reload(w http.ResponseWriter, r *http.Request) {
|
|||
h.reloadCh <- struct{}{}
|
||||
}
|
||||
|
||||
func (h *Handler) getTemplateFile(name string) (string, error) {
|
||||
if h.options.UseLocalAssets {
|
||||
file, err := ioutil.ReadFile(fmt.Sprintf("web/blob/templates/%s.html", name))
|
||||
if err != nil {
|
||||
log.Errorf("Could not read %s template: %s", name, err)
|
||||
return "", err
|
||||
}
|
||||
return string(file), nil
|
||||
}
|
||||
file, err := blob.GetFile(blob.TemplateFiles, name+".html")
|
||||
if err != nil {
|
||||
log.Errorf("Could not read %s template: %s", name, err)
|
||||
return "", err
|
||||
}
|
||||
return string(file), nil
|
||||
}
|
||||
|
||||
func (h *Handler) consolesPath() string {
|
||||
if _, err := os.Stat(h.options.ConsoleTemplatesPath + "/index.html"); !os.IsNotExist(err) {
|
||||
return h.options.ExternalURL.Path + "/consoles/index.html"
|
||||
|
@ -353,18 +355,6 @@ func (h *Handler) consolesPath() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (h *Handler) getTemplate(name string) (string, error) {
|
||||
baseTmpl, err := h.getTemplateFile("_base")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading base template: %s", err)
|
||||
}
|
||||
pageTmpl, err := h.getTemplateFile(name)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading page template %s: %s", name, err)
|
||||
}
|
||||
return baseTmpl + pageTmpl, nil
|
||||
}
|
||||
|
||||
func tmplFuncs(consolesPath string, opts *Options) template_text.FuncMap {
|
||||
return template_text.FuncMap{
|
||||
"since": time.Since,
|
||||
|
@ -439,6 +429,18 @@ func tmplFuncs(consolesPath string, opts *Options) template_text.FuncMap {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *Handler) getTemplate(name string) (string, error) {
|
||||
baseTmpl, err := ui.Asset("web/ui/templates/_base.html")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading base template: %s", err)
|
||||
}
|
||||
pageTmpl, err := ui.Asset(filepath.Join("web/ui/templates", name))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading page template %s: %s", name, err)
|
||||
}
|
||||
return string(baseTmpl) + string(pageTmpl), nil
|
||||
}
|
||||
|
||||
func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data interface{}) {
|
||||
text, err := h.getTemplate(name)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue