Skip to content

Commit 5dc4f9a

Browse files
danielnelsonrgitzel
authored andcommitted
Use operation subtables in enum and rename processors (influxdata#4672)
1 parent a9428f2 commit 5dc4f9a

File tree

6 files changed

+96
-104
lines changed

6 files changed

+96
-104
lines changed

plugins/processors/enum/README.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,29 @@ source field is overwritten.
1313

1414
```toml
1515
[[processors.enum]]
16-
[[processors.enum.fields]]
16+
[[processors.enum.mapping]]
1717
## Name of the field to map
18-
source = "name"
18+
field = "status"
1919

2020
## Destination field to be used for the mapped value. By default the source
2121
## field is used, overwriting the original value.
22-
# destination = "mapped"
22+
# dest = "status_code"
2323

2424
## Default value to be used for all values not contained in the mapping
2525
## table. When unset, the unmodified value for the field will be used if no
2626
## match is found.
2727
# default = 0
2828

2929
## Table of mappings
30-
[processors.enum.fields.value_mappings]
31-
value1 = 1
32-
value2 = 2
30+
[processors.enum.mapping.value_mappings]
31+
green = 1
32+
amber = 2
33+
red = 3
34+
```
35+
36+
### Example:
37+
38+
```diff
39+
- xyzzy status="green" 1502489900000000000
40+
+ xyzzy status="green",status_code=1i 1502489900000000000
3341
```

plugins/processors/enum/enum.go

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,33 @@ import (
88
)
99

1010
var sampleConfig = `
11-
[[processors.enum.fields]]
11+
[[processors.enum.mapping]]
1212
## Name of the field to map
13-
source = "name"
13+
field = "status"
1414
1515
## Destination field to be used for the mapped value. By default the source
1616
## field is used, overwriting the original value.
17-
# destination = "mapped"
17+
# dest = "status_code"
1818
1919
## Default value to be used for all values not contained in the mapping
2020
## table. When unset, the unmodified value for the field will be used if no
2121
## match is found.
2222
# default = 0
2323
2424
## Table of mappings
25-
[processors.enum.fields.value_mappings]
26-
value1 = 1
27-
value2 = 2
25+
[processors.enum.mapping.value_mappings]
26+
green = 1
27+
yellow = 2
28+
red = 3
2829
`
2930

3031
type EnumMapper struct {
31-
Fields []Mapping
32+
Mappings []Mapping `toml:"mapping"`
3233
}
3334

3435
type Mapping struct {
35-
Source string
36-
Destination string
36+
Field string
37+
Dest string
3738
Default interface{}
3839
ValueMappings map[string]interface{}
3940
}
@@ -54,8 +55,8 @@ func (mapper *EnumMapper) Apply(in ...telegraf.Metric) []telegraf.Metric {
5455
}
5556

5657
func (mapper *EnumMapper) applyMappings(metric telegraf.Metric) telegraf.Metric {
57-
for _, mapping := range mapper.Fields {
58-
if originalValue, isPresent := metric.GetField(mapping.Source); isPresent == true {
58+
for _, mapping := range mapper.Mappings {
59+
if originalValue, isPresent := metric.GetField(mapping.Field); isPresent == true {
5960
if adjustedValue, isString := adjustBoolValue(originalValue).(string); isString == true {
6061
if mappedValue, isMappedValuePresent := mapping.mapValue(adjustedValue); isMappedValuePresent == true {
6162
writeField(metric, mapping.getDestination(), mappedValue)
@@ -84,16 +85,14 @@ func (mapping *Mapping) mapValue(original string) (interface{}, bool) {
8485
}
8586

8687
func (mapping *Mapping) getDestination() string {
87-
if mapping.Destination != "" {
88-
return mapping.Destination
88+
if mapping.Dest != "" {
89+
return mapping.Dest
8990
}
90-
return mapping.Source
91+
return mapping.Field
9192
}
9293

9394
func writeField(metric telegraf.Metric, name string, value interface{}) {
94-
if metric.HasField(name) {
95-
metric.RemoveField(name)
96-
}
95+
metric.RemoveField(name)
9796
metric.AddField(name, value)
9897
}
9998

plugins/processors/enum/enum_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,55 +49,55 @@ func TestRetainsMetric(t *testing.T) {
4949
}
5050

5151
func TestMapsSingleStringValue(t *testing.T) {
52-
mapper := EnumMapper{Fields: []Mapping{{Source: "string_value", ValueMappings: map[string]interface{}{"test": int64(1)}}}}
52+
mapper := EnumMapper{Mappings: []Mapping{{Field: "string_value", ValueMappings: map[string]interface{}{"test": int64(1)}}}}
5353

5454
fields := calculateProcessedValues(mapper, createTestMetric())
5555

5656
assertFieldValue(t, 1, "string_value", fields)
5757
}
5858

5959
func TestNoFailureOnMappingsOnNonStringValuedFields(t *testing.T) {
60-
mapper := EnumMapper{Fields: []Mapping{{Source: "int_value", ValueMappings: map[string]interface{}{"13i": int64(7)}}}}
60+
mapper := EnumMapper{Mappings: []Mapping{{Field: "int_value", ValueMappings: map[string]interface{}{"13i": int64(7)}}}}
6161

6262
fields := calculateProcessedValues(mapper, createTestMetric())
6363

6464
assertFieldValue(t, 13, "int_value", fields)
6565
}
6666

6767
func TestMapSingleBoolValue(t *testing.T) {
68-
mapper := EnumMapper{Fields: []Mapping{{Source: "true_value", ValueMappings: map[string]interface{}{"true": int64(1)}}}}
68+
mapper := EnumMapper{Mappings: []Mapping{{Field: "true_value", ValueMappings: map[string]interface{}{"true": int64(1)}}}}
6969

7070
fields := calculateProcessedValues(mapper, createTestMetric())
7171

7272
assertFieldValue(t, 1, "true_value", fields)
7373
}
7474

7575
func TestMapsToDefaultValueOnUnknownSourceValue(t *testing.T) {
76-
mapper := EnumMapper{Fields: []Mapping{{Source: "string_value", Default: int64(42), ValueMappings: map[string]interface{}{"other": int64(1)}}}}
76+
mapper := EnumMapper{Mappings: []Mapping{{Field: "string_value", Default: int64(42), ValueMappings: map[string]interface{}{"other": int64(1)}}}}
7777

7878
fields := calculateProcessedValues(mapper, createTestMetric())
7979

8080
assertFieldValue(t, 42, "string_value", fields)
8181
}
8282

8383
func TestDoNotMapToDefaultValueKnownSourceValue(t *testing.T) {
84-
mapper := EnumMapper{Fields: []Mapping{{Source: "string_value", Default: int64(42), ValueMappings: map[string]interface{}{"test": int64(1)}}}}
84+
mapper := EnumMapper{Mappings: []Mapping{{Field: "string_value", Default: int64(42), ValueMappings: map[string]interface{}{"test": int64(1)}}}}
8585

8686
fields := calculateProcessedValues(mapper, createTestMetric())
8787

8888
assertFieldValue(t, 1, "string_value", fields)
8989
}
9090

9191
func TestNoMappingWithoutDefaultOrDefinedMappingValue(t *testing.T) {
92-
mapper := EnumMapper{Fields: []Mapping{{Source: "string_value", ValueMappings: map[string]interface{}{"other": int64(1)}}}}
92+
mapper := EnumMapper{Mappings: []Mapping{{Field: "string_value", ValueMappings: map[string]interface{}{"other": int64(1)}}}}
9393

9494
fields := calculateProcessedValues(mapper, createTestMetric())
9595

9696
assertFieldValue(t, "test", "string_value", fields)
9797
}
9898

9999
func TestWritesToDestination(t *testing.T) {
100-
mapper := EnumMapper{Fields: []Mapping{{Source: "string_value", Destination: "string_code", ValueMappings: map[string]interface{}{"test": int64(1)}}}}
100+
mapper := EnumMapper{Mappings: []Mapping{{Field: "string_value", Dest: "string_code", ValueMappings: map[string]interface{}{"test": int64(1)}}}}
101101

102102
fields := calculateProcessedValues(mapper, createTestMetric())
103103

plugins/processors/rename/README.md

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,23 @@ The `rename` processor renames measurements, fields, and tags.
55
### Configuration:
66

77
```toml
8-
## Measurement, tag, and field renamings are stored in separate sub-tables.
9-
## Specify one sub-table per rename operation.
108
[[processors.rename]]
11-
[[processors.rename.measurement]]
12-
## measurement to change
13-
from = "network_interface_throughput"
14-
to = "throughput"
15-
16-
[[processors.rename.tag]]
17-
## tag to change
18-
from = "hostname"
19-
to = "host"
20-
21-
[[processors.rename.field]]
22-
## field to change
23-
from = "lower"
24-
to = "min"
25-
26-
[[processors.rename.field]]
27-
## field to change
28-
from = "upper"
29-
to = "max"
9+
## Specify one sub-table per rename operation.
10+
[[processors.rename.replace]]
11+
measurement = "network_interface_throughput"
12+
dest = "throughput"
13+
14+
[[processors.rename.replace]]
15+
tag = "hostname"
16+
dest = "host"
17+
18+
[[processors.rename.replace]]
19+
field = "lower"
20+
dest = "min"
21+
22+
[[processors.rename.replace]]
23+
field = "upper"
24+
dest = "max"
3025
```
3126

3227
### Tags:
@@ -36,6 +31,6 @@ No tags are applied by this processor, though it can alter them by renaming.
3631
### Example processing:
3732

3833
```diff
39-
- network_interface_throughput,hostname=backend.example.com,units=kbps lower=10i,upper=1000i,mean=500i 1502489900000000000
40-
+ throughput,host=backend.example.com,units=kbps min=10i,max=1000i,mean=500i 1502489900000000000
34+
- network_interface_throughput,hostname=backend.example.com lower=10i,upper=1000i,mean=500i 1502489900000000000
35+
+ throughput,host=backend.example.com min=10i,max=1000i,mean=500i 1502489900000000000
4136
```

plugins/processors/rename/rename.go

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,17 @@ import (
66
)
77

88
const sampleConfig = `
9-
## Measurement, tag, and field renamings are stored in separate sub-tables.
10-
## Specify one sub-table per rename operation.
11-
# [[processors.rename.measurement]]
12-
# ## measurement to change
13-
# from = "kilobytes_per_second"
14-
# to = "kbps"
15-
16-
# [[processors.rename.tag]]
17-
# ## tag to change
18-
# from = "host"
19-
# to = "hostname"
20-
21-
# [[processors.rename.field]]
22-
# ## field to change
23-
# from = "lower"
24-
# to = "min"
25-
26-
# [[processors.rename.field]]
27-
# ## field to change
28-
# from = "upper"
29-
# to = "max"
309
`
3110

32-
type renamer struct {
33-
From string
34-
To string
11+
type Replace struct {
12+
Measurement string `toml:"measurement"`
13+
Tag string `toml:"tag"`
14+
Field string `toml:"field"`
15+
Dest string `toml:"dest"`
3516
}
3617

3718
type Rename struct {
38-
Measurement []renamer
39-
Tag []renamer
40-
Field []renamer
19+
Replaces []Replace `toml:"replace"`
4120
}
4221

4322
func (r *Rename) SampleConfig() string {
@@ -50,24 +29,32 @@ func (r *Rename) Description() string {
5029

5130
func (r *Rename) Apply(in ...telegraf.Metric) []telegraf.Metric {
5231
for _, point := range in {
53-
for _, measurementRenamer := range r.Measurement {
54-
if point.Name() == measurementRenamer.From {
55-
point.SetName(measurementRenamer.To)
56-
break
32+
for _, replace := range r.Replaces {
33+
if replace.Dest == "" {
34+
continue
5735
}
58-
}
5936

60-
for _, tagRenamer := range r.Tag {
61-
if value, ok := point.GetTag(tagRenamer.From); ok {
62-
point.RemoveTag(tagRenamer.From)
63-
point.AddTag(tagRenamer.To, value)
37+
if replace.Measurement != "" {
38+
if value := point.Name(); value == replace.Measurement {
39+
point.SetName(replace.Dest)
40+
}
41+
continue
42+
}
43+
44+
if replace.Tag != "" {
45+
if value, ok := point.GetTag(replace.Tag); ok {
46+
point.RemoveTag(replace.Tag)
47+
point.AddTag(replace.Dest, value)
48+
}
49+
continue
6450
}
65-
}
6651

67-
for _, fieldRenamer := range r.Field {
68-
if value, ok := point.GetField(fieldRenamer.From); ok {
69-
point.RemoveField(fieldRenamer.From)
70-
point.AddField(fieldRenamer.To, value)
52+
if replace.Field != "" {
53+
if value, ok := point.GetField(replace.Field); ok {
54+
point.RemoveField(replace.Field)
55+
point.AddField(replace.Dest, value)
56+
}
57+
continue
7158
}
7259
}
7360
}

plugins/processors/rename/rename_test.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ func newMetric(name string, tags map[string]string, fields map[string]interface{
2121
}
2222

2323
func TestMeasurementRename(t *testing.T) {
24-
r := Rename{}
25-
r.Measurement = []renamer{
26-
{From: "foo", To: "bar"},
27-
{From: "baz", To: "quux"},
24+
r := Rename{
25+
Replaces: []Replace{
26+
{Measurement: "foo", Dest: "bar"},
27+
{Measurement: "baz", Dest: "quux"},
28+
},
2829
}
2930
m1 := newMetric("foo", nil, nil)
3031
m2 := newMetric("bar", nil, nil)
@@ -36,9 +37,10 @@ func TestMeasurementRename(t *testing.T) {
3637
}
3738

3839
func TestTagRename(t *testing.T) {
39-
r := Rename{}
40-
r.Tag = []renamer{
41-
{From: "hostname", To: "host"},
40+
r := Rename{
41+
Replaces: []Replace{
42+
{Tag: "hostname", Dest: "host"},
43+
},
4244
}
4345
m := newMetric("foo", map[string]string{"hostname": "localhost", "region": "east-1"}, nil)
4446
results := r.Apply(m)
@@ -47,9 +49,10 @@ func TestTagRename(t *testing.T) {
4749
}
4850

4951
func TestFieldRename(t *testing.T) {
50-
r := Rename{}
51-
r.Field = []renamer{
52-
{From: "time_msec", To: "time"},
52+
r := Rename{
53+
Replaces: []Replace{
54+
{Field: "time_msec", Dest: "time"},
55+
},
5356
}
5457
m := newMetric("foo", nil, map[string]interface{}{"time_msec": int64(1250), "snakes": true})
5558
results := r.Apply(m)

0 commit comments

Comments
 (0)