Add integer support to enum processor (#7483)
This commit is contained in:
parent
134c84f45d
commit
568cb8e64c
|
@ -2,7 +2,7 @@
|
|||
|
||||
The Enum Processor allows the configuration of value mappings for metric tags or fields.
|
||||
The main use-case for this is to rewrite status codes such as _red_, _amber_ and
|
||||
_green_ by numeric values such as 0, 1, 2. The plugin supports string and bool
|
||||
_green_ by numeric values such as 0, 1, 2. The plugin supports string, int and bool
|
||||
types for the field values. Multiple tags or fields can be configured with separate
|
||||
value mappings for each. Default mapping values can be configured to be
|
||||
used for all values, which are not contained in the value_mappings. The
|
||||
|
|
|
@ -63,7 +63,7 @@ func (mapper *EnumMapper) applyMappings(metric telegraf.Metric) telegraf.Metric
|
|||
for _, mapping := range mapper.Mappings {
|
||||
if mapping.Field != "" {
|
||||
if originalValue, isPresent := metric.GetField(mapping.Field); isPresent {
|
||||
if adjustedValue, isString := adjustBoolValue(originalValue).(string); isString {
|
||||
if adjustedValue, isString := adjustValue(originalValue).(string); isString {
|
||||
if mappedValue, isMappedValuePresent := mapping.mapValue(adjustedValue); isMappedValuePresent {
|
||||
writeField(metric, mapping.getDestination(), mappedValue)
|
||||
}
|
||||
|
@ -86,11 +86,17 @@ func (mapper *EnumMapper) applyMappings(metric telegraf.Metric) telegraf.Metric
|
|||
return metric
|
||||
}
|
||||
|
||||
func adjustBoolValue(in interface{}) interface{} {
|
||||
if mappedBool, isBool := in.(bool); isBool == true {
|
||||
return strconv.FormatBool(mappedBool)
|
||||
func adjustValue(in interface{}) interface{} {
|
||||
switch val := in.(type) {
|
||||
case bool:
|
||||
return strconv.FormatBool(val)
|
||||
case int64:
|
||||
return strconv.FormatInt(val, 10)
|
||||
case uint64:
|
||||
return strconv.FormatUint(val, 10)
|
||||
default:
|
||||
return in
|
||||
}
|
||||
return in
|
||||
}
|
||||
|
||||
func (mapping *Mapping) mapValue(original string) (interface{}, bool) {
|
||||
|
|
|
@ -14,7 +14,9 @@ func createTestMetric() telegraf.Metric {
|
|||
map[string]string{"tag": "tag_value"},
|
||||
map[string]interface{}{
|
||||
"string_value": "test",
|
||||
"int_value": int(13),
|
||||
"int_value": int(200),
|
||||
"uint_value": uint(500),
|
||||
"float_value": float64(3.14),
|
||||
"true_value": true,
|
||||
},
|
||||
time.Now(),
|
||||
|
@ -52,21 +54,14 @@ func TestRetainsMetric(t *testing.T) {
|
|||
fields := target.Fields()
|
||||
|
||||
assertFieldValue(t, "test", "string_value", fields)
|
||||
assertFieldValue(t, 13, "int_value", fields)
|
||||
assertFieldValue(t, 200, "int_value", fields)
|
||||
assertFieldValue(t, 500, "uint_value", fields)
|
||||
assertFieldValue(t, true, "true_value", fields)
|
||||
assert.Equal(t, "m1", target.Name())
|
||||
assert.Equal(t, source.Tags(), target.Tags())
|
||||
assert.Equal(t, source.Time(), target.Time())
|
||||
}
|
||||
|
||||
func TestMapsSingleStringValue(t *testing.T) {
|
||||
mapper := EnumMapper{Mappings: []Mapping{{Field: "string_value", ValueMappings: map[string]interface{}{"test": int64(1)}}}}
|
||||
|
||||
fields := calculateProcessedValues(mapper, createTestMetric())
|
||||
|
||||
assertFieldValue(t, 1, "string_value", fields)
|
||||
}
|
||||
|
||||
func TestMapsSingleStringValueTag(t *testing.T) {
|
||||
mapper := EnumMapper{Mappings: []Mapping{{Tag: "tag", ValueMappings: map[string]interface{}{"tag_value": "valuable"}}}}
|
||||
|
||||
|
@ -75,20 +70,50 @@ func TestMapsSingleStringValueTag(t *testing.T) {
|
|||
assertTagValue(t, "valuable", "tag", tags)
|
||||
}
|
||||
|
||||
func TestNoFailureOnMappingsOnNonStringValuedFields(t *testing.T) {
|
||||
mapper := EnumMapper{Mappings: []Mapping{{Field: "int_value", ValueMappings: map[string]interface{}{"13i": int64(7)}}}}
|
||||
func TestNoFailureOnMappingsOnNonSupportedValuedFields(t *testing.T) {
|
||||
mapper := EnumMapper{Mappings: []Mapping{{Field: "float_value", ValueMappings: map[string]interface{}{"3.14": "pi"}}}}
|
||||
|
||||
fields := calculateProcessedValues(mapper, createTestMetric())
|
||||
|
||||
assertFieldValue(t, 13, "int_value", fields)
|
||||
assertFieldValue(t, float64(3.14), "float_value", fields)
|
||||
}
|
||||
|
||||
func TestMapSingleBoolValue(t *testing.T) {
|
||||
mapper := EnumMapper{Mappings: []Mapping{{Field: "true_value", ValueMappings: map[string]interface{}{"true": int64(1)}}}}
|
||||
func TestMappings(t *testing.T) {
|
||||
mappings := []map[string][]interface{}{
|
||||
{
|
||||
"field_name": []interface{}{"string_value"},
|
||||
"target_values": []interface{}{"test", "test", "test", "not_test", "50", "true"},
|
||||
"mapped_values": []interface{}{"test_1", 5, true, "test_1", 10, false},
|
||||
"expected_values": []interface{}{"test_1", 5, true, "test", "test", "test"},
|
||||
},
|
||||
{
|
||||
"field_name": []interface{}{"true_value"},
|
||||
"target_value": []interface{}{"true", "true", "true", "false", "test", "5"},
|
||||
"mapped_value": []interface{}{false, 1, "false", false, false, false},
|
||||
"expected_value": []interface{}{false, 1, "false", true, true, true},
|
||||
},
|
||||
{
|
||||
"field_name": []interface{}{"int_value"},
|
||||
"target_value": []interface{}{"200", "200", "200", "200", "test", "5"},
|
||||
"mapped_value": []interface{}{"http_ok", true, 1, float64(200.001), false, false},
|
||||
"expected_value": []interface{}{"http_ok", true, 1, float64(200.001), 200, 200},
|
||||
},
|
||||
{
|
||||
"field_name": []interface{}{"uint_value"},
|
||||
"target_value": []interface{}{"500", "500", "500", "test", "false", "5"},
|
||||
"mapped_value": []interface{}{"internal_error", 1, false, false, false, false},
|
||||
"expected_value": []interface{}{"internal_error", 1, false, 500, 500, 500},
|
||||
},
|
||||
}
|
||||
|
||||
fields := calculateProcessedValues(mapper, createTestMetric())
|
||||
|
||||
assertFieldValue(t, 1, "true_value", fields)
|
||||
for _, mapping := range mappings {
|
||||
field_name := mapping["field_name"][0].(string)
|
||||
for index := range mapping["target_value"] {
|
||||
mapper := EnumMapper{Mappings: []Mapping{{Field: field_name, ValueMappings: map[string]interface{}{mapping["target_value"][index].(string): mapping["mapped_value"][index]}}}}
|
||||
fields := calculateProcessedValues(mapper, createTestMetric())
|
||||
assertFieldValue(t, mapping["expected_value"][index], field_name, fields)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapsToDefaultValueOnUnknownSourceValue(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue