Merge pull request #1804 from pydima/master

web: return status code and error message for config resource
pull/1825/head
Fabian Reinartz 2016-07-15 18:26:19 +09:00 committed by GitHub
commit 0938661db9
6 changed files with 44 additions and 35 deletions

View File

@ -116,7 +116,8 @@ func Main() int {
reloadables = append(reloadables, targetManager, ruleManager, webHandler, notifier) reloadables = append(reloadables, targetManager, ruleManager, webHandler, notifier)
if !reloadConfig(cfg.configFile, reloadables...) { if err := reloadConfig(cfg.configFile, reloadables...); err != nil {
log.Errorf("Error loading config: %s", err)
return 1 return 1
} }
@ -131,9 +132,17 @@ func Main() int {
for { for {
select { select {
case <-hup: case <-hup:
case <-webHandler.Reload(): if err := reloadConfig(cfg.configFile, reloadables...); err != nil {
log.Errorf("Error reloading config: %s", err)
}
case rc := <-webHandler.Reload():
if err := reloadConfig(cfg.configFile, reloadables...); err != nil {
log.Errorf("Error reloading config: %s", err)
rc <- err
} else {
rc <- nil
}
} }
reloadConfig(cfg.configFile, reloadables...)
} }
}() }()
@ -199,13 +208,13 @@ func Main() int {
// Reloadable things can change their internal state to match a new config // Reloadable things can change their internal state to match a new config
// and handle failure gracefully. // and handle failure gracefully.
type Reloadable interface { type Reloadable interface {
ApplyConfig(*config.Config) bool ApplyConfig(*config.Config) error
} }
func reloadConfig(filename string, rls ...Reloadable) (success bool) { func reloadConfig(filename string, rls ...Reloadable) (err error) {
log.Infof("Loading configuration file %s", filename) log.Infof("Loading configuration file %s", filename)
defer func() { defer func() {
if success { if err == nil {
configSuccess.Set(1) configSuccess.Set(1)
configSuccessTime.Set(float64(time.Now().Unix())) configSuccessTime.Set(float64(time.Now().Unix()))
} else { } else {
@ -215,13 +224,16 @@ func reloadConfig(filename string, rls ...Reloadable) (success bool) {
conf, err := config.LoadFile(filename) conf, err := config.LoadFile(filename)
if err != nil { if err != nil {
log.Errorf("Couldn't load configuration (-config.file=%s): %v", filename, err) return fmt.Errorf("couldn't load configuration (-config.file=%s): %v", filename, err)
return false
} }
success = true
// Apply all configs and return the first error if there were any.
for _, rl := range rls { for _, rl := range rls {
success = success && rl.ApplyConfig(conf) if err != nil {
err = rl.ApplyConfig(conf)
} else {
rl.ApplyConfig(conf)
} }
return success }
return err
} }

View File

@ -131,13 +131,12 @@ func New(o *Options) *Notifier {
} }
// ApplyConfig updates the status state as the new config requires. // ApplyConfig updates the status state as the new config requires.
// Returns true on success. func (n *Notifier) ApplyConfig(conf *config.Config) error {
func (n *Notifier) ApplyConfig(conf *config.Config) bool {
n.mtx.Lock() n.mtx.Lock()
defer n.mtx.Unlock() defer n.mtx.Unlock()
n.opts.ExternalLabels = conf.GlobalConfig.ExternalLabels n.opts.ExternalLabels = conf.GlobalConfig.ExternalLabels
return true return nil
} }
const maxBatchSize = 64 const maxBatchSize = 64

View File

@ -160,8 +160,7 @@ func (tm *TargetManager) Pools() map[string]Targets {
// ApplyConfig resets the manager's target providers and job configurations as defined // ApplyConfig resets the manager's target providers and job configurations as defined
// by the new cfg. The state of targets that are valid in the new configuration remains unchanged. // by the new cfg. The state of targets that are valid in the new configuration remains unchanged.
// Returns true on success. func (tm *TargetManager) ApplyConfig(cfg *config.Config) error {
func (tm *TargetManager) ApplyConfig(cfg *config.Config) bool {
tm.mtx.Lock() tm.mtx.Lock()
defer tm.mtx.Unlock() defer tm.mtx.Unlock()
@ -170,7 +169,7 @@ func (tm *TargetManager) ApplyConfig(cfg *config.Config) bool {
if tm.ctx != nil { if tm.ctx != nil {
tm.reload() tm.reload()
} }
return true return nil
} }
// targetSet holds several TargetProviders for which the same scrape configuration // targetSet holds several TargetProviders for which the same scrape configuration

View File

@ -373,8 +373,8 @@ func (m *Manager) Stop() {
} }
// ApplyConfig updates the rule manager's state as the config requires. If // ApplyConfig updates the rule manager's state as the config requires. If
// loading the new rules failed the old rule set is restored. Returns true on success. // loading the new rules failed the old rule set is restored.
func (m *Manager) ApplyConfig(conf *config.Config) bool { func (m *Manager) ApplyConfig(conf *config.Config) error {
m.mtx.Lock() m.mtx.Lock()
defer m.mtx.Unlock() defer m.mtx.Unlock()
@ -384,16 +384,14 @@ func (m *Manager) ApplyConfig(conf *config.Config) bool {
fs, err := filepath.Glob(pat) fs, err := filepath.Glob(pat)
if err != nil { if err != nil {
// The only error can be a bad pattern. // The only error can be a bad pattern.
log.Errorf("Error retrieving rule files for %s: %s", pat, err) return fmt.Errorf("error retrieving rule files for %s: %s", pat, err)
return false
} }
files = append(files, fs...) files = append(files, fs...)
} }
groups, err := m.loadGroups(files...) groups, err := m.loadGroups(files...)
if err != nil { if err != nil {
log.Errorf("Error loading rules, previous rule set restored: %s", err) return fmt.Errorf("error loading rules, previous rule set restored: %s", err)
return false
} }
var wg sync.WaitGroup var wg sync.WaitGroup
@ -433,7 +431,7 @@ func (m *Manager) ApplyConfig(conf *config.Config) bool {
wg.Wait() wg.Wait()
m.groups = groups m.groups = groups
return true return nil
} }
// loadGroups reads groups from a list of files. // loadGroups reads groups from a list of files.

View File

@ -37,13 +37,12 @@ type Storage struct {
} }
// ApplyConfig updates the status state as the new config requires. // ApplyConfig updates the status state as the new config requires.
// Returns true on success. func (s *Storage) ApplyConfig(conf *config.Config) error {
func (s *Storage) ApplyConfig(conf *config.Config) bool {
s.mtx.Lock() s.mtx.Lock()
defer s.mtx.Unlock() defer s.mtx.Unlock()
s.externalLabels = conf.GlobalConfig.ExternalLabels s.externalLabels = conf.GlobalConfig.ExternalLabels
return true return nil
} }
// New returns a new remote Storage. // New returns a new remote Storage.

View File

@ -62,7 +62,7 @@ type Handler struct {
router *route.Router router *route.Router
listenErrCh chan error listenErrCh chan error
quitCh chan struct{} quitCh chan struct{}
reloadCh chan struct{} reloadCh chan chan error
options *Options options *Options
configString string configString string
versionInfo *PrometheusVersion versionInfo *PrometheusVersion
@ -74,15 +74,14 @@ type Handler struct {
} }
// ApplyConfig updates the status state as the new config requires. // ApplyConfig updates the status state as the new config requires.
// Returns true on success. func (h *Handler) ApplyConfig(conf *config.Config) error {
func (h *Handler) ApplyConfig(conf *config.Config) bool {
h.mtx.Lock() h.mtx.Lock()
defer h.mtx.Unlock() defer h.mtx.Unlock()
h.externalLabels = conf.GlobalConfig.ExternalLabels h.externalLabels = conf.GlobalConfig.ExternalLabels
h.configString = conf.String() h.configString = conf.String()
return true return nil
} }
// PrometheusVersion contains build information about Prometheus. // PrometheusVersion contains build information about Prometheus.
@ -124,7 +123,7 @@ func New(
router: router, router: router,
listenErrCh: make(chan error), listenErrCh: make(chan error),
quitCh: make(chan struct{}), quitCh: make(chan struct{}),
reloadCh: make(chan struct{}), reloadCh: make(chan chan error),
options: o, options: o,
versionInfo: version, versionInfo: version,
birth: time.Now(), birth: time.Now(),
@ -225,7 +224,7 @@ func (h *Handler) Quit() <-chan struct{} {
} }
// Reload returns the receive-only channel that signals configuration reload requests. // Reload returns the receive-only channel that signals configuration reload requests.
func (h *Handler) Reload() <-chan struct{} { func (h *Handler) Reload() <-chan chan error {
return h.reloadCh return h.reloadCh
} }
@ -352,8 +351,11 @@ func (h *Handler) quit(w http.ResponseWriter, r *http.Request) {
} }
func (h *Handler) reload(w http.ResponseWriter, r *http.Request) { func (h *Handler) reload(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Reloading configuration file...") rc := make(chan error)
h.reloadCh <- struct{}{} h.reloadCh <- rc
if err := <-rc; err != nil {
http.Error(w, fmt.Sprintf("failed to reload config: %s", err), http.StatusInternalServerError)
}
} }
func (h *Handler) consolesPath() string { func (h *Handler) consolesPath() string {