2015-05-22 23:45:14 +00:00
|
|
|
package telegraf
|
2015-04-06 16:32:10 +00:00
|
|
|
|
2015-04-07 00:24:24 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
2015-11-10 21:40:39 +00:00
|
|
|
"log"
|
2015-11-23 21:16:20 +00:00
|
|
|
"math"
|
2015-06-22 01:16:46 +00:00
|
|
|
"sync"
|
2015-05-27 05:14:42 +00:00
|
|
|
"time"
|
2015-04-07 00:24:24 +00:00
|
|
|
|
2016-01-22 18:54:12 +00:00
|
|
|
"github.com/influxdata/telegraf/internal/models"
|
2015-11-24 21:22:11 +00:00
|
|
|
|
2016-01-20 18:57:35 +00:00
|
|
|
"github.com/influxdata/influxdb/client/v2"
|
2015-04-07 00:24:24 +00:00
|
|
|
)
|
2015-04-06 16:32:10 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
type Accumulator interface {
|
|
|
|
Add(measurement string, value interface{},
|
|
|
|
tags map[string]string, t ...time.Time)
|
|
|
|
AddFields(measurement string, fields map[string]interface{},
|
|
|
|
tags map[string]string, t ...time.Time)
|
2015-04-07 00:24:24 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
SetDefaultTags(tags map[string]string)
|
|
|
|
AddDefaultTag(key, value string)
|
2015-05-18 19:15:15 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
Prefix() string
|
|
|
|
SetPrefix(prefix string)
|
2015-05-20 05:19:32 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
Debug() bool
|
|
|
|
SetDebug(enabled bool)
|
2015-04-06 16:32:10 +00:00
|
|
|
}
|
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
func NewAccumulator(
|
2016-01-22 18:54:12 +00:00
|
|
|
inputConfig *models.InputConfig,
|
2015-10-16 22:13:32 +00:00
|
|
|
points chan *client.Point,
|
|
|
|
) Accumulator {
|
|
|
|
acc := accumulator{}
|
|
|
|
acc.points = points
|
2016-01-07 20:39:43 +00:00
|
|
|
acc.inputConfig = inputConfig
|
2015-10-16 22:13:32 +00:00
|
|
|
return &acc
|
|
|
|
}
|
2015-10-08 17:33:56 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
type accumulator struct {
|
|
|
|
sync.Mutex
|
2015-10-08 17:33:56 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
points chan *client.Point
|
2015-10-08 17:33:56 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
defaultTags map[string]string
|
2015-10-08 17:33:56 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
debug bool
|
2015-10-08 17:33:56 +00:00
|
|
|
|
2016-01-22 18:54:12 +00:00
|
|
|
inputConfig *models.InputConfig
|
2015-10-08 17:33:56 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
prefix string
|
2015-10-08 17:33:56 +00:00
|
|
|
}
|
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
func (ac *accumulator) Add(
|
2015-09-10 03:27:58 +00:00
|
|
|
measurement string,
|
2015-10-16 22:13:32 +00:00
|
|
|
value interface{},
|
2015-09-10 03:27:58 +00:00
|
|
|
tags map[string]string,
|
2015-10-16 22:13:32 +00:00
|
|
|
t ...time.Time,
|
2015-09-10 03:27:58 +00:00
|
|
|
) {
|
2015-10-07 22:11:52 +00:00
|
|
|
fields := make(map[string]interface{})
|
2015-10-16 22:13:32 +00:00
|
|
|
fields["value"] = value
|
|
|
|
ac.AddFields(measurement, fields, tags, t...)
|
2015-04-06 16:32:10 +00:00
|
|
|
}
|
2015-05-27 05:14:42 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
func (ac *accumulator) AddFields(
|
2015-05-29 20:25:48 +00:00
|
|
|
measurement string,
|
2015-09-16 23:50:43 +00:00
|
|
|
fields map[string]interface{},
|
2015-05-27 05:14:42 +00:00
|
|
|
tags map[string]string,
|
2015-10-16 22:13:32 +00:00
|
|
|
t ...time.Time,
|
2015-09-16 23:50:43 +00:00
|
|
|
) {
|
2016-01-06 23:55:28 +00:00
|
|
|
if len(fields) == 0 || len(measurement) == 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2016-01-07 20:39:43 +00:00
|
|
|
if !ac.inputConfig.Filter.ShouldTagsPass(tags) {
|
2015-12-11 20:07:32 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override measurement name if set
|
2016-01-07 20:39:43 +00:00
|
|
|
if len(ac.inputConfig.NameOverride) != 0 {
|
|
|
|
measurement = ac.inputConfig.NameOverride
|
2015-12-11 20:07:32 +00:00
|
|
|
}
|
|
|
|
// Apply measurement prefix and suffix if set
|
2016-01-07 20:39:43 +00:00
|
|
|
if len(ac.inputConfig.MeasurementPrefix) != 0 {
|
|
|
|
measurement = ac.inputConfig.MeasurementPrefix + measurement
|
2015-12-11 20:07:32 +00:00
|
|
|
}
|
2016-01-07 20:39:43 +00:00
|
|
|
if len(ac.inputConfig.MeasurementSuffix) != 0 {
|
|
|
|
measurement = measurement + ac.inputConfig.MeasurementSuffix
|
2015-12-11 20:07:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if tags == nil {
|
|
|
|
tags = make(map[string]string)
|
|
|
|
}
|
|
|
|
// Apply plugin-wide tags if set
|
2016-01-07 20:39:43 +00:00
|
|
|
for k, v := range ac.inputConfig.Tags {
|
2015-12-11 20:07:32 +00:00
|
|
|
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{})
|
2015-10-20 00:43:40 +00:00
|
|
|
for k, v := range fields {
|
2015-12-11 20:07:32 +00:00
|
|
|
// Filter out any filtered fields
|
2016-01-07 20:39:43 +00:00
|
|
|
if ac.inputConfig != nil {
|
|
|
|
if !ac.inputConfig.Filter.ShouldPass(k) {
|
2015-12-11 20:07:32 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result[k] = v
|
|
|
|
|
|
|
|
// Validate uint64 and float64 fields
|
2015-10-20 00:43:40 +00:00
|
|
|
switch val := v.(type) {
|
|
|
|
case uint64:
|
2015-11-23 21:16:20 +00:00
|
|
|
// InfluxDB does not support writing uint64
|
2015-10-20 00:43:40 +00:00
|
|
|
if val < uint64(9223372036854775808) {
|
2015-12-11 20:07:32 +00:00
|
|
|
result[k] = int64(val)
|
2015-10-16 22:13:32 +00:00
|
|
|
} else {
|
2015-12-11 20:07:32 +00:00
|
|
|
result[k] = int64(9223372036854775807)
|
2015-10-20 00:43:40 +00:00
|
|
|
}
|
2015-11-23 21:16:20 +00:00
|
|
|
case float64:
|
|
|
|
// NaNs are invalid values in influxdb, skip measurement
|
|
|
|
if math.IsNaN(val) || math.IsInf(val, 0) {
|
|
|
|
if ac.debug {
|
2015-12-11 20:07:32 +00:00
|
|
|
log.Printf("Measurement [%s] field [%s] has a NaN or Inf "+
|
|
|
|
"field, skipping",
|
|
|
|
measurement, k)
|
2015-11-23 21:16:20 +00:00
|
|
|
}
|
2015-12-11 20:07:32 +00:00
|
|
|
continue
|
2015-11-23 21:16:20 +00:00
|
|
|
}
|
2015-10-20 00:43:40 +00:00
|
|
|
}
|
|
|
|
}
|
2015-12-11 20:07:32 +00:00
|
|
|
fields = nil
|
|
|
|
if len(result) == 0 {
|
|
|
|
return
|
2015-11-23 21:16:20 +00:00
|
|
|
}
|
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
var timestamp time.Time
|
|
|
|
if len(t) > 0 {
|
|
|
|
timestamp = t[0]
|
|
|
|
} else {
|
|
|
|
timestamp = time.Now()
|
|
|
|
}
|
2015-05-27 05:14:42 +00:00
|
|
|
|
2015-11-12 08:52:30 +00:00
|
|
|
if ac.prefix != "" {
|
|
|
|
measurement = ac.prefix + measurement
|
|
|
|
}
|
|
|
|
|
2015-12-11 20:07:32 +00:00
|
|
|
pt, err := client.NewPoint(measurement, tags, result, timestamp)
|
2015-11-10 21:40:39 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Printf("Error adding point [%s]: %s\n", measurement, err.Error())
|
2015-11-23 21:16:20 +00:00
|
|
|
return
|
2015-11-10 21:40:39 +00:00
|
|
|
}
|
2015-10-16 22:13:32 +00:00
|
|
|
if ac.debug {
|
|
|
|
fmt.Println("> " + pt.String())
|
|
|
|
}
|
|
|
|
ac.points <- pt
|
|
|
|
}
|
2015-05-27 05:14:42 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
func (ac *accumulator) SetDefaultTags(tags map[string]string) {
|
|
|
|
ac.defaultTags = tags
|
|
|
|
}
|
2015-05-27 05:14:42 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
func (ac *accumulator) AddDefaultTag(key, value string) {
|
|
|
|
ac.defaultTags[key] = value
|
|
|
|
}
|
2015-05-27 05:14:42 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
func (ac *accumulator) Prefix() string {
|
|
|
|
return ac.prefix
|
|
|
|
}
|
2015-05-27 05:14:42 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
func (ac *accumulator) SetPrefix(prefix string) {
|
|
|
|
ac.prefix = prefix
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ac *accumulator) Debug() bool {
|
|
|
|
return ac.debug
|
|
|
|
}
|
2015-05-27 05:14:42 +00:00
|
|
|
|
2015-10-16 22:13:32 +00:00
|
|
|
func (ac *accumulator) SetDebug(debug bool) {
|
|
|
|
ac.debug = debug
|
2015-05-27 05:14:42 +00:00
|
|
|
}
|