97
97
showVersion = flag .Bool ("version" , false , "print version string" )
98
98
deleteGauges = flag .Bool ("delete-gauges" , true , "don't send values to graphite for inactive gauges, as opposed to sending the previous value" )
99
99
persistCountKeys = flag .Uint ("persist-count-keys" , 60 , "number of flush-intervals to persist count keys (at zero)" )
100
+ persistTimerKeys = flag .Uint ("persist-timer-counts" , 0 , "number of flush-intervals to persist timer count keys (at zero)" )
100
101
receiveCounter = flag .String ("receive-counter" , "" , "Metric name for total metrics received per interval" )
101
102
percentThreshold = Percentiles {}
102
103
prefix = flag .String ("prefix" , "" , "Prefix for all stats" )
@@ -116,6 +117,7 @@ var (
116
117
timers = make (map [string ]Float64Slice )
117
118
sets = make (map [string ][]string )
118
119
inactivCounters = make (map [string ]uint )
120
+ inactivTimers = make (map [string ]uint )
119
121
)
120
122
121
123
func monitor () {
@@ -144,8 +146,14 @@ func packetHandler(s *Packet) {
144
146
145
147
switch s .Modifier {
146
148
case "ms" :
147
- // if missing gets nil []float64, works with append()
148
- timers [s .Bucket ] = append (timers [s .Bucket ], s .ValFlt )
149
+ vals := timers [s .Bucket ]
150
+ if vals == nil {
151
+ vals = make ([]float64 , 1 , 5 )
152
+ vals [0 ] = 0.0
153
+ }
154
+ // first slot is sampled count, following are times
155
+ vals [0 ] += float64 (1 / s .Sampling )
156
+ timers [s .Bucket ] = append (vals , s .ValFlt )
149
157
case "g" :
150
158
var gaugeValue float64
151
159
if s .ValStr == "" {
@@ -290,8 +298,12 @@ func processSets(buffer *bytes.Buffer, now int64) int64 {
290
298
291
299
func processTimers (buffer * bytes.Buffer , now int64 , pctls Percentiles ) int64 {
292
300
var num int64
301
+ persist := * persistTimerKeys
302
+
293
303
for bucket , timer := range timers {
294
304
num ++
305
+ sampled := timer [0 ]
306
+ timer = timer [1 :]
295
307
296
308
sort .Sort (timer )
297
309
min := timer [0 ]
@@ -336,13 +348,31 @@ func processTimers(buffer *bytes.Buffer, now int64, pctls Percentiles) int64 {
336
348
mean_s := strconv .FormatFloat (mean , 'f' , - 1 , 64 )
337
349
max_s := strconv .FormatFloat (max , 'f' , - 1 , 64 )
338
350
min_s := strconv .FormatFloat (min , 'f' , - 1 , 64 )
351
+ count_s := strconv .FormatFloat (sampled , 'f' , - 1 , 64 )
339
352
340
353
fmt .Fprintf (buffer , "%s%s.mean%s %s %d\n " , * prefix , bucket , * postfix , mean_s , now )
341
354
fmt .Fprintf (buffer , "%s%s.upper%s %s %d\n " , * prefix , bucket , * postfix , max_s , now )
342
355
fmt .Fprintf (buffer , "%s%s.lower%s %s %d\n " , * prefix , bucket , * postfix , min_s , now )
343
- fmt .Fprintf (buffer , "%s%s.count%s %d %d\n " , * prefix , bucket , * postfix , count , now )
356
+ fmt .Fprintf (buffer , "%s%s.count%s %s %d\n " , * prefix , bucket , * postfix , count_s , now )
344
357
345
358
delete (timers , bucket )
359
+ if persist > 0 {
360
+ countKey := fmt .Sprintf ("%s%s.count%s" , * prefix , bucket , * postfix )
361
+ inactivTimers [countKey ] = 0
362
+ }
363
+ }
364
+
365
+ // continue sending zeros for no-longer-active timer counts for configured flush-intervals
366
+ for bucket , purgeCount := range inactivTimers {
367
+ if purgeCount > 0 {
368
+ fmt .Fprintf (buffer , "%s 0 %d\n " , bucket , now )
369
+ num ++
370
+ }
371
+ if purgeCount >= persist {
372
+ delete (inactivTimers , bucket )
373
+ } else {
374
+ inactivTimers [bucket ] = purgeCount + 1
375
+ }
346
376
}
347
377
return num
348
378
}
0 commit comments