2016-09-08 14:22:10 +00:00
|
|
|
package models
|
|
|
|
|
|
|
|
import (
|
2018-11-05 21:34:28 +00:00
|
|
|
"sync"
|
2016-09-08 14:22:10 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/influxdata/telegraf"
|
2019-03-01 19:21:31 +00:00
|
|
|
"github.com/influxdata/telegraf/metric"
|
2018-11-05 21:34:28 +00:00
|
|
|
"github.com/influxdata/telegraf/selfstat"
|
2016-09-08 14:22:10 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type RunningAggregator struct {
|
2018-11-05 21:34:28 +00:00
|
|
|
sync.Mutex
|
|
|
|
Aggregator telegraf.Aggregator
|
|
|
|
Config *AggregatorConfig
|
2016-10-10 12:43:47 +00:00
|
|
|
periodStart time.Time
|
|
|
|
periodEnd time.Time
|
2019-08-21 23:49:07 +00:00
|
|
|
log telegraf.Logger
|
2018-11-05 21:34:28 +00:00
|
|
|
|
|
|
|
MetricsPushed selfstat.Stat
|
|
|
|
MetricsFiltered selfstat.Stat
|
|
|
|
MetricsDropped selfstat.Stat
|
|
|
|
PushTime selfstat.Stat
|
2016-09-22 17:10:51 +00:00
|
|
|
}
|
|
|
|
|
2019-08-21 23:49:07 +00:00
|
|
|
func NewRunningAggregator(aggregator telegraf.Aggregator, config *AggregatorConfig) *RunningAggregator {
|
2019-10-23 19:40:31 +00:00
|
|
|
tags := map[string]string{"aggregator": config.Name}
|
|
|
|
if config.Alias != "" {
|
|
|
|
tags["alias"] = config.Alias
|
|
|
|
}
|
|
|
|
|
2020-02-25 18:40:29 +00:00
|
|
|
aggErrorsRegister := selfstat.Register("aggregate", "errors", tags)
|
|
|
|
logger := NewLogger("aggregators", config.Name, config.Alias)
|
|
|
|
logger.OnErr(func() {
|
|
|
|
aggErrorsRegister.Incr(1)
|
|
|
|
})
|
2019-08-21 23:49:07 +00:00
|
|
|
|
|
|
|
setLogIfExist(aggregator, logger)
|
|
|
|
|
2016-09-22 17:10:51 +00:00
|
|
|
return &RunningAggregator{
|
2018-11-05 21:34:28 +00:00
|
|
|
Aggregator: aggregator,
|
|
|
|
Config: config,
|
|
|
|
MetricsPushed: selfstat.Register(
|
|
|
|
"aggregate",
|
|
|
|
"metrics_pushed",
|
2019-10-23 19:40:31 +00:00
|
|
|
tags,
|
2018-11-05 21:34:28 +00:00
|
|
|
),
|
|
|
|
MetricsFiltered: selfstat.Register(
|
|
|
|
"aggregate",
|
|
|
|
"metrics_filtered",
|
2019-10-23 19:40:31 +00:00
|
|
|
tags,
|
2018-11-05 21:34:28 +00:00
|
|
|
),
|
|
|
|
MetricsDropped: selfstat.Register(
|
|
|
|
"aggregate",
|
|
|
|
"metrics_dropped",
|
2019-10-23 19:40:31 +00:00
|
|
|
tags,
|
2018-11-05 21:34:28 +00:00
|
|
|
),
|
|
|
|
PushTime: selfstat.Register(
|
|
|
|
"aggregate",
|
|
|
|
"push_time_ns",
|
2019-10-23 19:40:31 +00:00
|
|
|
tags,
|
2018-11-05 21:34:28 +00:00
|
|
|
),
|
2019-08-21 23:49:07 +00:00
|
|
|
log: logger,
|
2016-09-22 17:10:51 +00:00
|
|
|
}
|
2016-09-08 14:22:10 +00:00
|
|
|
}
|
|
|
|
|
2018-09-28 21:48:20 +00:00
|
|
|
// AggregatorConfig is the common config for all aggregators.
|
2016-09-08 14:22:10 +00:00
|
|
|
type AggregatorConfig struct {
|
2018-09-28 21:48:20 +00:00
|
|
|
Name string
|
2019-08-21 23:49:07 +00:00
|
|
|
Alias string
|
2018-09-28 21:48:20 +00:00
|
|
|
DropOriginal bool
|
|
|
|
Period time.Duration
|
|
|
|
Delay time.Duration
|
2019-07-31 19:52:12 +00:00
|
|
|
Grace time.Duration
|
2016-09-08 14:22:10 +00:00
|
|
|
|
|
|
|
NameOverride string
|
|
|
|
MeasurementPrefix string
|
|
|
|
MeasurementSuffix string
|
|
|
|
Tags map[string]string
|
|
|
|
Filter Filter
|
|
|
|
}
|
|
|
|
|
2019-08-21 23:49:07 +00:00
|
|
|
func (r *RunningAggregator) LogName() string {
|
|
|
|
return logName("aggregators", r.Config.Name, r.Config.Alias)
|
2016-09-08 14:22:10 +00:00
|
|
|
}
|
|
|
|
|
2019-06-14 22:12:27 +00:00
|
|
|
func (r *RunningAggregator) Init() error {
|
|
|
|
if p, ok := r.Aggregator.(telegraf.Initializer); ok {
|
|
|
|
err := p.Init()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-11-05 21:34:28 +00:00
|
|
|
func (r *RunningAggregator) Period() time.Duration {
|
|
|
|
return r.Config.Period
|
|
|
|
}
|
|
|
|
|
2019-03-29 22:40:33 +00:00
|
|
|
func (r *RunningAggregator) EndPeriod() time.Time {
|
|
|
|
return r.periodEnd
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RunningAggregator) UpdateWindow(start, until time.Time) {
|
2018-11-05 21:34:28 +00:00
|
|
|
r.periodStart = start
|
2019-03-29 22:40:33 +00:00
|
|
|
r.periodEnd = until
|
2019-08-21 23:49:07 +00:00
|
|
|
r.log.Debugf("Updated aggregation range [%s, %s]", start, until)
|
2018-11-05 21:34:28 +00:00
|
|
|
}
|
|
|
|
|
2018-09-28 21:48:20 +00:00
|
|
|
func (r *RunningAggregator) MakeMetric(metric telegraf.Metric) telegraf.Metric {
|
2016-09-08 14:22:10 +00:00
|
|
|
m := makemetric(
|
2018-09-28 21:48:20 +00:00
|
|
|
metric,
|
2016-09-08 14:22:10 +00:00
|
|
|
r.Config.NameOverride,
|
|
|
|
r.Config.MeasurementPrefix,
|
|
|
|
r.Config.MeasurementSuffix,
|
|
|
|
r.Config.Tags,
|
2018-09-28 21:48:20 +00:00
|
|
|
nil)
|
2016-09-08 14:22:10 +00:00
|
|
|
|
2016-12-13 12:24:39 +00:00
|
|
|
if m != nil {
|
|
|
|
m.SetAggregate(true)
|
|
|
|
}
|
2016-09-08 14:22:10 +00:00
|
|
|
|
2018-11-05 21:34:28 +00:00
|
|
|
r.MetricsPushed.Incr(1)
|
|
|
|
|
2016-09-08 14:22:10 +00:00
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
2018-09-28 21:48:20 +00:00
|
|
|
// Add a metric to the aggregator and return true if the original metric
|
|
|
|
// should be dropped.
|
2019-03-01 19:21:31 +00:00
|
|
|
func (r *RunningAggregator) Add(m telegraf.Metric) bool {
|
|
|
|
if ok := r.Config.Filter.Select(m); !ok {
|
2018-09-28 21:48:20 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2019-03-29 22:40:33 +00:00
|
|
|
// Make a copy of the metric but don't retain tracking. We do not fail a
|
|
|
|
// delivery due to the aggregation not being sent because we can't create
|
|
|
|
// aggregations of historical data. Additionally, waiting for the
|
|
|
|
// aggregation to be pushed would introduce a hefty latency to delivery.
|
2019-03-01 19:21:31 +00:00
|
|
|
m = metric.FromMetric(m)
|
2019-01-08 19:56:44 +00:00
|
|
|
|
2019-03-01 19:21:31 +00:00
|
|
|
r.Config.Filter.Modify(m)
|
|
|
|
if len(m.FieldList()) == 0 {
|
2019-03-29 22:40:33 +00:00
|
|
|
r.MetricsFiltered.Incr(1)
|
2018-09-28 21:48:20 +00:00
|
|
|
return r.Config.DropOriginal
|
2016-09-08 14:22:10 +00:00
|
|
|
}
|
|
|
|
|
2018-11-05 21:34:28 +00:00
|
|
|
r.Lock()
|
|
|
|
defer r.Unlock()
|
2018-09-28 21:48:20 +00:00
|
|
|
|
2019-07-31 19:52:12 +00:00
|
|
|
if m.Time().Before(r.periodStart.Add(-r.Config.Grace)) || m.Time().After(r.periodEnd.Add(r.Config.Delay)) {
|
2019-09-23 22:39:50 +00:00
|
|
|
r.log.Debugf("Metric is outside aggregation window; discarding. %s: m: %s e: %s g: %s",
|
2019-08-21 23:49:07 +00:00
|
|
|
m.Time(), r.periodStart, r.periodEnd, r.Config.Grace)
|
2019-03-29 22:40:33 +00:00
|
|
|
r.MetricsDropped.Incr(1)
|
2018-12-11 00:07:08 +00:00
|
|
|
return r.Config.DropOriginal
|
2018-11-05 21:34:28 +00:00
|
|
|
}
|
2018-09-28 21:48:20 +00:00
|
|
|
|
2019-03-01 19:21:31 +00:00
|
|
|
r.Aggregator.Add(m)
|
2018-11-05 21:34:28 +00:00
|
|
|
return r.Config.DropOriginal
|
2016-09-22 17:10:51 +00:00
|
|
|
}
|
|
|
|
|
2018-11-05 21:34:28 +00:00
|
|
|
func (r *RunningAggregator) Push(acc telegraf.Accumulator) {
|
|
|
|
r.Lock()
|
|
|
|
defer r.Unlock()
|
2016-09-22 17:10:51 +00:00
|
|
|
|
2019-03-29 22:40:33 +00:00
|
|
|
since := r.periodEnd
|
|
|
|
until := r.periodEnd.Add(r.Config.Period)
|
|
|
|
r.UpdateWindow(since, until)
|
|
|
|
|
2018-11-05 21:34:28 +00:00
|
|
|
r.push(acc)
|
|
|
|
r.Aggregator.Reset()
|
2016-09-22 17:10:51 +00:00
|
|
|
}
|
|
|
|
|
2018-11-05 21:34:28 +00:00
|
|
|
func (r *RunningAggregator) push(acc telegraf.Accumulator) {
|
|
|
|
start := time.Now()
|
|
|
|
r.Aggregator.Push(acc)
|
|
|
|
elapsed := time.Since(start)
|
|
|
|
r.PushTime.Incr(elapsed.Nanoseconds())
|
2016-09-22 17:10:51 +00:00
|
|
|
}
|
2020-02-25 18:40:29 +00:00
|
|
|
|
|
|
|
func (r *RunningAggregator) Log() telegraf.Logger {
|
|
|
|
return r.log
|
|
|
|
}
|