func (g *graphitePush) PushMetric(mExp metric_export.MetricExporter, pn string) { metrics := mExp.RetGraphiteMetrics(pn) err := g.g.SendMetrics(metrics) if err != nil { glog.Infof("Error pushing metric", err) } }
// runProbes actually runs the probes. This is the core. func runProbes(pusher push_metric.Pusher, probes []modules.Prober, mExp metric_export.MetricExporter, ps *misc.ProbesStatus, stopCh chan bool) { for _, p := range probes { // Add some randomness to space out the probes a bit at start up. r := rand.New(rand.NewSource(time.Now().UnixNano())) time.Sleep(time.Duration(r.Intn(*probeSpaceOutTime)) * time.Second) if *pushMetric { pusher.Setup() } go func(p modules.Prober) { for { // Buffered channel so that the read happens even if there is nothing to receive it. Needed to // handle the timeout scenario as well as the situaion when the go routine has to return on stop // signal. respCh := make(chan *modules.ProbeData, 1) errCh := make(chan error, 1) pn := *p.Name() to := *p.TimeoutSecs() timer := time.NewTimer(time.Duration(*p.RunIntervalSecs()) * time.Second) glog.Infof("Launching new probe:%s", pn) startTime := time.Now().UnixNano() startTimeSecs := startTime / 1000000000 // used to expose time field in json metric expostion. go p.Run(respCh, errCh) select { case msg := <-respCh: err := misc.CheckProbeData(msg) mExp.IncProbeCount(pn, startTimeSecs) if err != nil { glog.Errorf("Error: %v", err) mExp.IncProbeErrorCount(pn, startTimeSecs) mExp.SetFieldValuesUnexpected(pn, startTimeSecs) ps.WriteProbeErrorStatus(pn, startTime, time.Now().UnixNano()) } else { mExp.SetFieldValues(pn, msg, startTimeSecs) ps.WriteProbeStatus(pn, msg, startTime, time.Now().UnixNano()) } case err_msg := <-errCh: glog.Errorf("Probe %s error'ed out: %v", pn, err_msg) mExp.IncProbeCount(pn, startTimeSecs) mExp.IncProbeErrorCount(pn, startTimeSecs) mExp.SetFieldValuesUnexpected(pn, startTimeSecs) ps.WriteProbeErrorStatus(pn, startTime, time.Now().UnixNano()) case <-time.After(time.Duration(to) * time.Second): glog.Errorf("Timed out probe:%v ", pn) mExp.IncProbeCount(pn, startTimeSecs) mExp.IncProbeTimeoutCount(pn, startTimeSecs) mExp.SetFieldValuesUnexpected(pn, startTimeSecs) ps.WriteProbeTimeoutStatus(pn, startTime, time.Now().UnixNano()) case <-stopCh: glog.Infof("Goroutine probe named: %s recieved stop signal. Returning.", pn) return } if *pushMetric { go pusher.PushMetric(mExp, pn) } <-timer.C } }(p) } }