Skip to content

Commit

Permalink
fix: mqtt topic extracting no longer requires all three fields (influ…
Browse files Browse the repository at this point in the history
  • Loading branch information
MyaLongmire authored Dec 2, 2021
1 parent b954e56 commit d15cf79
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 13 deletions.
16 changes: 3 additions & 13 deletions plugins/inputs/mqtt_consumer/mqtt_consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@ var sampleConfig = `
"telegraf/+/mem",
"sensors/#",
]
## Enable extracting tag values from MQTT topics
## _ denotes an ignored entry in the topic path
# topic_tags = "_/format/client/_"
# topic_measurement = "measurement/_/_/_"
# topic_fields = "_/_/_/temperature"
## The message topic will be stored in a tag specified by this value. If set
## to the empty string no topic tag will be created.
Expand Down Expand Up @@ -199,15 +195,15 @@ func (m *MQTTConsumer) Init() error {
m.TopicParsing[i].SplitFields = strings.Split(p.Fields, "/")
m.TopicParsing[i].SplitTopic = strings.Split(p.Topic, "/")

if len(splitMeasurement) != len(m.TopicParsing[i].SplitTopic) {
if len(splitMeasurement) != len(m.TopicParsing[i].SplitTopic) && len(splitMeasurement) != 1 {
return fmt.Errorf("config error topic parsing: measurement length does not equal topic length")
}

if len(m.TopicParsing[i].SplitFields) != len(m.TopicParsing[i].SplitTopic) {
if len(m.TopicParsing[i].SplitFields) != len(m.TopicParsing[i].SplitTopic) && p.Fields != "" {
return fmt.Errorf("config error topic parsing: fields length does not equal topic length")
}

if len(m.TopicParsing[i].SplitTags) != len(m.TopicParsing[i].SplitTopic) {
if len(m.TopicParsing[i].SplitTags) != len(m.TopicParsing[i].SplitTopic) && p.Tags != "" {
return fmt.Errorf("config error topic parsing: tags length does not equal topic length")
}
}
Expand Down Expand Up @@ -408,27 +404,21 @@ func (m *MQTTConsumer) createOpts() (*mqtt.ClientOptions, error) {

// parseFields gets multiple fields from the topic based on the user configuration (TopicParsing.Fields)
func parseMetric(keys []string, values []string, types map[string]string, isTag bool, metric telegraf.Metric) error {
var metricFound bool
for i, k := range keys {
if k == "_" {
continue
}

if isTag {
metric.AddTag(k, values[i])
metricFound = true
} else {
newType, err := typeConvert(types, values[i], k)
if err != nil {
return err
}
metric.AddField(k, newType)
metricFound = true
}
}
if !metricFound {
return fmt.Errorf("no fields or tags found")
}
return nil
}

Expand Down
62 changes: 62 additions & 0 deletions plugins/inputs/mqtt_consumer/mqtt_consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,68 @@ func TestTopicTag(t *testing.T) {
),
},
},
{
name: "topic parsing configured without fields",
topic: "telegraf/123/test/hello",
topicTag: func() *string {
tag := ""
return &tag
},
topicParsing: []TopicParsingConfig{
{
Topic: "telegraf/+/test/hello",
Measurement: "_/_/measurement/_",
Tags: "testTag/_/_/_",
FieldTypes: map[string]string{
"testNumber": "int",
},
},
},
expected: []telegraf.Metric{
testutil.MustMetric(
"test",
map[string]string{
"testTag": "telegraf",
},
map[string]interface{}{
"time_idle": 42,
},
time.Unix(0, 0),
),
},
},
{
name: "topic parsing configured without measurement",
topic: "telegraf/123/test/hello",
topicTag: func() *string {
tag := ""
return &tag
},
topicParsing: []TopicParsingConfig{
{
Topic: "telegraf/+/test/hello",
Tags: "testTag/_/_/_",
Fields: "_/testNumber/_/testString",
FieldTypes: map[string]string{
"testNumber": "int",
},
},
},
expected: []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{
"testTag": "telegraf",
},
map[string]interface{}{
"testNumber": 123,
"testString": "hello",
"time_idle": 42,
},
time.Unix(0, 0),
),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit d15cf79

Please sign in to comment.