// gatherWithTimeout gathers from the given input, with the given timeout. // when the given timeout is reached, gatherWithTimeout logs an error message // but continues waiting for it to return. This is to avoid leaving behind // hung processes, and to prevent re-calling the same hung process over and // over. func gatherWithTimeout( shutdown chan struct{}, input *models.RunningInput, acc *accumulator, timeout time.Duration, ) { ticker := time.NewTicker(timeout) defer ticker.Stop() done := make(chan error) go func() { done <- input.Input.Gather(acc) }() for { select { case err := <-done: if err != nil { log.Printf("E! ERROR in input [%s]: %s", input.Name(), err) } return case <-ticker.C: log.Printf("E! ERROR: input [%s] took longer to collect than "+ "collection interval (%s)", input.Name(), timeout) continue case <-shutdown: return } } }
func panicRecover(input *models.RunningInput) { if err := recover(); err != nil { trace := make([]byte, 2048) runtime.Stack(trace, true) log.Printf("E! FATAL: Input [%s] panicked: %s, Stack:\n%s\n", input.Name(), err, trace) log.Println("E! PLEASE REPORT THIS PANIC ON GITHUB with " + "stack trace, configuration, and OS information: " + "https://github.com/influxdata/telegraf/issues/new") } }
// gatherer runs the inputs that have been configured with their own // reporting interval. func (a *Agent) gatherer( shutdown chan struct{}, input *models.RunningInput, interval time.Duration, metricC chan telegraf.Metric, ) { defer panicRecover(input) ticker := time.NewTicker(interval) defer ticker.Stop() for { acc := NewAccumulator(input, metricC) acc.SetPrecision(a.Config.Agent.Precision.Duration, a.Config.Agent.Interval.Duration) input.SetDebug(a.Config.Agent.Debug) input.SetDefaultTags(a.Config.Tags) internal.RandomSleep(a.Config.Agent.CollectionJitter.Duration, shutdown) start := time.Now() gatherWithTimeout(shutdown, input, acc, interval) elapsed := time.Since(start) log.Printf("D! Input [%s] gathered metrics, (%s interval) in %s\n", input.Name(), interval, elapsed) select { case <-shutdown: return case <-ticker.C: continue } } }