Skip to content

Commit

Permalink
simplify gauge "+"/"-": float64 naturally saturates, negative is OK
Browse files Browse the repository at this point in the history
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 ...
  • Loading branch information
ploxiln committed Jul 31, 2018
1 parent b50abac commit ea7dcd4
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 17 deletions.
18 changes: 3 additions & 15 deletions statsdaemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions statsdaemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit ea7dcd4

Please sign in to comment.