mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
Define dependencies for web. stack concretely.
This commit destroys the use of AppState, which makes passing concrete state along to various serving components onerous.
This commit is contained in:
parent
cfc3b1053d
commit
3b9b1c6ab4
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -21,5 +21,11 @@ _cgo_*
|
|||
core
|
||||
|
||||
*-stamp
|
||||
prometheus.build
|
||||
prometheus
|
||||
|
||||
.#*
|
||||
command-line-arguments.test
|
||||
*BACKUP*
|
||||
*BASE*
|
||||
*LOCAL*
|
||||
*REMOTE*
|
||||
|
|
36
Makefile
36
Makefile
|
@ -11,36 +11,19 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
TEST_ARTIFACTS = prometheus prometheus.build search_index
|
||||
TEST_ARTIFACTS = prometheus search_index
|
||||
|
||||
include Makefile.INCLUDE
|
||||
|
||||
REV := $(shell git rev-parse --short HEAD)
|
||||
BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
||||
HOSTNAME := $(shell hostname -f)
|
||||
BUILD_DATE := $(shell date +%Y%m%d-%H:%M:%S)
|
||||
BUILDFLAGS := -ldflags \
|
||||
" -X main.buildVersion $(REV)\
|
||||
-X main.buildBranch $(BRANCH)\
|
||||
-X main.buildUser $(USER)@$(HOSTNAME)\
|
||||
-X main.buildDate $(BUILD_DATE)\
|
||||
-X main.goVersion $(GO_VERSION)\
|
||||
-X main.leveldbVersion $(LEVELDB_VERSION)\
|
||||
-X main.protobufVersion $(PROTOCOL_BUFFERS_VERSION)\
|
||||
-X main.snappyVersion $(SNAPPY_VERSION)"
|
||||
|
||||
all: test
|
||||
|
||||
advice:
|
||||
go tool vet .
|
||||
|
||||
binary: build
|
||||
go build $(BUILDFLAGS) -o prometheus.build
|
||||
go build $(BUILDFLAGS) .
|
||||
|
||||
build: preparation config model web
|
||||
go build $(BUILDFLAGS) .
|
||||
|
||||
clean:
|
||||
$(MAKE) -C build clean
|
||||
|
@ -72,11 +55,14 @@ preparation: source_path
|
|||
$(MAKE) -C build
|
||||
|
||||
run: binary
|
||||
./prometheus.build $(ARGUMENTS)
|
||||
./prometheus $(ARGUMENTS)
|
||||
|
||||
search_index:
|
||||
godoc -index -write_index -index_files='search_index'
|
||||
|
||||
server: config model preparation
|
||||
$(MAKE) -C server
|
||||
|
||||
# source_path is responsible for ensuring that the builder has not done anything
|
||||
# stupid like working on Prometheus outside of ${GOPATH}.
|
||||
source_path:
|
||||
|
@ -84,15 +70,7 @@ source_path:
|
|||
[ -d "$(FULL_GOPATH)" ]
|
||||
|
||||
test: build
|
||||
go test ./appstate/... $(GO_TEST_FLAGS)
|
||||
go test ./coding/... $(GO_TEST_FLAGS)
|
||||
go test ./config/... $(GO_TEST_FLAGS)
|
||||
go test ./model/... $(GO_TEST_FLAGS)
|
||||
go test ./retrieval/... $(GO_TEST_FLAGS)
|
||||
go test ./rules/... $(GO_TEST_FLAGS)
|
||||
go test ./storage/... $(GO_TEST_FLAGS)
|
||||
go test ./utility/... $(GO_TEST_FLAGS)
|
||||
go test ./web/... $(GO_TEST_FLAGS)
|
||||
go test ./... $(GO_TEST_FLAGS)
|
||||
|
||||
web: preparation config model
|
||||
$(MAKE) -C web
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# -*- Mode: makefile -*-
|
||||
|
||||
# Copyright 2013 Prometheus Team
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
@ -52,3 +54,17 @@ BREW_INSTALL := brew install
|
|||
# By default, wget sets the creation time to match the server's, which throws
|
||||
# off Make. :-(
|
||||
WGET := wget --no-use-server-timestamps -c
|
||||
|
||||
REV := $(shell git rev-parse --short HEAD)
|
||||
BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
||||
HOSTNAME := $(shell hostname -f)
|
||||
BUILD_DATE := $(shell date +%Y%m%d-%H:%M:%S)
|
||||
BUILDFLAGS := -ldflags \
|
||||
" -X main.buildVersion $(REV)\
|
||||
-X main.buildBranch $(BRANCH)\
|
||||
-X main.buildUser $(USER)@$(HOSTNAME)\
|
||||
-X main.buildDate $(BUILD_DATE)\
|
||||
-X main.goVersion $(GO_VERSION)\
|
||||
-X main.leveldbVersion $(LEVELDB_VERSION)\
|
||||
-X main.protobufVersion $(PROTOCOL_BUFFERS_VERSION)\
|
||||
-X main.snappyVersion $(SNAPPY_VERSION)"
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright 2013 Prometheus Team
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package appstate
|
||||
|
||||
import (
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/retrieval"
|
||||
"github.com/prometheus/prometheus/rules"
|
||||
"github.com/prometheus/prometheus/storage/metric"
|
||||
)
|
||||
|
||||
// ApplicationState is an encapsulation of all relevant Prometheus application
|
||||
// runtime state. It enables simpler passing of this state to components that
|
||||
// require it.
|
||||
type ApplicationState struct {
|
||||
Config config.Config
|
||||
RuleManager rules.RuleManager
|
||||
Storage metric.TieredStorage
|
||||
TargetManager retrieval.TargetManager
|
||||
BuildInfo map[string]string
|
||||
CurationState chan metric.CurationState
|
||||
}
|
63
main.go
63
main.go
|
@ -15,7 +15,6 @@ package main
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"github.com/prometheus/prometheus/appstate"
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/retrieval"
|
||||
"github.com/prometheus/prometheus/retrieval/format"
|
||||
|
@ -23,6 +22,7 @@ import (
|
|||
"github.com/prometheus/prometheus/rules/ast"
|
||||
"github.com/prometheus/prometheus/storage/metric"
|
||||
"github.com/prometheus/prometheus/web"
|
||||
"github.com/prometheus/prometheus/web/api"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
@ -42,10 +42,10 @@ var (
|
|||
)
|
||||
|
||||
type prometheus struct {
|
||||
storage metric.TieredStorage
|
||||
// TODO: Refactor channels to work with arrays of results for better chunking.
|
||||
scrapeResults chan format.Result
|
||||
curationState chan metric.CurationState
|
||||
ruleResults chan *rules.Result
|
||||
storage metric.TieredStorage
|
||||
scrapeResults chan format.Result
|
||||
}
|
||||
|
||||
func (p prometheus) interruptHandler() {
|
||||
|
@ -60,9 +60,8 @@ func (p prometheus) interruptHandler() {
|
|||
}
|
||||
|
||||
func (p prometheus) close() {
|
||||
close(p.curationState)
|
||||
p.storage.Close()
|
||||
close(p.scrapeResults)
|
||||
close(p.ruleResults)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -92,22 +91,46 @@ func main() {
|
|||
|
||||
scrapeResults := make(chan format.Result, *scrapeResultsQueueCapacity)
|
||||
ruleResults := make(chan *rules.Result, *ruleResultsQueueCapacity)
|
||||
curationState := make(chan metric.CurationState, 1)
|
||||
|
||||
// Queue depth will need to be exposed
|
||||
targetManager := retrieval.NewTargetManager(scrapeResults, *concurrentRetrievalAllowance)
|
||||
targetManager.AddTargetsFromConfig(conf)
|
||||
|
||||
statusHandler := &web.StatusHandler{
|
||||
BuildInfo: BuildInfo,
|
||||
Config: &conf,
|
||||
CurationState: curationState,
|
||||
// Furnish the default status.
|
||||
PrometheusStatus: &web.PrometheusStatus{},
|
||||
TargetManager: targetManager,
|
||||
}
|
||||
|
||||
// The closing of curationState implicitly closes this routine.
|
||||
go statusHandler.ServeRequestsForever()
|
||||
|
||||
metricsService := &api.MetricsService{
|
||||
Config: &conf,
|
||||
TargetManager: targetManager,
|
||||
Storage: ts,
|
||||
}
|
||||
|
||||
webService := &web.WebService{
|
||||
StatusHandler: statusHandler,
|
||||
MetricsHandler: metricsService,
|
||||
}
|
||||
|
||||
prometheus := prometheus{
|
||||
storage: *ts,
|
||||
scrapeResults: scrapeResults,
|
||||
curationState: curationState,
|
||||
ruleResults: ruleResults,
|
||||
scrapeResults: scrapeResults,
|
||||
storage: *ts,
|
||||
}
|
||||
defer prometheus.close()
|
||||
|
||||
go ts.Serve()
|
||||
go prometheus.interruptHandler()
|
||||
|
||||
// Queue depth will need to be exposed
|
||||
|
||||
targetManager := retrieval.NewTargetManager(scrapeResults, *concurrentRetrievalAllowance)
|
||||
targetManager.AddTargetsFromConfig(conf)
|
||||
|
||||
ast.SetStorage(*ts)
|
||||
|
||||
ruleManager := rules.NewRuleManager(ruleResults, conf.EvaluationInterval())
|
||||
|
@ -116,16 +139,12 @@ func main() {
|
|||
log.Fatalf("Error loading rule files: %v", err)
|
||||
}
|
||||
|
||||
appState := &appstate.ApplicationState{
|
||||
BuildInfo: BuildInfo,
|
||||
Config: conf,
|
||||
CurationState: make(chan metric.CurationState),
|
||||
RuleManager: ruleManager,
|
||||
Storage: *ts,
|
||||
TargetManager: targetManager,
|
||||
go func() {
|
||||
err := webService.ServeForever()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
web.StartServing(appState)
|
||||
}()
|
||||
|
||||
// TODO(all): Migrate this into prometheus.serve().
|
||||
for {
|
||||
|
|
|
@ -29,4 +29,4 @@ clean:
|
|||
rm -rf generated/*
|
||||
-rm -f $(MAKE_ARTIFACTS)
|
||||
|
||||
.PHONY: generated
|
||||
.PHONY: clean generated
|
||||
|
|
|
@ -11,13 +11,15 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
all: blob
|
||||
all: blob-stamp
|
||||
|
||||
blob: static/generated/protocol_buffer.descriptor
|
||||
blob-stamp: static/generated/protocol_buffer.descriptor
|
||||
$(MAKE) -C blob
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
$(MAKE) -C blob clean
|
||||
-rm -f *-stamp
|
||||
|
||||
static/generated:
|
||||
mkdir -vp static/generated
|
||||
|
@ -25,4 +27,4 @@ static/generated:
|
|||
static/generated/protocol_buffer.descriptor: static/generated ../model/generated/descriptor.blob
|
||||
cp -f ../model/generated/descriptor.blob $@
|
||||
|
||||
.PHONY: blob clean
|
||||
.PHONY: clean
|
||||
|
|
|
@ -15,7 +15,9 @@ package api
|
|||
|
||||
import (
|
||||
"code.google.com/p/gorest"
|
||||
"github.com/prometheus/prometheus/appstate"
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/retrieval"
|
||||
"github.com/prometheus/prometheus/storage/metric"
|
||||
"github.com/prometheus/prometheus/utility"
|
||||
)
|
||||
|
||||
|
@ -27,13 +29,9 @@ type MetricsService struct {
|
|||
metrics gorest.EndPoint `method:"GET" path:"/metrics" output:"string"`
|
||||
|
||||
setTargets gorest.EndPoint `method:"PUT" path:"/jobs/{jobName:string}/targets" postdata:"[]TargetGroup"`
|
||||
|
||||
appState *appstate.ApplicationState
|
||||
time utility.Time
|
||||
}
|
||||
|
||||
func NewMetricsService(appState *appstate.ApplicationState) *MetricsService {
|
||||
return &MetricsService{
|
||||
appState: appState,
|
||||
}
|
||||
Config *config.Config
|
||||
TargetManager retrieval.TargetManager
|
||||
Storage *metric.TieredStorage
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ func (serv MetricsService) QueryRange(expr string, end int64, duration int64, st
|
|||
}
|
||||
|
||||
func (serv MetricsService) Metrics() string {
|
||||
metricNames, err := serv.appState.Storage.GetAllValuesForLabel(model.MetricNameLabel)
|
||||
metricNames, err := serv.Storage.GetAllValuesForLabel(model.MetricNameLabel)
|
||||
rb := serv.ResponseBuilder()
|
||||
serv.setAccessControlHeaders(rb)
|
||||
rb.SetContentType(gorest.Application_Json)
|
||||
|
|
|
@ -26,11 +26,15 @@ type TargetGroup struct {
|
|||
}
|
||||
|
||||
func (serv MetricsService) SetTargets(targetGroups []TargetGroup, jobName string) {
|
||||
if job := serv.appState.Config.GetJobByName(jobName); job == nil {
|
||||
job := serv.Config.GetJobByName(jobName)
|
||||
if job == nil {
|
||||
rb := serv.ResponseBuilder()
|
||||
rb.SetResponseCode(http.StatusNotFound)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
newTargets := []retrieval.Target{}
|
||||
|
||||
for _, targetGroup := range targetGroups {
|
||||
// Do mandatory map type conversion due to Go shortcomings.
|
||||
baseLabels := model.LabelSet{
|
||||
|
@ -45,6 +49,8 @@ func (serv MetricsService) SetTargets(targetGroups []TargetGroup, jobName string
|
|||
newTargets = append(newTargets, newTarget)
|
||||
}
|
||||
}
|
||||
serv.appState.TargetManager.ReplaceTargets(*job, newTargets, serv.appState.Config.ScrapeInterval())
|
||||
}
|
||||
|
||||
// BUG(julius): Validate that this ScrapeInterval is in fact the proper one
|
||||
// for the job.
|
||||
serv.TargetManager.ReplaceTargets(*job, newTargets, serv.Config.ScrapeInterval())
|
||||
}
|
||||
|
|
1
web/blob/.gitignore
vendored
1
web/blob/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
files.go
|
||||
protocol_buffer.descriptor
|
||||
|
|
|
@ -15,27 +15,32 @@ package web
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"github.com/prometheus/prometheus/appstate"
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/retrieval"
|
||||
"github.com/prometheus/prometheus/storage/metric"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type PrometheusStatus struct {
|
||||
BuildInfo map[string]string
|
||||
Config string
|
||||
Curation metric.CurationState
|
||||
Flags map[string]string
|
||||
Rules string
|
||||
TargetPools map[string]*retrieval.TargetPool
|
||||
BuildInfo map[string]string
|
||||
Flags map[string]string
|
||||
Curation metric.CurationState
|
||||
}
|
||||
|
||||
type StatusHandler struct {
|
||||
appState *appstate.ApplicationState
|
||||
BuildInfo map[string]string
|
||||
Config *config.Config
|
||||
CurationState chan metric.CurationState
|
||||
PrometheusStatus *PrometheusStatus
|
||||
TargetManager retrieval.TargetManager
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
func (h *StatusHandler) Run() {
|
||||
func (h *StatusHandler) ServeRequestsForever() {
|
||||
flags := map[string]string{}
|
||||
|
||||
flag.VisitAll(func(f *flag.Flag) {
|
||||
|
@ -43,19 +48,22 @@ func (h *StatusHandler) Run() {
|
|||
})
|
||||
|
||||
h.PrometheusStatus = &PrometheusStatus{
|
||||
Config: h.appState.Config.String(),
|
||||
Rules: "TODO: list rules here",
|
||||
TargetPools: h.appState.TargetManager.Pools(),
|
||||
BuildInfo: h.appState.BuildInfo,
|
||||
BuildInfo: h.BuildInfo,
|
||||
Config: h.Config.String(),
|
||||
Flags: flags,
|
||||
Rules: "TODO: list rules here",
|
||||
TargetPools: h.TargetManager.Pools(),
|
||||
}
|
||||
|
||||
// Law of Demeter :-(
|
||||
for state := range h.appState.CurationState {
|
||||
for state := range h.CurationState {
|
||||
h.Lock()
|
||||
h.PrometheusStatus.Curation = state
|
||||
h.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (h StatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
func (h *StatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
executeTemplate(w, "status", h.PrometheusStatus)
|
||||
}
|
||||
|
|
18
web/web.go
18
web/web.go
|
@ -19,7 +19,6 @@ import (
|
|||
"fmt"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/exp"
|
||||
"github.com/prometheus/prometheus/appstate"
|
||||
"github.com/prometheus/prometheus/web/api"
|
||||
"github.com/prometheus/prometheus/web/blob"
|
||||
"html/template"
|
||||
|
@ -34,8 +33,13 @@ var (
|
|||
useLocalAssets = flag.Bool("useLocalAssets", false, "Read assets/templates from file instead of binary.")
|
||||
)
|
||||
|
||||
func StartServing(appState *appstate.ApplicationState) {
|
||||
gorest.RegisterService(api.NewMetricsService(appState))
|
||||
type WebService struct {
|
||||
StatusHandler *StatusHandler
|
||||
MetricsHandler *api.MetricsService
|
||||
}
|
||||
|
||||
func (w WebService) ServeForever() error {
|
||||
gorest.RegisterService(w.MetricsHandler)
|
||||
|
||||
// TODO(julius): This will need to be rewritten once the exp package provides
|
||||
// the coarse mux behaviors via a wrapper function.
|
||||
|
@ -44,10 +48,7 @@ func StartServing(appState *appstate.ApplicationState) {
|
|||
exp.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
|
||||
exp.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
|
||||
|
||||
statusHandler := &StatusHandler{appState: appState}
|
||||
go statusHandler.Run()
|
||||
|
||||
exp.Handle("/", statusHandler)
|
||||
exp.Handle("/", w.StatusHandler)
|
||||
exp.HandleFunc("/graph", graphHandler)
|
||||
|
||||
exp.Handle("/api/", gorest.Handle())
|
||||
|
@ -59,7 +60,8 @@ func StartServing(appState *appstate.ApplicationState) {
|
|||
}
|
||||
|
||||
log.Printf("listening on %s", *listenAddress)
|
||||
go http.ListenAndServe(*listenAddress, exp.DefaultCoarseMux)
|
||||
|
||||
return http.ListenAndServe(*listenAddress, exp.DefaultCoarseMux)
|
||||
}
|
||||
|
||||
func getTemplate(name string) (t *template.Template, err error) {
|
||||
|
|
Loading…
Reference in a new issue