Skip to content

Commit

Permalink
ui: add new React UI from Prometheus (#2412)
Browse files Browse the repository at this point in the history
* ui: add React UI from upstream Prometheus

Signed-off-by: Adrien Fillon <adrien.fillon@gmail.com>

* ui: incorporate new changes from Prometheus React UI

Signed-off-by: Prem Kumar <prmsrswt@gmail.com>

* ui: adapted the React UI to Thanos

Signed-off-by: Prem Kumar <prmsrswt@gmail.com>

Co-authored-by: Adrien Fillon <adrien.fillon@gmail.com>
Co-authored-by: Giedrius Statkevičius <giedriuswork@gmail.com>
  • Loading branch information
3 people committed May 11, 2020
1 parent a384c43 commit f692134
Show file tree
Hide file tree
Showing 114 changed files with 23,610 additions and 98 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
exit
fi
taskset 2 make test-ci
taskset 2 make react-app-test
# Cross build is needed for publish_release but needs to be done outside of docker.
cross_build:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ website/public/
website/docs-pre-processed/
!website/data

# React build assets
pkg/ui/static/react

tmp/bin
examples/tmp/

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ We use *breaking* word for marking changes that are not backward compatible (rel

- [#2502](https://github.com/thanos-io/thanos/pull/2502) Added `hints` field to `SeriesResponse`. Hints in an opaque data structure that can be used to carry additional information from the store and its content is implementation specific.
- [#2521](https://github.com/thanos-io/thanos/pull/2521) Sidecar: add `thanos_sidecar_reloader_reloads_failed_total`, `thanos_sidecar_reloader_reloads_total`, `thanos_sidecar_reloader_watch_errors_total`, `thanos_sidecar_reloader_watch_events_total` and `thanos_sidecar_reloader_watches` metrics.
- [#2412](https://github.com/thanos-io/thanos/pull/2412) ui: add React UI from Prometheus upstream. Currently only accessible from Query component as only `/graph` endpoint is migrated.
- [#2532](https://github.com/thanos-io/thanos/pull/2532) Store: Added hidden option for experimental caching bucket, that can cache chunks into shared memcached. This can speed up querying and reduce number of requests to object storage.

### Changed
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ The following section explains various suggestions and procedures to note during

* It is strongly recommended that you use Linux distributions systems or OSX for development.
* Go 1.13.9 or newer installed.
* For React UI, you will need a working NodeJS environment and the Yarn package manager to compile the Web UI assets

### First Steps

Expand Down
72 changes: 54 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ MINIO_SERVER ?=$(GOBIN)/minio-$(MINIO_SERVER_VERSION)
FAILLINT_VERSION ?= v1.2.0
FAILLINT ?=$(GOBIN)/faillint-$(FAILLINT_VERSION)

REACT_APP_PATH = pkg/ui/react-app
REACT_APP_SOURCE_FILES = $(wildcard $(REACT_APP_PATH)/public/* $(REACT_APP_PATH)/src/* $(REACT_APP_PATH)/tsconfig.json)
REACT_APP_OUTPUT_DIR = pkg/ui/static/react
REACT_APP_NODE_MODULES_PATH = $(REACT_APP_PATH)/node_modules

# fetch_go_bin_version downloads (go gets) the binary from specific version and installs it in $(GOBIN)/<bin>-<version>
# arguments:
# $(1): Install path. (e.g github.com/campoy/embedmd)
Expand All @@ -95,9 +100,9 @@ define fetch_go_bin_version

@echo ">> fetching $(1)@$(2) revision/version"
@if [ ! -d '$(TMP_GOPATH)/src/$(1)' ]; then \
GOPATH='$(TMP_GOPATH)' GO111MODULE='off' go get -d -u '$(1)/...'; \
GOPATH='$(TMP_GOPATH)' GO111MODULE='off' go get -d -u '$(1)/...'; \
else \
CDPATH='' cd -- '$(TMP_GOPATH)/src/$(1)' && git fetch; \
CDPATH='' cd -- '$(TMP_GOPATH)/src/$(1)' && git fetch; \
fi
@CDPATH='' cd -- '$(TMP_GOPATH)/src/$(1)' && git checkout -f -q '$(2)'
@echo ">> installing $(1)@$(2)"
Expand All @@ -110,19 +115,19 @@ endef
define require_clean_work_tree
@git update-index -q --ignore-submodules --refresh

@if ! git diff-files --quiet --ignore-submodules --; then \
echo >&2 "cannot $1: you have unstaged changes."; \
git diff-files --name-status -r --ignore-submodules -- >&2; \
echo >&2 "Please commit or stash them."; \
exit 1; \
fi
@if ! git diff-files --quiet --ignore-submodules --; then \
echo >&2 "cannot $1: you have unstaged changes."; \
git diff-files --name-status -r --ignore-submodules -- >&2; \
echo >&2 "Please commit or stash them."; \
exit 1; \
fi

@if ! git diff-index --cached --quiet HEAD --ignore-submodules --; then \
echo >&2 "cannot $1: your index contains uncommitted changes."; \
git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2; \
echo >&2 "Please commit or stash them."; \
exit 1; \
fi
@if ! git diff-index --cached --quiet HEAD --ignore-submodules --; then \
echo >&2 "cannot $1: your index contains uncommitted changes."; \
git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2; \
echo >&2 "Please commit or stash them."; \
exit 1; \
fi

endef

Expand All @@ -132,15 +137,42 @@ help: ## Displays help.
.PHONY: all
all: format build

$(REACT_APP_NODE_MODULES_PATH): $(REACT_APP_PATH)/package.json $(REACT_APP_PATH)/yarn.lock
cd $(REACT_APP_PATH) && yarn --frozen-lockfile

$(REACT_APP_OUTPUT_DIR): $(REACT_APP_NODE_MODULES_PATH) $(REACT_APP_SOURCE_FILES)
@echo ">> building React app"
@./scripts/build-react-app.sh

.PHONY: assets
assets: # Repacks all static assets into go file for easier deploy.
assets: $(GOBINDATA)
assets: $(GOBINDATA) $(REACT_APP_OUTPUT_DIR)
@echo ">> deleting asset file"
@rm pkg/ui/bindata.go || true
@echo ">> writing assets"
@$(GOBINDATA) $(bindata_flags) -pkg ui -o pkg/ui/bindata.go -ignore '(.*\.map|bootstrap\.js|bootstrap-theme\.css|bootstrap\.css)' pkg/ui/templates/... pkg/ui/static/...
@go fmt ./pkg/ui

.PHONY: react-app-lint
react-app-lint: $(REACT_APP_NODE_MODULES_PATH)
@echo ">> running React app linting"
cd $(REACT_APP_PATH) && yarn lint:ci

.PHONY: react-app-lint-fix
react-app-lint-fix:
@echo ">> running React app linting and fixing errors where possible"
cd $(REACT_APP_PATH) && yarn lint

.PHONY: react-app-test
react-app-test: | $(REACT_APP_NODE_MODULES_PATH) react-app-lint
@echo ">> running React app tests"
cd $(REACT_APP_PATH) && export CI=true && yarn test --no-watch --coverage

.PHONY: react-app-start
react-app-start: $(REACT_APP_NODE_MODULES_PATH)
@echo ">> running React app"
cd $(REACT_APP_PATH) && yarn start

.PHONY: build
build: ## Builds Thanos binary using `promu`.
build: check-git deps $(PROMU)
Expand Down Expand Up @@ -294,13 +326,17 @@ web: web-pre-process $(HUGO)
# TODO(bwplotka): Make it --gc
@cd $(WEB_DIR) && HUGO_ENV=production $(HUGO) --config hugo.yaml --minify -v -b $(WEBSITE_BASE_URL)

.PHONY:lint
lint: ## Runs various static analysis against our code.
lint: go-lint react-app-lint

# PROTIP:
# Add
# --cpu-profile-path string Path to CPU profile output file
# --mem-profile-path string Path to memory profile output file
# to debug big allocations during linting.
lint: ## Runs various static analysis against our code.
lint: check-git deps $(GOLANGCILINT) $(MISSPELL) $(FAILLINT)
.PHONY: go-lint
go-lint: check-git deps $(GOLANGCILINT) $(MISSPELL) $(FAILLINT)
$(call require_clean_work_tree,"detected not clean master before running lint")
@echo ">> verifying modules being imported"
@# TODO(bwplotka): Add, Printf, DefaultRegisterer, NewGaugeFunc and MustRegister once exception are accepted. Add fmt.{Errorf}=github.com/pkg/errors.{Errorf} once https://github.com/fatih/faillint/issues/10 is addressed.
Expand All @@ -317,7 +353,7 @@ NewCounterVec,NewCounterVec,NewGauge,NewGaugeVec,NewGaugeFunc,NewHistorgram,NewH
@echo ">> linting all of the Go files GOGC=${GOGC}"
@$(GOLANGCILINT) run
@echo ">> detecting misspells"
@find . -type f | grep -v vendor/ | grep -vE '\./\..*' | xargs $(MISSPELL) -error
@find . -type f | grep -v vendor/ | grep -v pkg/ui/react-app/node_modules | grep -v pkg/ui/static | grep -vE '\./\..*' | xargs $(MISSPELL) -error
@echo ">> detecting white noise"
@find . -type f \( -name "*.md" -o -name "*.go" \) | SED_BIN="$(SED)" xargs scripts/cleanup-white-noise.sh
$(call require_clean_work_tree,"detected white noise")
Expand Down
2 changes: 1 addition & 1 deletion cmd/thanos/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ func runQuery(
// TODO(bplotka in PR #513 review): pass all flags, not only the flags needed by prefix rewriting.
ui.NewQueryUI(logger, reg, stores, webExternalPrefix, webPrefixHeaderName).Register(router, ins)

api := v1.NewAPI(logger, reg, engine, queryableCreator, enableAutodownsampling, enablePartialResponse, replicaLabels, instantDefaultMaxSourceResolution)
api := v1.NewAPI(logger, reg, stores, engine, queryableCreator, enableAutodownsampling, enablePartialResponse, replicaLabels, instantDefaultMaxSourceResolution)

api.Register(router.WithPrefix("/api/v1"), tracer, logger, ins)

Expand Down
13 changes: 13 additions & 0 deletions pkg/query/api/v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ type API struct {
enablePartialResponse bool
replicaLabels []string
reg prometheus.Registerer
storeSet *query.StoreSet
defaultInstantQueryMaxSourceResolution time.Duration

now func() time.Time
Expand All @@ -116,6 +117,7 @@ type API struct {
func NewAPI(
logger log.Logger,
reg *prometheus.Registry,
storeSet *query.StoreSet,
qe *promql.Engine,
c query.QueryableCreator,
enableAutodownsampling bool,
Expand All @@ -131,6 +133,7 @@ func NewAPI(
enablePartialResponse: enablePartialResponse,
replicaLabels: replicaLabels,
reg: reg,
storeSet: storeSet,
defaultInstantQueryMaxSourceResolution: defaultInstantQueryMaxSourceResolution,

now: time.Now,
Expand Down Expand Up @@ -168,6 +171,8 @@ func (api *API) Register(r *route.Router, tracer opentracing.Tracer, logger log.

r.Get("/labels", instr("label_names", api.labelNames))
r.Post("/labels", instr("label_names", api.labelNames))

r.Get("/stores", instr("stores", api.stores))
}

type queryData struct {
Expand Down Expand Up @@ -626,3 +631,11 @@ func (api *API) labelNames(r *http.Request) (interface{}, []error, *ApiError) {

return names, warnings, nil
}

func (api *API) stores(r *http.Request) (interface{}, []error, *ApiError) {
statuses := make(map[string][]query.StoreStatus)
for _, status := range api.storeSet.GetStoreStatus() {
statuses[status.StoreType.String()] = append(statuses[status.StoreType.String()], status)
}
return statuses, nil, nil
}
14 changes: 7 additions & 7 deletions pkg/query/storeset.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ type StoreSpec interface {
}

type StoreStatus struct {
Name string
LastCheck time.Time
LastError error
LabelSets []storepb.LabelSet
StoreType component.StoreAPI
MinTime int64
MaxTime int64
Name string `json:"name"`
LastCheck time.Time `json:"last_check"`
LastError error `json:"last_error"`
LabelSets []storepb.LabelSet `json:"label_sets"`
StoreType component.StoreAPI `json:"store_type"`
MinTime int64 `json:"min_time"`
MaxTime int64 `json:"max_time"`
}

type grpcStoreSpec struct {
Expand Down
Loading

0 comments on commit f692134

Please sign in to comment.