func BenchmarkMillionDifferentCountersAddAndProcess(b *testing.B) { metrics := getDifferentCounters(1000000) b.ResetTimer() c := counters.New("bar") for i := 0; i < len(metrics); i++ { for n := 0; n < b.N; n++ { c.Add(&metrics[i]) } } c.Process(&bytes.Buffer{}, time.Now().Unix(), 10) }
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) c := counters.New("") for _, p := range packets { c.Add(p) } var buff bytes.Buffer var num int64 num += c.Process(&buff, time.Now().Unix(), 10) dataForGraphite := buff.String() assert.T(t, strings.Contains(dataForGraphite, "foo=bar.target_type=rate.unit=Bps 1.5")) }
// 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, }) } } }