func createPoint(r *pstore.Record) (*client.Point, error) { tags := map[string]string{ kTagVersion: kVersionNum, kTagHost: r.HostName, } for k, v := range r.Tags { tags[k] = v } fields := map[string]interface{}{ kFieldName: r.Path, } if r.Kind == types.String { fields[kFieldValue] = r.Value.(string) } else { fields[kFieldValue] = kafka.ToFloat64(r) } return client.NewPoint(r.Path, tags, fields, r.Timestamp) }
func (w *writer) Write(records []pstore.Record) (err error) { reqs := make([]opentsdb.StoreSamplesRequest, len(records)) for i := range records { v := kafka.ToFloat64(&records[i]) // We can't allow Infinity or NaN, so we do the best we can. if math.IsInf(v, 1) { v = math.MaxFloat64 } else if math.IsInf(v, -1) { v = -math.MaxFloat64 } else if math.IsNaN(v) { v = 0 } reqs[i] = opentsdb.StoreSamplesRequest{ Metric: opentsdb.TagValue(records[i].Path), // TODO: Milliseconds? Timestamp: records[i].Timestamp.Unix(), Value: v, Tags: allTagValues(&records[i]), } } u, err := url.Parse(w.url) if err != nil { return err } u.Path = putEndpoint buf, err := json.Marshal(reqs) if err != nil { return err } resp, err := w.httpClient.Post( u.String(), contentTypeJSON, bytes.NewBuffer(buf), ) if err != nil { return err } defer resp.Body.Close() // API returns status code 204 for successful writes. // http://opentsdb.net/docs/build/html/api_http/put.html if resp.StatusCode == http.StatusNoContent { return nil } // API returns status code 400 on error, encoding error details in the // response content in JSON. buf, err = ioutil.ReadAll(resp.Body) if err != nil { return err } var r map[string]int if err := json.Unmarshal(buf, &r); err != nil { return err } return fmt.Errorf("failed to write %d samples to OpenTSDB, %d succeeded", r["failed"], r["success"]) }