2016-01-27 21:21:36 +00:00
|
|
|
package agent
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"time"
|
|
|
|
|
2016-01-27 23:15:14 +00:00
|
|
|
"github.com/influxdata/telegraf"
|
2016-11-07 08:34:46 +00:00
|
|
|
"github.com/influxdata/telegraf/selfstat"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
NErrors = selfstat.Register("agent", "gather_errors", map[string]string{})
|
2016-01-27 21:21:36 +00:00
|
|
|
)
|
|
|
|
|
2016-09-08 14:22:10 +00:00
|
|
|
type MetricMaker interface {
|
|
|
|
Name() string
|
|
|
|
MakeMetric(
|
|
|
|
measurement string,
|
|
|
|
fields map[string]interface{},
|
|
|
|
tags map[string]string,
|
|
|
|
mType telegraf.ValueType,
|
|
|
|
t time.Time,
|
|
|
|
) telegraf.Metric
|
|
|
|
}
|
|
|
|
|
2016-01-27 21:21:36 +00:00
|
|
|
func NewAccumulator(
|
2016-09-08 14:22:10 +00:00
|
|
|
maker MetricMaker,
|
2016-01-27 23:15:14 +00:00
|
|
|
metrics chan telegraf.Metric,
|
2016-01-27 21:21:36 +00:00
|
|
|
) *accumulator {
|
2016-09-08 14:22:10 +00:00
|
|
|
acc := accumulator{
|
|
|
|
maker: maker,
|
|
|
|
metrics: metrics,
|
|
|
|
precision: time.Nanosecond,
|
|
|
|
}
|
2016-01-27 21:21:36 +00:00
|
|
|
return &acc
|
|
|
|
}
|
|
|
|
|
|
|
|
type accumulator struct {
|
2016-01-27 23:15:14 +00:00
|
|
|
metrics chan telegraf.Metric
|
2016-01-27 21:21:36 +00:00
|
|
|
|
2016-09-08 14:22:10 +00:00
|
|
|
maker MetricMaker
|
2016-01-27 21:21:36 +00:00
|
|
|
|
2016-06-13 14:21:11 +00:00
|
|
|
precision time.Duration
|
2016-01-27 21:21:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ac *accumulator) AddFields(
|
|
|
|
measurement string,
|
|
|
|
fields map[string]interface{},
|
|
|
|
tags map[string]string,
|
|
|
|
t ...time.Time,
|
|
|
|
) {
|
2016-09-08 14:22:10 +00:00
|
|
|
if m := ac.maker.MakeMetric(measurement, fields, tags, telegraf.Untyped, ac.getTime(t)); m != nil {
|
2016-08-31 16:27:37 +00:00
|
|
|
ac.metrics <- m
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ac *accumulator) AddGauge(
|
|
|
|
measurement string,
|
|
|
|
fields map[string]interface{},
|
|
|
|
tags map[string]string,
|
|
|
|
t ...time.Time,
|
|
|
|
) {
|
2016-09-08 14:22:10 +00:00
|
|
|
if m := ac.maker.MakeMetric(measurement, fields, tags, telegraf.Gauge, ac.getTime(t)); m != nil {
|
2016-08-31 16:27:37 +00:00
|
|
|
ac.metrics <- m
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ac *accumulator) AddCounter(
|
|
|
|
measurement string,
|
|
|
|
fields map[string]interface{},
|
|
|
|
tags map[string]string,
|
|
|
|
t ...time.Time,
|
|
|
|
) {
|
2016-09-08 14:22:10 +00:00
|
|
|
if m := ac.maker.MakeMetric(measurement, fields, tags, telegraf.Counter, ac.getTime(t)); m != nil {
|
2016-08-31 16:27:37 +00:00
|
|
|
ac.metrics <- m
|
|
|
|
}
|
2016-10-03 17:49:30 +00:00
|
|
|
}
|
2016-08-31 16:27:37 +00:00
|
|
|
|
2017-10-24 23:28:52 +00:00
|
|
|
func (ac *accumulator) AddSummary(
|
|
|
|
measurement string,
|
|
|
|
fields map[string]interface{},
|
|
|
|
tags map[string]string,
|
|
|
|
t ...time.Time,
|
|
|
|
) {
|
|
|
|
if m := ac.maker.MakeMetric(measurement, fields, tags, telegraf.Summary, ac.getTime(t)); m != nil {
|
|
|
|
ac.metrics <- m
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ac *accumulator) AddHistogram(
|
|
|
|
measurement string,
|
|
|
|
fields map[string]interface{},
|
|
|
|
tags map[string]string,
|
|
|
|
t ...time.Time,
|
|
|
|
) {
|
|
|
|
if m := ac.maker.MakeMetric(measurement, fields, tags, telegraf.Histogram, ac.getTime(t)); m != nil {
|
|
|
|
ac.metrics <- m
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-25 12:09:49 +00:00
|
|
|
// AddError passes a runtime error to the accumulator.
|
|
|
|
// The error will be tagged with the plugin name and written to the log.
|
|
|
|
func (ac *accumulator) AddError(err error) {
|
|
|
|
if err == nil {
|
|
|
|
return
|
|
|
|
}
|
2016-11-07 08:34:46 +00:00
|
|
|
NErrors.Incr(1)
|
2016-07-25 12:09:49 +00:00
|
|
|
//TODO suppress/throttle consecutive duplicate errors?
|
2016-09-08 14:22:10 +00:00
|
|
|
log.Printf("E! Error in plugin [%s]: %s", ac.maker.Name(), err)
|
2016-05-19 15:36:58 +00:00
|
|
|
}
|
|
|
|
|
2016-06-13 14:21:11 +00:00
|
|
|
// SetPrecision takes two time.Duration objects. If the first is non-zero,
|
|
|
|
// it sets that as the precision. Otherwise, it takes the second argument
|
|
|
|
// as the order of time that the metrics should be rounded to, with the
|
|
|
|
// maximum being 1s.
|
|
|
|
func (ac *accumulator) SetPrecision(precision, interval time.Duration) {
|
|
|
|
if precision > 0 {
|
|
|
|
ac.precision = precision
|
|
|
|
return
|
|
|
|
}
|
|
|
|
switch {
|
|
|
|
case interval >= time.Second:
|
|
|
|
ac.precision = time.Second
|
|
|
|
case interval >= time.Millisecond:
|
|
|
|
ac.precision = time.Millisecond
|
|
|
|
case interval >= time.Microsecond:
|
|
|
|
ac.precision = time.Microsecond
|
|
|
|
default:
|
|
|
|
ac.precision = time.Nanosecond
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-08 14:22:10 +00:00
|
|
|
func (ac accumulator) getTime(t []time.Time) time.Time {
|
|
|
|
var timestamp time.Time
|
|
|
|
if len(t) > 0 {
|
|
|
|
timestamp = t[0]
|
|
|
|
} else {
|
|
|
|
timestamp = time.Now()
|
2016-10-03 17:49:30 +00:00
|
|
|
}
|
2016-09-08 14:22:10 +00:00
|
|
|
return timestamp.Round(ac.precision)
|
2016-01-27 21:21:36 +00:00
|
|
|
}
|