Fix bool serialization when using carbon2 (#8162)

This commit is contained in:
Patryk Małek 2020-10-07 21:54:45 +02:00 committed by GitHub
parent 2180bbfed5
commit a976e6ff95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 7 deletions

View File

@ -61,7 +61,7 @@ func (s *Serializer) createObject(metric telegraf.Metric) []byte {
metricsFormat := s.getMetricsFormat()
for fieldName, fieldValue := range metric.Fields() {
if !isNumeric(fieldValue) {
if isString(fieldValue) {
continue
}
@ -88,7 +88,7 @@ func (s *Serializer) createObject(metric telegraf.Metric) []byte {
m.WriteString(" ")
}
m.WriteString(" ")
m.WriteString(fmt.Sprintf("%v", fieldValue))
m.WriteString(formatValue(fieldValue))
m.WriteString(" ")
m.WriteString(strconv.FormatInt(metric.Time().Unix(), 10))
m.WriteString("\n")
@ -122,11 +122,33 @@ func serializeMetricIncludeField(name, fieldName string) string {
)
}
func isNumeric(v interface{}) bool {
switch v.(type) {
case string:
return false
func formatValue(fieldValue interface{}) string {
switch v := fieldValue.(type) {
case bool:
// Print bools as 0s and 1s
return fmt.Sprintf("%d", bool2int(v))
default:
return true
return fmt.Sprintf("%v", v)
}
}
func isString(v interface{}) bool {
switch v.(type) {
case string:
return true
default:
return false
}
}
func bool2int(b bool) int {
// Slightly more optimized than a usual if ... return ... else return ... .
// See: https://0x0f.me/blog/golang-compiler-optimization/
var i int
if b {
i = 1
} else {
i = 0
}
return i
}

View File

@ -209,6 +209,63 @@ func TestSerializeMetricString(t *testing.T) {
}
}
func TestSerializeMetricBool(t *testing.T) {
requireMetric := func(t *testing.T, tim time.Time, value bool) telegraf.Metric {
tags := map[string]string{
"tag_name": "tag_value",
}
fields := map[string]interface{}{
"java_lang_GarbageCollector_Valid": value,
}
m, err := metric.New("cpu", tags, fields, tim)
require.NoError(t, err)
return m
}
now := time.Now()
testcases := []struct {
metric telegraf.Metric
format string
expected string
}{
{
metric: requireMetric(t, now, false),
format: Carbon2FormatFieldSeparate,
expected: fmt.Sprintf("metric=cpu field=java_lang_GarbageCollector_Valid tag_name=tag_value 0 %d\n", now.Unix()),
},
{
metric: requireMetric(t, now, false),
format: Carbon2FormatMetricIncludesField,
expected: fmt.Sprintf("metric=cpu_java_lang_GarbageCollector_Valid tag_name=tag_value 0 %d\n", now.Unix()),
},
{
metric: requireMetric(t, now, true),
format: Carbon2FormatFieldSeparate,
expected: fmt.Sprintf("metric=cpu field=java_lang_GarbageCollector_Valid tag_name=tag_value 1 %d\n", now.Unix()),
},
{
metric: requireMetric(t, now, true),
format: Carbon2FormatMetricIncludesField,
expected: fmt.Sprintf("metric=cpu_java_lang_GarbageCollector_Valid tag_name=tag_value 1 %d\n", now.Unix()),
},
}
for _, tc := range testcases {
t.Run(tc.format, func(t *testing.T) {
s, err := NewSerializer(tc.format)
require.NoError(t, err)
buf, err := s.Serialize(tc.metric)
require.NoError(t, err)
assert.Equal(t, tc.expected, string(buf))
})
}
}
func TestSerializeBatch(t *testing.T) {
m := MustMetric(
metric.New(