// 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 metricsMonitor() { period := time.Duration(*flushInterval) * time.Second ticker := time.NewTicker(period) for { select { case sig := <-signalchan: switch sig { case syscall.SIGTERM, syscall.SIGINT: fmt.Printf("!! Caught signal %d... shutting down\n", sig) if err := submit(time.Now().Add(period)); err != nil { log.Printf("ERROR: %s", err) } return default: fmt.Printf("unknown signal %d, ignoring\n", sig) } case <-ticker.C: if err := submit(time.Now().Add(period)); err != nil { log.Printf("ERROR: %s", err) } events.Broadcast <- "flush" case s := <-Metrics: var name string if s.Modifier == "ms" { timer.Add(timers, s) name = "timer" } else if s.Modifier == "g" { gauges[s.Bucket] = s.Value name = "gauge" } else { counter.Add(counters, s) name = "counter" } k := fmt.Sprintf("%sdirection=in.statsd_type=%s.target_type=count.unit=Metric", prefix_internal, name) _, ok := counters[k] if !ok { counters[k] = 1 } else { counters[k] += 1 } } } }
func TestMetrics20Count(t *testing.T) { d := []byte("foo=bar.target_type=count.unit=B:5|c\nfoo=bar.target_type=count.unit=B:10|c") packets := udp.ParseMessage(d, prefix_internal, output, udp.ParseLine) for _, p := range packets { counter.Add(counters, p) } var buff bytes.Buffer var num int64 num += processCounters(&buff, time.Now().Unix(), Percentiles{ &Percentile{ 75, "75", }, }) dataForGraphite := buff.String() assert.T(t, strings.Contains(dataForGraphite, "foo=bar.target_type=rate.unit=Bps 1.5")) }