Rainbond/monitor/prometheus/manager.go
2018-06-02 10:45:11 +08:00

178 lines
4.4 KiB
Go

// Copyright (C) 2014-2018 Goodrain Co., Ltd.
// RAINBOND, Application Management Platform
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package prometheus
import (
"fmt"
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/cmd/monitor/option"
discover3 "github.com/goodrain/rainbond/discover.v2"
"gopkg.in/yaml.v2"
"io/ioutil"
"net/http"
"sync"
"time"
"os"
"syscall"
)
type Manager struct {
ApiUrl string
Opt *option.Config
Config *Config
Process *os.Process
Registry *discover3.KeepAlive
httpClient *http.Client
l *sync.Mutex
}
func NewManager(config *option.Config) *Manager {
client := &http.Client{
Timeout: time.Second * 3,
}
reg, err := discover3.CreateKeepAlive(config.EtcdEndpoints, "prometheus", "http", config.BindIp, config.Port)
if err != nil {
panic(err)
}
m := &Manager{
ApiUrl: fmt.Sprintf("http://127.0.0.1:%d", config.Port),
Opt: config,
Config: &Config{},
Registry: reg,
httpClient: client,
l: &sync.Mutex{},
}
m.LoadConfig()
return m
}
func (p *Manager) StartDaemon() {
logrus.Info("Start daemon for prometheus.")
procAttr := &os.ProcAttr{
Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
}
process, err := os.StartProcess("/bin/prometheus", p.Opt.Args, procAttr)
if err != nil {
if err != nil {
logrus.Error("Can not start prometheus daemon: ", err)
os.Exit(11)
}
}
p.Process = process
// waiting started
for i := 0; i < 15; i++ {
time.Sleep(time.Second)
if _, err = os.FindProcess(process.Pid); err == nil {
logrus.Info("The prometheus daemon is started.")
return
}
}
logrus.Error("Timeout start prometheus daemon: ", err)
os.Exit(13)
}
func (p *Manager) StopDaemon() {
logrus.Info("Stopping prometheus daemon ...")
//exec.Command("sh", "-c", "kill `pgrep prometheus` ; while pgrep prometheus; do sleep 1; done").Run()
p.Process.Kill()
p.Process.Wait()
logrus.Info("Stopped prometheus daemon.")
}
func (p *Manager) RestartDaemon() error {
logrus.Debug("Restart daemon for prometheus.")
//request, err := http.NewRequest("POST", p.ApiUrl+"/-/reload", nil)
//if err != nil {
// logrus.Error("Create request to load config error: ", err)
// return err
//}
//
//_, err = p.httpClient.Do(request)
if err := p.Process.Signal(syscall.SIGHUP); err != nil {
logrus.Error("Failed to restart daemon for prometheus: ", err)
return err
}
return nil
}
func (p *Manager) LoadConfig() error {
logrus.Info("Load prometheus config file.")
context, err := ioutil.ReadFile(p.Opt.ConfigFile)
if err != nil {
logrus.Error("Failed to read prometheus config file: ", err)
return err
}
if err := yaml.Unmarshal(context, p.Config); err != nil {
logrus.Error("Unmarshal prometheus config string to object error.", err.Error())
return err
}
logrus.Debugf("Loaded config file to memory: %+v", p.Config) //TODO
return nil
}
func (p *Manager) SaveConfig() error {
logrus.Debug("Save prometheus config file.")
data, err := yaml.Marshal(p.Config)
if err != nil {
logrus.Error("Marshal prometheus config to yaml error.", err.Error())
return err
}
err = ioutil.WriteFile(p.Opt.ConfigFile, data, 0644)
if err != nil {
logrus.Error("Write prometheus config file error.", err.Error())
return err
}
return nil
}
func (p *Manager) UpdateScrape(scrape *ScrapeConfig) {
logrus.Debugf("update scrape: %+v", scrape)
p.l.Lock()
defer p.l.Unlock()
exist := false
for i, s := range p.Config.ScrapeConfigs {
if s.JobName == scrape.JobName {
p.Config.ScrapeConfigs[i] = scrape
exist = true
break
}
}
if !exist {
p.Config.ScrapeConfigs = append(p.Config.ScrapeConfigs, scrape)
}
p.SaveConfig()
p.RestartDaemon()
}