Skip to content

Commit 9f8bdb4

Browse files
committed
Fix bool serialization when using carbon2
1 parent 998611f commit 9f8bdb4

File tree

2 files changed

+84
-5
lines changed

2 files changed

+84
-5
lines changed

plugins/serializers/carbon2/carbon2.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func (s *Serializer) createObject(metric telegraf.Metric) []byte {
5757
metricsFormat := s.getMetricsFormat()
5858

5959
for fieldName, fieldValue := range metric.Fields() {
60-
if !isNumeric(fieldValue) {
60+
if isString(fieldValue) {
6161
continue
6262
}
6363

@@ -86,7 +86,7 @@ func (s *Serializer) createObject(metric telegraf.Metric) []byte {
8686
m.WriteString(" ")
8787
}
8888
m.WriteString(" ")
89-
m.WriteString(fmt.Sprintf("%v", fieldValue))
89+
m.WriteString(formatValue(fieldValue))
9090
m.WriteString(" ")
9191
m.WriteString(strconv.FormatInt(metric.Time().Unix(), 10))
9292
m.WriteString("\n")
@@ -126,11 +126,33 @@ func serializeMetricIncludeField(name, fieldName string) string {
126126
)
127127
}
128128

129-
func isNumeric(v interface{}) bool {
129+
func formatValue(fieldValue interface{}) string {
130+
switch v := fieldValue.(type) {
131+
case bool:
132+
// Print bools as 0s and 1s
133+
return fmt.Sprintf("%d", bool2int(v))
134+
default:
135+
return fmt.Sprintf("%v", v)
136+
}
137+
}
138+
139+
func isString(v interface{}) bool {
130140
switch v.(type) {
131141
case string:
132-
return false
133-
default:
134142
return true
143+
default:
144+
return false
145+
}
146+
}
147+
148+
func bool2int(b bool) int {
149+
// Slightly more optimized than a usual if ... return ... else return ... .
150+
// See: https://0x0f.me/blog/golang-compiler-optimization/
151+
var i int
152+
if b {
153+
i = 1
154+
} else {
155+
i = 0
135156
}
157+
return i
136158
}

plugins/serializers/carbon2/carbon2_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,63 @@ func TestSerializeMetricString(t *testing.T) {
209209
}
210210
}
211211

212+
func TestSerializeMetricBool(t *testing.T) {
213+
requireMetric := func(t *testing.T, tim time.Time, value bool) telegraf.Metric {
214+
tags := map[string]string{
215+
"tag_name": "tag_value",
216+
}
217+
fields := map[string]interface{}{
218+
"java_lang_GarbageCollector_Valid": value,
219+
}
220+
221+
m, err := metric.New("cpu", tags, fields, tim)
222+
require.NoError(t, err)
223+
224+
return m
225+
}
226+
227+
now := time.Now()
228+
229+
testcases := []struct {
230+
metric telegraf.Metric
231+
format string
232+
expected string
233+
}{
234+
{
235+
metric: requireMetric(t, now, false),
236+
format: Carbon2FormatFieldSeparate,
237+
expected: fmt.Sprintf("metric=cpu field=java_lang_GarbageCollector_Valid tag_name=tag_value 0 %d\n", now.Unix()),
238+
},
239+
{
240+
metric: requireMetric(t, now, false),
241+
format: Carbon2FormatMetricIncludesField,
242+
expected: fmt.Sprintf("metric=cpu_java_lang_GarbageCollector_Valid tag_name=tag_value 0 %d\n", now.Unix()),
243+
},
244+
{
245+
metric: requireMetric(t, now, true),
246+
format: Carbon2FormatFieldSeparate,
247+
expected: fmt.Sprintf("metric=cpu field=java_lang_GarbageCollector_Valid tag_name=tag_value 1 %d\n", now.Unix()),
248+
},
249+
{
250+
metric: requireMetric(t, now, true),
251+
format: Carbon2FormatMetricIncludesField,
252+
expected: fmt.Sprintf("metric=cpu_java_lang_GarbageCollector_Valid tag_name=tag_value 1 %d\n", now.Unix()),
253+
},
254+
}
255+
256+
for _, tc := range testcases {
257+
t.Run(tc.format, func(t *testing.T) {
258+
s, err := NewSerializer(tc.format)
259+
require.NoError(t, err)
260+
261+
buf, err := s.Serialize(tc.metric)
262+
require.NoError(t, err)
263+
264+
assert.Equal(t, tc.expected, string(buf))
265+
})
266+
}
267+
}
268+
212269
func TestSerializeBatch(t *testing.T) {
213270
m := MustMetric(
214271
metric.New(

0 commit comments

Comments
 (0)