func fetchMetricFamilies(url string, ch chan<- *dto.MetricFamily) { defer close(ch) req, err := http.NewRequest("GET", url, nil) if err != nil { log.Fatalf("creating GET request for URL %q failed: %s", url, err) } req.Header.Add("Accept", acceptHeader) resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatalf("executing GET request for URL %q failed: %s", url, err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { log.Fatalf("GET request for URL %q returned HTTP status %s", url, resp.Status) } mediatype, params, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) if err == nil && mediatype == "application/vnd.google.protobuf" && params["encoding"] == "delimited" && params["proto"] == "io.prometheus.client.MetricFamily" { for { mf := &dto.MetricFamily{} if _, err = pbutil.ReadDelimited(resp.Body, mf); err != nil { if err == io.EOF { break } log.Fatalln("reading metric family protocol buffer failed:", err) } ch <- mf } } else { // We could do further content-type checks here, but the // fallback for now will anyway be the text format // version 0.0.4, so just go for it and see if it works. var parser expfmt.TextParser metricFamilies, err := parser.TextToMetricFamilies(resp.Body) if err != nil { log.Fatalln("reading text format failed:", err) } for _, mf := range metricFamilies { ch <- mf } } }
func main() { runtime.GOMAXPROCS(2) if len(os.Args) != 2 { log.Fatalf("Usage: %s METRICS_URL", os.Args[0]) } mfChan := make(chan *dto.MetricFamily, 1024) go fetchMetricFamilies(os.Args[1], mfChan) result := []*metricFamily{} for mf := range mfChan { result = append(result, newMetricFamily(mf)) } json, err := json.Marshal(result) if err != nil { log.Fatalln("error marshaling JSON:", err) } if _, err := os.Stdout.Write(json); err != nil { log.Fatalln("error writing to stdout:", err) } fmt.Println() }
func main() { flag.Parse() if !strings.HasPrefix(*pathPrefix, "/") { *pathPrefix = "/" + *pathPrefix } if !strings.HasSuffix(*pathPrefix, "/") { *pathPrefix = *pathPrefix + "/" } versionInfoTmpl.Execute(os.Stdout, BuildInfo) conf := config.MustLoadFromFile(*configFile) silencer := manager.NewSilencer() defer silencer.Close() err := silencer.LoadFromFile(*silencesFile) if err != nil { log.Warn("Couldn't load silences, starting up with empty silence list: ", err) } saveSilencesTicker := time.NewTicker(10 * time.Second) go func() { for range saveSilencesTicker.C { if err := silencer.SaveToFile(*silencesFile); err != nil { log.Error("Error saving silences to file: ", err) } } }() defer saveSilencesTicker.Stop() amURL, err := alertmanagerURL(*hostname, *pathPrefix, *listenAddress, *externalURL) if err != nil { log.Fatalln("Error building Alertmanager URL:", err) } notifier := manager.NewNotifier(conf.NotificationConfig, amURL) defer notifier.Close() inhibitor := new(manager.Inhibitor) inhibitor.SetInhibitRules(conf.InhibitRules()) options := &manager.MemoryAlertManagerOptions{ Inhibitor: inhibitor, Silencer: silencer, Notifier: notifier, MinRefreshInterval: *minRefreshPeriod, } alertManager := manager.NewMemoryAlertManager(options) alertManager.SetAggregationRules(conf.AggregationRules()) go alertManager.Run() // Web initialization. flags := map[string]string{} flag.VisitAll(func(f *flag.Flag) { flags[f.Name] = f.Value.String() }) statusHandler := &web.StatusHandler{ Config: conf.String(), Flags: flags, BuildInfo: BuildInfo, Birth: time.Now(), PathPrefix: *pathPrefix, } webService := &web.WebService{ // REST API Service. AlertManagerService: &api.AlertManagerService{ Manager: alertManager, Silencer: silencer, PathPrefix: *pathPrefix, }, // Template-based page handlers. AlertsHandler: &web.AlertsHandler{ Manager: alertManager, IsSilencedInterrogator: silencer, PathPrefix: *pathPrefix, }, SilencesHandler: &web.SilencesHandler{ Silencer: silencer, PathPrefix: *pathPrefix, }, StatusHandler: statusHandler, } go webService.ServeForever(*listenAddress, *pathPrefix) // React to configuration changes. watcher := config.NewFileWatcher(*configFile) go watcher.Watch(func(conf *config.Config) { inhibitor.SetInhibitRules(conf.InhibitRules()) notifier.SetNotificationConfigs(conf.NotificationConfig) alertManager.SetAggregationRules(conf.AggregationRules()) statusHandler.UpdateConfig(conf.String()) }) log.Info("Running notification dispatcher...") notifier.Dispatch() }