Handle negative integers coming as unsigned integers from Aerospike (#1679)

* Handle negative integers coming as unsigned integers from Aerospike stats

* skip values with overflow

* aerospike stat values parsing tests

* better tests
This commit is contained in:
Denis Orlikhin 2016-09-05 16:29:14 +03:00 committed by Cameron Sparr
parent 54c9ba7639
commit 5628049440
2 changed files with 38 additions and 6 deletions

View File

@ -1,6 +1,8 @@
package aerospike package aerospike
import ( import (
"errors"
"log"
"net" "net"
"strconv" "strconv"
"strings" "strings"
@ -82,7 +84,12 @@ func (a *Aerospike) gatherServer(hostport string, acc telegraf.Accumulator) erro
return err return err
} }
for k, v := range stats { for k, v := range stats {
fields[strings.Replace(k, "-", "_", -1)] = parseValue(v) val, err := parseValue(v)
if err == nil {
fields[strings.Replace(k, "-", "_", -1)] = val
} else {
log.Printf("skipping aerospike field %v with int64 overflow", k)
}
} }
acc.AddFields("aerospike_node", fields, tags, time.Now()) acc.AddFields("aerospike_node", fields, tags, time.Now())
@ -110,7 +117,12 @@ func (a *Aerospike) gatherServer(hostport string, acc telegraf.Accumulator) erro
if len(parts) < 2 { if len(parts) < 2 {
continue continue
} }
nFields[strings.Replace(parts[0], "-", "_", -1)] = parseValue(parts[1]) val, err := parseValue(parts[1])
if err == nil {
nFields[strings.Replace(parts[0], "-", "_", -1)] = val
} else {
log.Printf("skipping aerospike field %v with int64 overflow", parts[0])
}
} }
acc.AddFields("aerospike_namespace", nFields, nTags, time.Now()) acc.AddFields("aerospike_namespace", nFields, nTags, time.Now())
} }
@ -118,13 +130,16 @@ func (a *Aerospike) gatherServer(hostport string, acc telegraf.Accumulator) erro
return nil return nil
} }
func parseValue(v string) interface{} { func parseValue(v string) (interface{}, error) {
if parsed, err := strconv.ParseInt(v, 10, 64); err == nil { if parsed, err := strconv.ParseInt(v, 10, 64); err == nil {
return parsed return parsed, nil
} else if _, err := strconv.ParseUint(v, 10, 64); err == nil {
// int64 overflow, yet valid uint64
return nil, errors.New("Number is too large")
} else if parsed, err := strconv.ParseBool(v); err == nil { } else if parsed, err := strconv.ParseBool(v); err == nil {
return parsed return parsed, nil
} else { } else {
return v return v, nil
} }
} }

View File

@ -48,3 +48,20 @@ func TestAerospikeStatisticsPartialErr(t *testing.T) {
assert.True(t, acc.HasMeasurement("aerospike_namespace")) assert.True(t, acc.HasMeasurement("aerospike_namespace"))
assert.True(t, acc.HasIntField("aerospike_node", "batch_error")) assert.True(t, acc.HasIntField("aerospike_node", "batch_error"))
} }
func TestAerospikeParseValue(t *testing.T) {
// uint64 with value bigger than int64 max
val, err := parseValue("18446744041841121751")
assert.Nil(t, val)
assert.Error(t, err)
// int values
val, err = parseValue("42")
assert.NoError(t, err)
assert.Equal(t, val, int64(42), "must be parsed as int")
// string values
val, err = parseValue("BB977942A2CA502")
assert.NoError(t, err)
assert.Equal(t, val, `BB977942A2CA502`, "must be left as string")
}