// metricsMonitor basically guards the metrics datastructures. // it typically receives metrics on the Metrics channel but also responds to // external signals and every flushInterval, computes and flushes the data func (s *StatsDaemon) metricsMonitor() { period := time.Duration(s.flushInterval) * time.Second tick := ticker.GetAlignedTicker(period) var c *counters.Counters var g *gauges.Gauges var t *timers.Timers initializeCounters := func() { c = counters.New(s.prefix_rates) g = gauges.New(s.prefix_gauges) t = timers.New(s.prefix_timers, s.pct) for _, name := range []string{"timer", "gauge", "counter"} { c.Add(&common.Metric{ Bucket: fmt.Sprintf("%sdirection_is_in.statsd_type_is_%s.target_type_is_count.unit_is_Metric", s.prefix, name), Sampling: 1, }) } } initializeCounters() for { select { case sig := <-s.signalchan: switch sig { case syscall.SIGTERM, syscall.SIGINT: fmt.Printf("!! Caught signal %s... shutting down\n", sig) if err := s.submit(c, g, t, time.Now().Add(period)); err != nil { log.Printf("ERROR: %s", err) } return default: fmt.Printf("unknown signal %s, ignoring\n", sig) } case <-tick.C: go func(c *counters.Counters, g *gauges.Gauges, t *timers.Timers) { if err := s.submit(c, g, t, time.Now().Add(period)); err != nil { log.Printf("ERROR: %s", err) } s.events.Broadcast <- "flush" }(c, g, t) initializeCounters() tick = ticker.GetAlignedTicker(period) case m := <-s.Metrics: var name string if m.Modifier == "ms" { t.Add(m) name = "timer" } else if m.Modifier == "g" { g.Add(m) name = "gauge" } else { c.Add(m) name = "counter" } c.Add(&common.Metric{ Bucket: fmt.Sprintf("%sdirection_is_in.statsd_type_is_%s.target_type_is_count.unit_is_Metric", s.prefix, name), Value: 1, Sampling: 1, }) } } }