consul/vendor/github.com/circonus-labs/circonus-gometrics/submit.go

123 lines
2.7 KiB
Go

package circonusgometrics
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"log"
"net"
"net/http"
"strconv"
"time"
"github.com/circonus-labs/circonus-gometrics/api"
"github.com/hashicorp/go-retryablehttp"
)
func (m *CirconusMetrics) submit(output map[string]interface{}, newMetrics map[string]*api.CheckBundleMetric) {
if len(newMetrics) > 0 {
m.check.AddNewMetrics(newMetrics)
}
str, err := json.Marshal(output)
if err != nil {
m.Log.Printf("[ERROR] marshling output %+v", err)
return
}
numStats, err := m.trapCall(str)
if err != nil {
m.Log.Printf("[ERROR] %+v\n", err)
return
}
if m.Debug {
m.Log.Printf("[DEBUG] %d stats sent\n", numStats)
}
}
func (m *CirconusMetrics) trapCall(payload []byte) (int, error) {
trap, err := m.check.GetTrap()
if err != nil {
return 0, err
}
dataReader := bytes.NewReader(payload)
req, err := retryablehttp.NewRequest("PUT", trap.URL.String(), dataReader)
if err != nil {
return 0, err
}
req.Header.Add("Accept", "application/json")
client := retryablehttp.NewClient()
if trap.URL.Scheme == "https" {
client.HTTPClient.Transport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: trap.TLS,
DisableKeepAlives: true,
MaxIdleConnsPerHost: -1,
DisableCompression: true,
}
} else {
client.HTTPClient.Transport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
DisableKeepAlives: true,
MaxIdleConnsPerHost: -1,
DisableCompression: true,
}
}
client.RetryWaitMin = 10 * time.Millisecond
client.RetryWaitMax = 50 * time.Millisecond
client.RetryMax = 3
client.Logger = m.Log
attempts := -1
client.RequestLogHook = func(logger *log.Logger, req *http.Request, retryNumber int) {
attempts = retryNumber
}
resp, err := client.Do(req)
if err != nil {
if attempts == client.RetryMax {
m.check.RefreshTrap()
}
return 0, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
m.Log.Printf("[ERROR] reading body, proceeding. %s\n", err)
}
var response map[string]interface{}
err = json.Unmarshal(body, &response)
if err != nil {
m.Log.Printf("[ERROR] parsing body, proceeding. %s\n", err)
}
if resp.StatusCode != 200 {
return 0, errors.New("[ERROR] bad response code: " + strconv.Itoa(resp.StatusCode))
}
switch v := response["stats"].(type) {
case float64:
return int(v), nil
case int:
return v, nil
default:
}
return 0, errors.New("[ERROR] bad response type")
}