From 562804944074b39b2d02abf06ddb8428e5e0e78d Mon Sep 17 00:00:00 2001 From: Denis Orlikhin Date: Mon, 5 Sep 2016 16:29:14 +0300 Subject: [PATCH] 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 --- plugins/inputs/aerospike/aerospike.go | 27 +++++++++++++++++----- plugins/inputs/aerospike/aerospike_test.go | 17 ++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/plugins/inputs/aerospike/aerospike.go b/plugins/inputs/aerospike/aerospike.go index 477772774..f7c900195 100644 --- a/plugins/inputs/aerospike/aerospike.go +++ b/plugins/inputs/aerospike/aerospike.go @@ -1,6 +1,8 @@ package aerospike import ( + "errors" + "log" "net" "strconv" "strings" @@ -82,7 +84,12 @@ func (a *Aerospike) gatherServer(hostport string, acc telegraf.Accumulator) erro return err } 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()) @@ -110,7 +117,12 @@ func (a *Aerospike) gatherServer(hostport string, acc telegraf.Accumulator) erro if len(parts) < 2 { 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()) } @@ -118,13 +130,16 @@ func (a *Aerospike) gatherServer(hostport string, acc telegraf.Accumulator) erro return nil } -func parseValue(v string) interface{} { +func parseValue(v string) (interface{}, error) { 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 { - return parsed + return parsed, nil } else { - return v + return v, nil } } diff --git a/plugins/inputs/aerospike/aerospike_test.go b/plugins/inputs/aerospike/aerospike_test.go index 5f80b5196..b20af1657 100644 --- a/plugins/inputs/aerospike/aerospike_test.go +++ b/plugins/inputs/aerospike/aerospike_test.go @@ -48,3 +48,20 @@ func TestAerospikeStatisticsPartialErr(t *testing.T) { assert.True(t, acc.HasMeasurement("aerospike_namespace")) 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") +}