From 9000d115df77cd2d0c0b76efeae637ae36fe3d05 Mon Sep 17 00:00:00 2001 From: Pierce Lopez Date: Fri, 27 Jul 2018 02:08:24 -0400 Subject: [PATCH 1/6] also catch SIGINT signal for graceful shutdown in addition to current SIGTERM --- statsdaemon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/statsdaemon.go b/statsdaemon.go index a4d24e6..35156ea 100644 --- a/statsdaemon.go +++ b/statsdaemon.go @@ -583,7 +583,7 @@ func main() { *postfix = sanitizeBucket([]byte(*postfix)) signalchan = make(chan os.Signal, 1) - signal.Notify(signalchan, syscall.SIGTERM) + signal.Notify(signalchan, syscall.SIGTERM, syscall.SIGINT) go udpListener() if *tcpServiceAddress != "" { From ce416fffa6ef39eac584dcbee011df77267d3996 Mon Sep 17 00:00:00 2001 From: Pierce Lopez Date: Fri, 27 Jul 2018 02:10:13 -0400 Subject: [PATCH 2/6] use flag.Set() instead of changing prefix/postfix pointers directly possibly more robust --- statsdaemon.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/statsdaemon.go b/statsdaemon.go index 35156ea..25d9f21 100644 --- a/statsdaemon.go +++ b/statsdaemon.go @@ -579,8 +579,8 @@ func main() { fmt.Printf("statsdaemon v%s (built w/%s)\n", VERSION, runtime.Version()) return } - *prefix = sanitizeBucket([]byte(*prefix)) - *postfix = sanitizeBucket([]byte(*postfix)) + flag.Set("prefix", sanitizeBucket([]byte(*prefix))) + flag.Set("postfix", sanitizeBucket([]byte(*postfix))) signalchan = make(chan os.Signal, 1) signal.Notify(signalchan, syscall.SIGTERM, syscall.SIGINT) From b50abac7591c49def25dde45e9891d33b8503406 Mon Sep 17 00:00:00 2001 From: Pierce Lopez Date: Fri, 27 Jul 2018 02:34:08 -0400 Subject: [PATCH 3/6] simplify packetHandler: go map missing-key gets usable zero value works out great: adding to zero works, and a "nil" slice, which acts like an empty slice, works with append() --- statsdaemon.go | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/statsdaemon.go b/statsdaemon.go index 25d9f21..09ccbeb 100644 --- a/statsdaemon.go +++ b/statsdaemon.go @@ -140,20 +140,13 @@ func monitor() { func packetHandler(s *Packet) { if *receiveCounter != "" { - v, ok := counters[*receiveCounter] - if !ok || v < 0 { - counters[*receiveCounter] = 0 - } + // if missing gets 0.0 (and adds 1 and stores) counters[*receiveCounter] += 1 } switch s.Modifier { case "ms": - _, ok := timers[s.Bucket] - if !ok { - var t Float64Slice - timers[s.Bucket] = t - } + // if missing gets nil []float64, works with append() timers[s.Bucket] = append(timers[s.Bucket], s.ValFlt) case "g": gaugeValue, _ := gauges[s.Bucket] @@ -178,16 +171,8 @@ func packetHandler(s *Packet) { gauges[s.Bucket] = gaugeValue case "c": - _, ok := counters[s.Bucket] - if !ok { - counters[s.Bucket] = 0 - } - counters[s.Bucket] += s.ValFlt * float64(1/s.Sampling) + counters[s.Bucket] += s.ValFlt / float64(s.Sampling) case "s": - _, ok := sets[s.Bucket] - if !ok { - sets[s.Bucket] = make([]string, 0) - } sets[s.Bucket] = append(sets[s.Bucket], s.ValStr) } } From ea7dcd415da86fb9fce02fa43f59ca9e9306c903 Mon Sep 17 00:00:00 2001 From: Pierce Lopez Date: Fri, 27 Jul 2018 02:37:30 -0400 Subject: [PATCH 4/6] simplify gauge "+"/"-": float64 naturally saturates, negative is OK Gauge relative change limit checks are a hold-over from when gauge values were uint64. float64 loses much precision at very high values, and it rounds to values it is able to represent: MaxFloat64 + 123456789.0 = MaxFloat64 (you have to subtract about 1e292 to get it to budge!) Negative gauge results seem to be part of the informal spec: > This implies you can't explicitly set a gauge to a negative number > without first setting it to zero. https://github.com/etsy/statsd/blob/master/docs/metric_types.md#gauges And really, who uses relative gauge changes anyway ... --- statsdaemon.go | 18 +++--------------- statsdaemon_test.go | 4 ++-- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/statsdaemon.go b/statsdaemon.go index 09ccbeb..e44e93f 100644 --- a/statsdaemon.go +++ b/statsdaemon.go @@ -149,26 +149,14 @@ func packetHandler(s *Packet) { // if missing gets nil []float64, works with append() timers[s.Bucket] = append(timers[s.Bucket], s.ValFlt) case "g": - gaugeValue, _ := gauges[s.Bucket] - + var gaugeValue float64 if s.ValStr == "" { gaugeValue = s.ValFlt } else if s.ValStr == "+" { - // watch out for overflows - if s.ValFlt > (math.MaxFloat64 - gaugeValue) { - gaugeValue = math.MaxFloat64 - } else { - gaugeValue += s.ValFlt - } + gaugeValue = gauges[s.Bucket] + s.ValFlt } else if s.ValStr == "-" { - // subtract checking for negative numbers - if s.ValFlt > gaugeValue { - gaugeValue = 0 - } else { - gaugeValue -= s.ValFlt - } + gaugeValue = gauges[s.Bucket] - s.ValFlt } - gauges[s.Bucket] = gaugeValue case "c": counters[s.Bucket] += s.ValFlt / float64(s.Sampling) diff --git a/statsdaemon_test.go b/statsdaemon_test.go index a657a9b..2ab5a4f 100644 --- a/statsdaemon_test.go +++ b/statsdaemon_test.go @@ -433,14 +433,14 @@ func TestPacketHandlerGauge(t *testing.T) { packetHandler(p) assert.Equal(t, gauges["gaugor"], float64(327)) - // <0 overflow + // going negative p.ValFlt = 10 p.ValStr = "" packetHandler(p) p.ValFlt = 20 p.ValStr = "-" packetHandler(p) - assert.Equal(t, gauges["gaugor"], float64(0)) + assert.Equal(t, gauges["gaugor"], float64(-10)) // >MaxFloat64 overflow p.ValFlt = float64(math.MaxFloat64 - 10) From 9fdc27bc143b0e6cc32458885b026a7e96cfd71a Mon Sep 17 00:00:00 2001 From: Pierce Lopez Date: Fri, 27 Jul 2018 15:21:47 -0400 Subject: [PATCH 5/6] add prefix and postfix only during final processing instead of just after parsing bucket/key before counting - less work if multiple messages aggregate into single bucket need special handling for receive-counter so it continues to not have prefix/postfix apply to it rename countInactivity to inactivCounters, change to map[string]uint (planning to add inactivTimers etc) update tests for prefix/postfix applied during different stage and minor cleanup to TestProcessCounters persist-count-keys bits --- statsdaemon.go | 71 +++++++++++++++++++++++++++------------------ statsdaemon_test.go | 71 +++++++++++++++++++++++++++++++-------------- 2 files changed, 92 insertions(+), 50 deletions(-) diff --git a/statsdaemon.go b/statsdaemon.go index e44e93f..680ff75 100644 --- a/statsdaemon.go +++ b/statsdaemon.go @@ -96,7 +96,7 @@ var ( debug = flag.Bool("debug", false, "print statistics sent to graphite") showVersion = flag.Bool("version", false, "print version string") deleteGauges = flag.Bool("delete-gauges", true, "don't send values to graphite for inactive gauges, as opposed to sending the previous value") - persistCountKeys = flag.Int64("persist-count-keys", 60, "number of flush-intervals to persist count keys") + persistCountKeys = flag.Uint("persist-count-keys", 60, "number of flush-intervals to persist count keys (at zero)") receiveCounter = flag.String("receive-counter", "", "Metric name for total metrics received per interval") percentThreshold = Percentiles{} prefix = flag.String("prefix", "", "Prefix for all stats") @@ -109,12 +109,13 @@ func init() { } var ( + receiveCount uint64 In = make(chan *Packet, MAX_UNPROCESSED_PACKETS) counters = make(map[string]float64) gauges = make(map[string]float64) timers = make(map[string]Float64Slice) - countInactivity = make(map[string]int64) sets = make(map[string][]string) + inactivCounters = make(map[string]uint) ) func monitor() { @@ -139,10 +140,7 @@ func monitor() { } func packetHandler(s *Packet) { - if *receiveCounter != "" { - // if missing gets 0.0 (and adds 1 and stores) - counters[*receiveCounter] += 1 - } + receiveCount++ switch s.Modifier { case "ms": @@ -224,21 +222,38 @@ func submit(deadline time.Time) error { func processCounters(buffer *bytes.Buffer, now int64) int64 { var num int64 - // continue sending zeros for counters for a short period of time even if we have no new data + persist := *persistCountKeys + + // avoid adding prefix/postfix to receiveCounter + if *receiveCounter != "" && receiveCount > 0 { + fmt.Fprintf(buffer, "%s %d %d\n", *receiveCounter, receiveCount, now) + if persist > 0 { + inactivCounters[*receiveCounter] = 0 + } + num++ + } + receiveCount = 0 + for bucket, value := range counters { - fmt.Fprintf(buffer, "%s %s %d\n", bucket, strconv.FormatFloat(value, 'f', -1, 64), now) + fullbucket := *prefix + bucket + *postfix + fmt.Fprintf(buffer, "%s %s %d\n", fullbucket, strconv.FormatFloat(value, 'f', -1, 64), now) delete(counters, bucket) - countInactivity[bucket] = 0 + if persist > 0 { + inactivCounters[fullbucket] = 0 + } num++ } - for bucket, purgeCount := range countInactivity { + + // continue sending zeros for no-longer-active counters for configured flush-intervals + for bucket, purgeCount := range inactivCounters { if purgeCount > 0 { fmt.Fprintf(buffer, "%s 0 %d\n", bucket, now) num++ } - countInactivity[bucket] += 1 - if countInactivity[bucket] > *persistCountKeys { - delete(countInactivity, bucket) + if purgeCount >= persist { + delete(inactivCounters, bucket) + } else { + inactivCounters[bucket] = purgeCount + 1 } } return num @@ -248,7 +263,8 @@ func processGauges(buffer *bytes.Buffer, now int64) int64 { var num int64 for bucket, currentValue := range gauges { - fmt.Fprintf(buffer, "%s %s %d\n", bucket, strconv.FormatFloat(currentValue, 'f', -1, 64), now) + valstr := strconv.FormatFloat(currentValue, 'f', -1, 64) + fmt.Fprintf(buffer, "%s%s%s %s %d\n", *prefix, bucket, *postfix, valstr, now) num++ if *deleteGauges { delete(gauges, bucket) @@ -266,7 +282,7 @@ func processSets(buffer *bytes.Buffer, now int64) int64 { uniqueSet[str] = true } - fmt.Fprintf(buffer, "%s %d %d\n", bucket, len(uniqueSet), now) + fmt.Fprintf(buffer, "%s%s%s %d %d\n", *prefix, bucket, *postfix, len(uniqueSet), now) delete(sets, bucket) } return num @@ -275,7 +291,6 @@ func processSets(buffer *bytes.Buffer, now int64) int64 { func processTimers(buffer *bytes.Buffer, now int64, pctls Percentiles) int64 { var num int64 for bucket, timer := range timers { - bucketWithoutPostfix := bucket[:len(bucket)-len(*postfix)] num++ sort.Sort(timer) @@ -307,27 +322,25 @@ func processTimers(buffer *bytes.Buffer, now int64, pctls Percentiles) int64 { maxAtThreshold = timer[indexOfPerc] } - var tmpl string - var pctstr string - if pct.float >= 0 { - tmpl = "%s.upper_%s%s %s %d\n" - pctstr = pct.str - } else { - tmpl = "%s.lower_%s%s %s %d\n" + ptype := "upper" + pctstr := pct.str + if pct.float < 0 { + ptype = "lower" pctstr = pct.str[1:] } threshold_s := strconv.FormatFloat(maxAtThreshold, 'f', -1, 64) - fmt.Fprintf(buffer, tmpl, bucketWithoutPostfix, pctstr, *postfix, threshold_s, now) + fmt.Fprintf(buffer, "%s%s.%s_%s%s %s %d\n", + *prefix, bucket, ptype, pctstr, *postfix, threshold_s, now) } mean_s := strconv.FormatFloat(mean, 'f', -1, 64) max_s := strconv.FormatFloat(max, 'f', -1, 64) min_s := strconv.FormatFloat(min, 'f', -1, 64) - fmt.Fprintf(buffer, "%s.mean%s %s %d\n", bucketWithoutPostfix, *postfix, mean_s, now) - fmt.Fprintf(buffer, "%s.upper%s %s %d\n", bucketWithoutPostfix, *postfix, max_s, now) - fmt.Fprintf(buffer, "%s.lower%s %s %d\n", bucketWithoutPostfix, *postfix, min_s, now) - fmt.Fprintf(buffer, "%s.count%s %d %d\n", bucketWithoutPostfix, *postfix, count, now) + fmt.Fprintf(buffer, "%s%s.mean%s %s %d\n", *prefix, bucket, *postfix, mean_s, now) + fmt.Fprintf(buffer, "%s%s.upper%s %s %d\n", *prefix, bucket, *postfix, max_s, now) + fmt.Fprintf(buffer, "%s%s.lower%s %s %d\n", *prefix, bucket, *postfix, min_s, now) + fmt.Fprintf(buffer, "%s%s.count%s %d %d\n", *prefix, bucket, *postfix, count, now) delete(timers, bucket) } @@ -486,7 +499,7 @@ func parseLine(line []byte) *Packet { } return &Packet{ - Bucket: *prefix + sanitizeBucket(name) + *postfix, + Bucket: sanitizeBucket(name), ValFlt: floatval, ValStr: strval, Modifier: typeCode, diff --git a/statsdaemon_test.go b/statsdaemon_test.go index 2ab5a4f..1ffb8f0 100644 --- a/statsdaemon_test.go +++ b/statsdaemon_test.go @@ -202,21 +202,15 @@ func TestParseLineMisc(t *testing.T) { assert.Equal(t, float32(1), packet.Sampling) flag.Set("prefix", "test.") + flag.Set("postfix", ".test") d = []byte("prefix:4|c") packet = parseLine(d) - assert.Equal(t, "test.prefix", packet.Bucket) + // prefix/postfix not in Bucket/key, added in processCounters() etc + assert.Equal(t, "prefix", packet.Bucket) assert.Equal(t, float64(4), packet.ValFlt) assert.Equal(t, "c", packet.Modifier) assert.Equal(t, float32(1), packet.Sampling) flag.Set("prefix", "") - - flag.Set("postfix", ".test") - d = []byte("postfix:4|c") - packet = parseLine(d) - assert.Equal(t, "postfix.test", packet.Bucket) - assert.Equal(t, float64(4), packet.ValFlt) - assert.Equal(t, "c", packet.Modifier) - assert.Equal(t, float32(1), packet.Sampling) flag.Set("postfix", "") d = []byte("a.key.with-0.dash:4|c\ngauge:3|g") @@ -367,8 +361,9 @@ func TestMultiTcp(t *testing.T) { } func TestPacketHandlerReceiveCounter(t *testing.T) { + flag.Set("receive-counter", "countme") + receiveCount = 0 counters = make(map[string]float64) - *receiveCounter = "countme" p := &Packet{ Bucket: "gorets", @@ -377,10 +372,11 @@ func TestPacketHandlerReceiveCounter(t *testing.T) { Sampling: float32(1), } packetHandler(p) - assert.Equal(t, counters["countme"], float64(1)) - + assert.Equal(t, receiveCount, uint64(1)) packetHandler(p) - assert.Equal(t, counters["countme"], float64(2)) + assert.Equal(t, receiveCount, uint64(2)) + + flag.Set("receive-counter", "") } func TestPacketHandlerCount(t *testing.T) { @@ -491,8 +487,8 @@ func TestPacketHandlerSet(t *testing.T) { } func TestProcessCounters(t *testing.T) { - - *persistCountKeys = int64(10) + flag.Set("persist-count-keys", "10") + receiveCount = 0 counters = make(map[string]float64) var buffer bytes.Buffer now := int64(1418052649) @@ -504,7 +500,7 @@ func TestProcessCounters(t *testing.T) { assert.Equal(t, buffer.String(), "gorets 123 1418052649\n") // run processCounters() enough times to make sure it purges items - for i := 0; i < int(*persistCountKeys)+10; i++ { + for i := 0; i < int(*persistCountKeys); i++ { num = processCounters(&buffer, now) } lines := bytes.Split(buffer.Bytes(), []byte("\n")) @@ -515,6 +511,37 @@ func TestProcessCounters(t *testing.T) { assert.Equal(t, string(lines[*persistCountKeys]), "gorets 0 1418052649") } +func TestProcessCountersPrefix(t *testing.T) { + counters = make(map[string]float64) + var buffer bytes.Buffer + now := int64(1418052649) + + flag.Set("persist-count-keys", "2") + flag.Set("prefix", "pre.") + flag.Set("postfix", ".post") + + counters["gorets"] = float64(123) + num := processCounters(&buffer, now) + firstOutput := buffer.String() + // run processCounters() enough times to make sure it purges items + for i := 0; i < int(*persistCountKeys); i++ { + processCounters(&buffer, now) + } + + // set back flags before asserting + flag.Set("persist-count-keys", "60") + flag.Set("prefix", "") + flag.Set("postfix", "") + + assert.Equal(t, num, int64(1)) + assert.Equal(t, firstOutput, "pre.gorets.post 123 1418052649\n") + + lines := bytes.Split(buffer.Bytes(), []byte("\n")) + assert.Equal(t, string(lines[0]), "pre.gorets.post 123 1418052649") + assert.Equal(t, string(lines[1]), "pre.gorets.post 0 1418052649") + assert.Equal(t, string(lines[2]), "pre.gorets.post 0 1418052649") +} + func TestProcessTimers(t *testing.T) { // Some data with expected mean of 20 timers = make(map[string]Float64Slice) @@ -644,11 +671,11 @@ func TestProcessTimersUpperPercentile(t *testing.T) { } func TestProcessTimersUpperPercentilePostfix(t *testing.T) { + flag.Set("prefix", "pfx.") flag.Set("postfix", ".test") // Some data with expected 75% of 2 timers = make(map[string]Float64Slice) - timers["postfix_response_time.test"] = []float64{0, 1, 2, 3} - + timers["postfix_response_time"] = []float64{0, 1, 2, 3} now := int64(1418052649) var buffer bytes.Buffer @@ -658,12 +685,14 @@ func TestProcessTimersUpperPercentilePostfix(t *testing.T) { "75", }, }) - lines := bytes.Split(buffer.Bytes(), []byte("\n")) - assert.Equal(t, num, int64(1)) - assert.Equal(t, string(lines[0]), "postfix_response_time.upper_75.test 2 1418052649") + // set flags back before asserting + flag.Set("prefix", "") flag.Set("postfix", "") + + assert.Equal(t, num, int64(1)) + assert.Equal(t, string(lines[0]), "pfx.postfix_response_time.upper_75.test 2 1418052649") } func TestProcessTimesLowerPercentile(t *testing.T) { From c572d91bf297779d6cdb8c341204c64c6683e98e Mon Sep 17 00:00:00 2001 From: Pierce Lopez Date: Fri, 27 Jul 2018 15:28:29 -0400 Subject: [PATCH 6/6] fix timer count sampling, new flag -persist-timer-counts by putting the sampled count first in the time values array and with new inactivTimers map also, BenchmarkManyDifferentSensors should clear the stats maps ... --- statsdaemon.go | 36 +++++++++++++++++++++++++++++++++--- statsdaemon_test.go | 22 ++++++++++++++-------- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/statsdaemon.go b/statsdaemon.go index 680ff75..654063a 100644 --- a/statsdaemon.go +++ b/statsdaemon.go @@ -97,6 +97,7 @@ var ( showVersion = flag.Bool("version", false, "print version string") deleteGauges = flag.Bool("delete-gauges", true, "don't send values to graphite for inactive gauges, as opposed to sending the previous value") persistCountKeys = flag.Uint("persist-count-keys", 60, "number of flush-intervals to persist count keys (at zero)") + persistTimerKeys = flag.Uint("persist-timer-counts", 0, "number of flush-intervals to persist timer count keys (at zero)") receiveCounter = flag.String("receive-counter", "", "Metric name for total metrics received per interval") percentThreshold = Percentiles{} prefix = flag.String("prefix", "", "Prefix for all stats") @@ -116,6 +117,7 @@ var ( timers = make(map[string]Float64Slice) sets = make(map[string][]string) inactivCounters = make(map[string]uint) + inactivTimers = make(map[string]uint) ) func monitor() { @@ -144,8 +146,14 @@ func packetHandler(s *Packet) { switch s.Modifier { case "ms": - // if missing gets nil []float64, works with append() - timers[s.Bucket] = append(timers[s.Bucket], s.ValFlt) + vals := timers[s.Bucket] + if vals == nil { + vals = make([]float64, 1, 5) + vals[0] = 0.0 + } + // first slot is sampled count, following are times + vals[0] += float64(1 / s.Sampling) + timers[s.Bucket] = append(vals, s.ValFlt) case "g": var gaugeValue float64 if s.ValStr == "" { @@ -290,8 +298,12 @@ func processSets(buffer *bytes.Buffer, now int64) int64 { func processTimers(buffer *bytes.Buffer, now int64, pctls Percentiles) int64 { var num int64 + persist := *persistTimerKeys + for bucket, timer := range timers { num++ + sampled := timer[0] + timer = timer[1:] sort.Sort(timer) min := timer[0] @@ -336,13 +348,31 @@ func processTimers(buffer *bytes.Buffer, now int64, pctls Percentiles) int64 { mean_s := strconv.FormatFloat(mean, 'f', -1, 64) max_s := strconv.FormatFloat(max, 'f', -1, 64) min_s := strconv.FormatFloat(min, 'f', -1, 64) + count_s := strconv.FormatFloat(sampled, 'f', -1, 64) fmt.Fprintf(buffer, "%s%s.mean%s %s %d\n", *prefix, bucket, *postfix, mean_s, now) fmt.Fprintf(buffer, "%s%s.upper%s %s %d\n", *prefix, bucket, *postfix, max_s, now) fmt.Fprintf(buffer, "%s%s.lower%s %s %d\n", *prefix, bucket, *postfix, min_s, now) - fmt.Fprintf(buffer, "%s%s.count%s %d %d\n", *prefix, bucket, *postfix, count, now) + fmt.Fprintf(buffer, "%s%s.count%s %s %d\n", *prefix, bucket, *postfix, count_s, now) delete(timers, bucket) + if persist > 0 { + countKey := fmt.Sprintf("%s%s.count%s", *prefix, bucket, *postfix) + inactivTimers[countKey] = 0 + } + } + + // continue sending zeros for no-longer-active timer counts for configured flush-intervals + for bucket, purgeCount := range inactivTimers { + if purgeCount > 0 { + fmt.Fprintf(buffer, "%s 0 %d\n", bucket, now) + num++ + } + if purgeCount >= persist { + delete(inactivTimers, bucket) + } else { + inactivTimers[bucket] = purgeCount + 1 + } } return num } diff --git a/statsdaemon_test.go b/statsdaemon_test.go index 1ffb8f0..adc08a9 100644 --- a/statsdaemon_test.go +++ b/statsdaemon_test.go @@ -458,13 +458,15 @@ func TestPacketHandlerTimer(t *testing.T) { Sampling: float32(1), } packetHandler(p) - assert.Equal(t, len(timers["glork"]), 1) - assert.Equal(t, timers["glork"][0], float64(320)) + assert.Equal(t, len(timers["glork"]), 2) + assert.Equal(t, timers["glork"][0], float64(1)) + assert.Equal(t, timers["glork"][1], float64(320)) p.ValFlt = float64(100) packetHandler(p) - assert.Equal(t, len(timers["glork"]), 2) - assert.Equal(t, timers["glork"][1], float64(100)) + assert.Equal(t, len(timers["glork"]), 3) + assert.Equal(t, timers["glork"][0], float64(2)) + assert.Equal(t, timers["glork"][2], float64(100)) } func TestPacketHandlerSet(t *testing.T) { @@ -545,7 +547,7 @@ func TestProcessCountersPrefix(t *testing.T) { func TestProcessTimers(t *testing.T) { // Some data with expected mean of 20 timers = make(map[string]Float64Slice) - timers["response_time"] = []float64{0, 30, 30} + timers["response_time"] = []float64{3, 0, 30, 30} now := int64(1418052649) @@ -652,7 +654,7 @@ func TestProcessSets(t *testing.T) { func TestProcessTimersUpperPercentile(t *testing.T) { // Some data with expected 75% of 2 timers = make(map[string]Float64Slice) - timers["response_time"] = []float64{0, 1, 2, 3} + timers["response_time"] = []float64{4, 0, 1, 2, 3} now := int64(1418052649) @@ -675,7 +677,7 @@ func TestProcessTimersUpperPercentilePostfix(t *testing.T) { flag.Set("postfix", ".test") // Some data with expected 75% of 2 timers = make(map[string]Float64Slice) - timers["postfix_response_time"] = []float64{0, 1, 2, 3} + timers["postfix_response_time"] = []float64{4, 0, 1, 2, 3} now := int64(1418052649) var buffer bytes.Buffer @@ -697,7 +699,7 @@ func TestProcessTimersUpperPercentilePostfix(t *testing.T) { func TestProcessTimesLowerPercentile(t *testing.T) { timers = make(map[string]Float64Slice) - timers["time"] = []float64{0, 1, 2, 3} + timers["time"] = []float64{4, 0, 1, 2, 3} now := int64(1418052649) @@ -769,7 +771,11 @@ func TestMultipleUDPSends(t *testing.T) { } func BenchmarkManyDifferentSensors(t *testing.B) { + counters = make(map[string]float64) + gauges = make(map[string]float64) + timers = make(map[string]Float64Slice) r := rand.New(rand.NewSource(438)) + for i := 0; i < 1000; i++ { bucket := "response_time" + strconv.Itoa(i) for i := 0; i < 10000; i++ {