From 51fd83f1bebb7c302d0b1d87209f77d8acf93eb9 Mon Sep 17 00:00:00 2001 From: Jan Grewe <jan.grewe@flixbus.com> Date: Wed, 6 Jun 2018 19:22:55 +0200 Subject: [PATCH] Catch and log API errors, always output 'nexenta_up' --- main.go | 57 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/main.go b/main.go index 1812e2a..17abf73 100644 --- a/main.go +++ b/main.go @@ -49,6 +49,8 @@ type Exporter struct { mutex sync.Mutex client *http.Client + apiReachable float64 + up *prometheus.Desc scrapeFailures prometheus.Counter volumeOnline *prometheus.Desc @@ -90,10 +92,14 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { func (e *Exporter) Collect(ch chan<- prometheus.Metric) { e.mutex.Lock() // To protect metrics from concurrent collects. defer e.mutex.Unlock() + e.apiReachable = 0 err := e.collect(ch) if err != nil { - log.Errorf("Collect(): %v", err) + log.Errorf("%v", err) } + + ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, e.apiReachable) + return } @@ -101,32 +107,27 @@ func (e *Exporter) collect(ch chan<- prometheus.Metric) error { volumes, err := e.getVolumes(ch) if err != nil { - log.Errorf("getVolumes(): %v", err) + err = fmt.Errorf("getVolumes(): %v", err) } if len(volumes) > 0 { for _, volume := range volumes { - err := e.getVolumeStatus(ch, volume) + err = e.getVolumeStatus(ch, volume) if err != nil { - log.Errorf("getVolumeStatus(): %v", err) + err = fmt.Errorf("getVolumeStatus(): %v", err) } } } - if err != nil { - ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 0) - return fmt.Errorf("Error scraping Nexenta API: %v", err) - } - ch <- prometheus.MustNewConstMetric(e.up, prometheus.GaugeValue, 1) - return err } func (e *Exporter) getVolumes(ch chan<- prometheus.Metric) ([]string, error) { var reqJson = []byte(`{"object": "volume", "params": [""], "method": "get_names"}`) + apiResponse, err := e.queryApi(ch, reqJson); if err != nil { return nil, err } - apiResult, err := json.Marshal(apiResponse.Result) + apiResult, err := json.Marshal(apiResponse.Result); if err != nil { return nil, err } var volumes []string err = json.Unmarshal([]byte(apiResult), &volumes) @@ -138,18 +139,17 @@ func (e *Exporter) getVolumeStatus(ch chan<- prometheus.Metric, volume string) e var reqJson = []byte(`{"object": "volume", "params": ["` + volume + `"], "method": "get_status"}`) apiResponse, err := e.queryApi(ch, reqJson); if err != nil { return err } + apiResult, err := json.Marshal(apiResponse.Result); if err != nil { return err } - apiResult, err := json.Marshal(apiResponse.Result) - - var result= new(ResultObject) - err = json.Unmarshal(apiResult, &result) + var result = new(ResultObject) + err = json.Unmarshal(apiResult, &result); if err != nil { return err } var volumeOnline float64 = 0 if len(result.State) > 0 { if result.State[0] == "ONLINE" { volumeOnline = 1 } } - ch <- prometheus.MustNewConstMetric(e.volumeOnline, prometheus.GaugeValue, volumeOnline, "data") + ch <- prometheus.MustNewConstMetric(e.volumeOnline, prometheus.GaugeValue, volumeOnline, volume) return err } @@ -157,31 +157,38 @@ func (e *Exporter) getVolumeStatus(ch chan<- prometheus.Metric, volume string) e func (e *Exporter) queryApi(ch chan<- prometheus.Metric, reqJson []byte) (*ApiResponse, error) { resp, err := e.client.Post(e.URI, "application/json", bytes.NewBuffer(reqJson)) + if err != nil { + return nil, fmt.Errorf("Error scraping Nexenta API: %v", err) + } + + e.apiReachable = 1 data, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if resp.StatusCode != 200 { if err != nil { data = []byte(err.Error()) - log.Errorf("Error scraping Nexenta API: %s", err) - e.scrapeFailures.Inc() - e.scrapeFailures.Collect(ch) } - return nil, fmt.Errorf("Status %s (%d)", resp.Status, resp.StatusCode) + e.scrapeFailures.Inc() + e.scrapeFailures.Collect(ch) + return nil, fmt.Errorf("Status %s (%d) %s", resp.Status, resp.StatusCode, data) } //log.Infof("response: %s", data) var apiResponse = new(ApiResponse) - err_json := json.Unmarshal(data, &apiResponse) - if err_json != nil { - log.Infof("whoops:", err_json) - } + err = json.Unmarshal(data, &apiResponse); if err != nil { return nil, err } if apiResponse.Result == nil { e.scrapeFailures.Inc() e.scrapeFailures.Collect(ch) - return nil, fmt.Errorf("Field 'result' in API response is null") + return nil, fmt.Errorf("Field 'result' in API response is null, API Error: %v", apiResponse.Error) + } + + if apiResponse.Error != nil { + e.scrapeFailures.Inc() + e.scrapeFailures.Collect(ch) + return nil, fmt.Errorf("API Error: %v", apiResponse.Error) } return apiResponse, nil -- GitLab