// Start monitoring func (self *app) startMonitoring(addr string) error { go func() { log.Info("Serving debug data (/debug/vars) on %s...", addr) log.Info("Serving monitoring xml data on %s...", addr) http.Handle("/", CreateXMLStatusHandler()) log.Fatal(http.ListenAndServe(addr, nil)) }() // Hmetrics2 hmetrics2.SetPeriod(time.Minute) hmetrics2.AddHook(expvarexport.Exporter("metrics")) // Export metrics // TODO: monitoring plugins return nil }
func CreateXMLStatusHandler() http.Handler { m := martini.Classic() var mu sync.Mutex var data = make(map[string]float64) hmetrics2.AddHook(func(newData map[string]float64) { mu.Lock() defer mu.Unlock() data = make(map[string]float64) for k, v := range newData { if !math.IsNaN(v) && !math.IsInf(v, 0) { data[k] = v } } }) var logger xmlstatusLogger m.Map(stdlog.New(&logger, "[martini] ", stdlog.LstdFlags)) m.Get("/mon", func() string { return servicestatus.GetString() }) m.Get("/version", func() string { return program_version.GetVersion() }) m.Get("/config", func(w http.ResponseWriter) { w.Header().Add("Content-type", "application/json") w.Write([]byte(App.Config())) }) m.Get("/stat", func(w http.ResponseWriter) { mu.Lock() defer mu.Unlock() w.Header().Add("Content-type", "application/xml") w.Write([]byte(xml.Header)) w.Write([]byte(fmt.Sprintf("<stat:document xmlns:stat=\"http://xml.sputnik.ru/stat\" name=\"%v\" version=\"%v\">\n", os.Args[0], program_version.GetVersion()))) w.Write([]byte(fmt.Sprintf(" <stat>\n <start_time>%v</start_time>\n </stat>\n", startTime))) w.Write([]byte(" <user>\n")) for k, v := range data { w.Write([]byte(fmt.Sprintf(" <%s>%v</%s>\n", k, v, k))) } w.Write([]byte(" </user>\n")) w.Write([]byte("</stat:document>\n")) }) return m }
func NewService() *Service { self := &Service{} self.data = make(map[string]float64) // Metircs hmetrics2.AddHook(func(newData map[string]float64) { self.dataMu.Lock() defer self.dataMu.Unlock() self.data = make(map[string]float64) for k, v := range newData { if !math.IsNaN(v) && !math.IsInf(v, 0) { self.data[k] = v } } }) return self }
// Set up monitoring func (self *app) setupMonitoring() error { // Set up debug HTTP interface debugAddrCfg := reflect.ValueOf(self.appConfig).FieldByName("DebugAddr") if debugAddrCfg.IsValid() { debugAddr, ok := debugAddrCfg.Interface().(string) if !ok { return fmt.Errorf(`Field "DebugAddr" in "%s" is invalid`, self.appName) } if debugAddr != "" { if err := self.startMonitoring(debugAddr); err != nil { return err } } } // Set up exporter for _, pCfg := range self.commonConfig.MonitoringPlugins { plug, err := plugins.DefaultPluginStore.Create(pCfg.Plugin, pCfg.PluginConfig) if err != nil { return fmt.Errorf("Filed to create new %s: %v", pCfg.Plugin, err) } mon, ok := plug.(gopnik.MonitoringPluginInterface) if !ok { fmt.Errorf(`Invalid monitoring plugin "%s"`, pCfg.Plugin) } exporter, err := mon.Exporter() if err != nil { return fmt.Errorf("%s exporter error: %v", pCfg.Plugin, err) } hmetrics2.AddHook(exporter) } return nil }