1// Copyright 2016 Circonus, Inc. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Metric API support - Fetch, Create*, Update, Delete*, and Search 6// See: https://login.circonus.com/resources/api/calls/metric 7// * : create and delete are handled via check_bundle or check_bundle_metrics 8 9package api 10 11import ( 12 "encoding/json" 13 "fmt" 14 "net/url" 15 "regexp" 16 17 "github.com/circonus-labs/circonus-gometrics/api/config" 18) 19 20// Metric defines a metric. See https://login.circonus.com/resources/api/calls/metric for more information. 21type Metric struct { 22 Active bool `json:"_active,omitempty"` // boolean 23 CheckActive bool `json:"_check_active,omitempty"` // boolean 24 CheckBundleCID string `json:"_check_bundle,omitempty"` // string 25 CheckCID string `json:"_check,omitempty"` // string 26 CheckTags []string `json:"_check_tags,omitempty"` // [] len >= 0 27 CheckUUID string `json:"_check_uuid,omitempty"` // string 28 CID string `json:"_cid,omitempty"` // string 29 Histogram string `json:"_histogram,omitempty"` // string 30 Link *string `json:"link,omitempty"` // string or null 31 MetricName string `json:"_metric_name,omitempty"` // string 32 MetricType string `json:"_metric_type,omitempty"` // string 33 Notes *string `json:"notes,omitempty"` // string or null 34 Tags []string `json:"tags,omitempty"` // [] len >= 0 35 Units *string `json:"units,omitempty"` // string or null 36} 37 38// FetchMetric retrieves metric with passed cid. 39func (a *API) FetchMetric(cid CIDType) (*Metric, error) { 40 if cid == nil || *cid == "" { 41 return nil, fmt.Errorf("Invalid metric CID [none]") 42 } 43 44 metricCID := string(*cid) 45 46 matched, err := regexp.MatchString(config.MetricCIDRegex, metricCID) 47 if err != nil { 48 return nil, err 49 } 50 if !matched { 51 return nil, fmt.Errorf("Invalid metric CID [%s]", metricCID) 52 } 53 54 result, err := a.Get(metricCID) 55 if err != nil { 56 return nil, err 57 } 58 59 if a.Debug { 60 a.Log.Printf("[DEBUG] fetch metric, received JSON: %s", string(result)) 61 } 62 63 metric := &Metric{} 64 if err := json.Unmarshal(result, metric); err != nil { 65 return nil, err 66 } 67 68 return metric, nil 69} 70 71// FetchMetrics retrieves all metrics available to API Token. 72func (a *API) FetchMetrics() (*[]Metric, error) { 73 result, err := a.Get(config.MetricPrefix) 74 if err != nil { 75 return nil, err 76 } 77 78 var metrics []Metric 79 if err := json.Unmarshal(result, &metrics); err != nil { 80 return nil, err 81 } 82 83 return &metrics, nil 84} 85 86// UpdateMetric updates passed metric. 87func (a *API) UpdateMetric(cfg *Metric) (*Metric, error) { 88 if cfg == nil { 89 return nil, fmt.Errorf("Invalid metric config [nil]") 90 } 91 92 metricCID := string(cfg.CID) 93 94 matched, err := regexp.MatchString(config.MetricCIDRegex, metricCID) 95 if err != nil { 96 return nil, err 97 } 98 if !matched { 99 return nil, fmt.Errorf("Invalid metric CID [%s]", metricCID) 100 } 101 102 jsonCfg, err := json.Marshal(cfg) 103 if err != nil { 104 return nil, err 105 } 106 107 if a.Debug { 108 a.Log.Printf("[DEBUG] update metric, sending JSON: %s", string(jsonCfg)) 109 } 110 111 result, err := a.Put(metricCID, jsonCfg) 112 if err != nil { 113 return nil, err 114 } 115 116 metric := &Metric{} 117 if err := json.Unmarshal(result, metric); err != nil { 118 return nil, err 119 } 120 121 return metric, nil 122} 123 124// SearchMetrics returns metrics matching the specified search query 125// and/or filter. If nil is passed for both parameters all metrics 126// will be returned. 127func (a *API) SearchMetrics(searchCriteria *SearchQueryType, filterCriteria *SearchFilterType) (*[]Metric, error) { 128 q := url.Values{} 129 130 if searchCriteria != nil && *searchCriteria != "" { 131 q.Set("search", string(*searchCriteria)) 132 } 133 134 if filterCriteria != nil && len(*filterCriteria) > 0 { 135 for filter, criteria := range *filterCriteria { 136 for _, val := range criteria { 137 q.Add(filter, val) 138 } 139 } 140 } 141 142 if q.Encode() == "" { 143 return a.FetchMetrics() 144 } 145 146 reqURL := url.URL{ 147 Path: config.MetricPrefix, 148 RawQuery: q.Encode(), 149 } 150 151 result, err := a.Get(reqURL.String()) 152 if err != nil { 153 return nil, fmt.Errorf("[ERROR] API call error %+v", err) 154 } 155 156 var metrics []Metric 157 if err := json.Unmarshal(result, &metrics); err != nil { 158 return nil, err 159 } 160 161 return &metrics, nil 162} 163