Skip to content
Snippets Groups Projects
Commit 1cefeb06 authored by Jan Grewe's avatar Jan Grewe
Browse files

Use struct for request JSON, assume that there's always an error message if...

Use struct for request JSON, assume that there's always an error message if the result is null (according to docs)
parent 51fd83f1
No related branches found
No related tags found
No related merge requests found
...@@ -33,10 +33,20 @@ var ( ...@@ -33,10 +33,20 @@ var (
showVersion = flag.Bool("version", false, "Print version information.") showVersion = flag.Bool("version", false, "Print version information.")
) )
type ApiRequest struct {
Object string `json:"object"`
Method string `json:"method"`
Params []string `json:"params"`
}
type ApiResponse struct { type ApiResponse struct {
TGFlash string `json:"tg_flash"` TGFlash string `json:"tg_flash"`
Result interface{} `json:"result"` Result interface{} `json:"result"`
Error interface{} `json:"error"` Error ApiError `json:"error"`
}
type ApiError struct {
Message string `json:"message"`
} }
type ResultObject struct { type ResultObject struct {
...@@ -61,13 +71,13 @@ func NewExporter(uri string) *Exporter { ...@@ -61,13 +71,13 @@ func NewExporter(uri string) *Exporter {
URI: uri, URI: uri,
up: prometheus.NewDesc( up: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "up"), prometheus.BuildFQName(namespace, "", "up"),
"Could the Nexenta API be reached", "Is the Nexenta API reachable",
nil, nil,
nil), nil),
scrapeFailures: prometheus.NewCounter(prometheus.CounterOpts{ scrapeFailures: prometheus.NewCounter(prometheus.CounterOpts{
Namespace: namespace, Namespace: namespace,
Name: "exporter_scrape_failures_total", Name: "exporter_scrape_failures_total",
Help: "Number of errors while scraping Nexenta API.", Help: "Number of errors while scraping the Nexenta API",
}), }),
volumeOnline: prometheus.NewDesc( volumeOnline: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "volume", "online"), prometheus.BuildFQName(namespace, "volume", "online"),
...@@ -92,7 +102,6 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { ...@@ -92,7 +102,6 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
func (e *Exporter) Collect(ch chan<- prometheus.Metric) { func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
e.mutex.Lock() // To protect metrics from concurrent collects. e.mutex.Lock() // To protect metrics from concurrent collects.
defer e.mutex.Unlock() defer e.mutex.Unlock()
e.apiReachable = 0
err := e.collect(ch) err := e.collect(ch)
if err != nil { if err != nil {
log.Errorf("%v", err) log.Errorf("%v", err)
...@@ -124,9 +133,7 @@ func (e *Exporter) collect(ch chan<- prometheus.Metric) error { ...@@ -124,9 +133,7 @@ func (e *Exporter) collect(ch chan<- prometheus.Metric) error {
func (e *Exporter) getVolumes(ch chan<- prometheus.Metric) ([]string, error) { func (e *Exporter) getVolumes(ch chan<- prometheus.Metric) ([]string, error) {
var reqJson = []byte(`{"object": "volume", "params": [""], "method": "get_names"}`) apiResponse, err := e.queryApi(ch, "volume", "get_names", []string{""}); if err != nil { return nil, err }
apiResponse, err := e.queryApi(ch, reqJson); if err != nil { return nil, err }
apiResult, err := json.Marshal(apiResponse.Result); if err != nil { return nil, err } apiResult, err := json.Marshal(apiResponse.Result); if err != nil { return nil, err }
var volumes []string var volumes []string
...@@ -137,8 +144,7 @@ func (e *Exporter) getVolumes(ch chan<- prometheus.Metric) ([]string, error) { ...@@ -137,8 +144,7 @@ func (e *Exporter) getVolumes(ch chan<- prometheus.Metric) ([]string, error) {
func (e *Exporter) getVolumeStatus(ch chan<- prometheus.Metric, volume string) error { func (e *Exporter) getVolumeStatus(ch chan<- prometheus.Metric, volume string) error {
var reqJson = []byte(`{"object": "volume", "params": ["` + volume + `"], "method": "get_status"}`) apiResponse, err := e.queryApi(ch, "volume", "get_status", []string{volume}); if err != nil { return err }
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); if err != nil { return err }
var result = new(ResultObject) var result = new(ResultObject)
...@@ -154,13 +160,20 @@ func (e *Exporter) getVolumeStatus(ch chan<- prometheus.Metric, volume string) e ...@@ -154,13 +160,20 @@ func (e *Exporter) getVolumeStatus(ch chan<- prometheus.Metric, volume string) e
return err return err
} }
func (e *Exporter) queryApi(ch chan<- prometheus.Metric, reqJson []byte) (*ApiResponse, error) { func (e *Exporter) queryApi(ch chan<- prometheus.Metric, object string, method string, params []string) (*ApiResponse, error) {
reqObject := &ApiRequest{
Object: object,
Method: method,
Params: params,
}
e.apiReachable = 0
reqJson, _ := json.Marshal(reqObject)
resp, err := e.client.Post(e.URI, "application/json", bytes.NewBuffer(reqJson)) resp, err := e.client.Post(e.URI, "application/json", bytes.NewBuffer(reqJson))
if err != nil { if err != nil {
return nil, fmt.Errorf("Error scraping Nexenta API: %v", err) return nil, fmt.Errorf("Error scraping Nexenta API: %v", err)
} }
e.apiReachable = 1 e.apiReachable = 1
data, err := ioutil.ReadAll(resp.Body) data, err := ioutil.ReadAll(resp.Body)
...@@ -171,7 +184,7 @@ func (e *Exporter) queryApi(ch chan<- prometheus.Metric, reqJson []byte) (*ApiRe ...@@ -171,7 +184,7 @@ func (e *Exporter) queryApi(ch chan<- prometheus.Metric, reqJson []byte) (*ApiRe
} }
e.scrapeFailures.Inc() e.scrapeFailures.Inc()
e.scrapeFailures.Collect(ch) e.scrapeFailures.Collect(ch)
return nil, fmt.Errorf("Status %s (%d) %s", resp.Status, resp.StatusCode, data) return nil, fmt.Errorf("Request Error: Status %s %s", resp.Status, data)
} }
//log.Infof("response: %s", data) //log.Infof("response: %s", data)
...@@ -182,13 +195,7 @@ func (e *Exporter) queryApi(ch chan<- prometheus.Metric, reqJson []byte) (*ApiRe ...@@ -182,13 +195,7 @@ func (e *Exporter) queryApi(ch chan<- prometheus.Metric, reqJson []byte) (*ApiRe
if apiResponse.Result == nil { if apiResponse.Result == nil {
e.scrapeFailures.Inc() e.scrapeFailures.Inc()
e.scrapeFailures.Collect(ch) e.scrapeFailures.Collect(ch)
return nil, fmt.Errorf("Field 'result' in API response is null, API Error: %v", apiResponse.Error) return nil, fmt.Errorf("API Error: %v", apiResponse.Error.Message)
}
if apiResponse.Error != nil {
e.scrapeFailures.Inc()
e.scrapeFailures.Collect(ch)
return nil, fmt.Errorf("API Error: %v", apiResponse.Error)
} }
return apiResponse, nil return apiResponse, nil
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment