// Parse returns a slice of Metrics from a text representation of a // metric (in line-protocol format) // with each metric separated by newlines. If any metrics fail to parse, // a non-nil error will be returned in addition to the metrics that parsed // successfully. func (p *InfluxParser) Parse(buf []byte) ([]telegraf.Metric, error) { // parse even if the buffer begins with a newline buf = bytes.TrimPrefix(buf, []byte("\n")) points, err := models.ParsePoints(buf) metrics := make([]telegraf.Metric, len(points)) for i, point := range points { tags := point.Tags() for k, v := range p.DefaultTags { // Only set tags not in parsed metric if _, ok := tags[k]; !ok { tags[k] = v } } // Ignore error here because it's impossible that a model.Point // wouldn't parse into client.Point properly metrics[i], _ = telegraf.NewMetric(point.Name(), tags, point.Fields(), point.Time()) } return metrics, err }
func (p *JSONParser) Parse(buf []byte) ([]telegraf.Metric, error) { metrics := make([]telegraf.Metric, 0) var jsonOut map[string]interface{} err := json.Unmarshal(buf, &jsonOut) if err != nil { err = fmt.Errorf("unable to parse out as JSON, %s", err) return nil, err } tags := make(map[string]string) for k, v := range p.DefaultTags { tags[k] = v } for _, tag := range p.TagKeys { switch v := jsonOut[tag].(type) { case string: tags[tag] = v } delete(jsonOut, tag) } f := JSONFlattener{} err = f.FlattenJSON("", jsonOut) if err != nil { return nil, err } metric, err := telegraf.NewMetric(p.MetricName, tags, f.Fields, time.Now().UTC()) if err != nil { return nil, err } return append(metrics, metric), nil }
func (ac *accumulator) AddFields( measurement string, fields map[string]interface{}, tags map[string]string, t ...time.Time, ) { if len(fields) == 0 || len(measurement) == 0 { return } if !ac.inputConfig.Filter.ShouldTagsPass(tags) { return } // Override measurement name if set if len(ac.inputConfig.NameOverride) != 0 { measurement = ac.inputConfig.NameOverride } // Apply measurement prefix and suffix if set if len(ac.inputConfig.MeasurementPrefix) != 0 { measurement = ac.inputConfig.MeasurementPrefix + measurement } if len(ac.inputConfig.MeasurementSuffix) != 0 { measurement = measurement + ac.inputConfig.MeasurementSuffix } if tags == nil { tags = make(map[string]string) } // Apply plugin-wide tags if set for k, v := range ac.inputConfig.Tags { if _, ok := tags[k]; !ok { tags[k] = v } } // Apply daemon-wide tags if set for k, v := range ac.defaultTags { if _, ok := tags[k]; !ok { tags[k] = v } } result := make(map[string]interface{}) for k, v := range fields { // Filter out any filtered fields if ac.inputConfig != nil { if !ac.inputConfig.Filter.ShouldPass(k) { continue } } result[k] = v // Validate uint64 and float64 fields switch val := v.(type) { case uint64: // InfluxDB does not support writing uint64 if val < uint64(9223372036854775808) { result[k] = int64(val) } else { result[k] = int64(9223372036854775807) } case float64: // NaNs are invalid values in influxdb, skip measurement if math.IsNaN(val) || math.IsInf(val, 0) { if ac.debug { log.Printf("Measurement [%s] field [%s] has a NaN or Inf "+ "field, skipping", measurement, k) } continue } } } fields = nil if len(result) == 0 { return } var timestamp time.Time if len(t) > 0 { timestamp = t[0] } else { timestamp = time.Now() } if ac.prefix != "" { measurement = ac.prefix + measurement } m, err := telegraf.NewMetric(measurement, tags, result, timestamp) if err != nil { log.Printf("Error adding point [%s]: %s\n", measurement, err.Error()) return } if ac.debug { fmt.Println("> " + m.String()) } ac.metrics <- m }