2013-08-02 15:22:26 +00:00
|
|
|
// 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 config
|
|
|
|
|
|
|
|
import (
|
2013-08-27 13:32:08 +00:00
|
|
|
"github.com/golang/glog"
|
2013-08-02 15:22:26 +00:00
|
|
|
"github.com/howeyc/fsnotify"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ReloadCallback func(*Config)
|
|
|
|
|
|
|
|
type Watcher interface {
|
|
|
|
Watch(c ReloadCallback)
|
|
|
|
}
|
|
|
|
|
|
|
|
type fileWatcher struct {
|
|
|
|
fileName string
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewFileWatcher(fileName string) *fileWatcher {
|
|
|
|
return &fileWatcher{
|
|
|
|
fileName: fileName,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *fileWatcher) Watch(cb ReloadCallback) {
|
|
|
|
watcher, err := fsnotify.NewWatcher()
|
|
|
|
if err != nil {
|
2013-08-27 13:32:08 +00:00
|
|
|
glog.Fatal(err)
|
2013-08-02 15:22:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err = watcher.WatchFlags(w.fileName, fsnotify.FSN_MODIFY)
|
|
|
|
if err != nil {
|
2013-08-27 13:32:08 +00:00
|
|
|
glog.Fatal(err)
|
2013-08-02 15:22:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case ev := <-watcher.Event:
|
2013-08-27 13:32:08 +00:00
|
|
|
glog.Infof("Config file changed (%s), attempting reload", ev)
|
2013-08-02 15:22:26 +00:00
|
|
|
conf, err := LoadFromFile(w.fileName)
|
|
|
|
if err != nil {
|
2013-08-27 13:32:08 +00:00
|
|
|
glog.Error("Error loading new config: ", err)
|
2014-10-27 13:53:31 +00:00
|
|
|
failedConfigReloads.Inc()
|
2013-08-02 15:22:26 +00:00
|
|
|
} else {
|
|
|
|
cb(&conf)
|
2013-08-27 13:32:08 +00:00
|
|
|
glog.Info("Config reloaded successfully")
|
2014-10-27 13:53:31 +00:00
|
|
|
configReloads.Inc()
|
2013-08-02 15:22:26 +00:00
|
|
|
}
|
|
|
|
// Re-add the file watcher since it can get lost on some changes. E.g.
|
|
|
|
// saving a file with vim results in a RENAME-MODIFY-DELETE event
|
|
|
|
// sequence, after which the newly written file is no longer watched.
|
|
|
|
err = watcher.WatchFlags(w.fileName, fsnotify.FSN_MODIFY)
|
|
|
|
case err := <-watcher.Error:
|
2013-08-27 13:32:08 +00:00
|
|
|
glog.Error("Error watching config: ", err)
|
2013-08-02 15:22:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|