Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wildcard tags json parser support #8579

Merged
merged 10 commits into from
Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions plugins/parsers/json/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ ignored unless specified in the `tag_key` or `json_string_fields` options.
json_query = ""

## Tag keys is an array of keys that should be added as tags. Matching keys
## are no longer saved as fields.
## are no longer saved as fields. Supports wildcard glob matching.
tag_keys = [
"my_tag_1",
"my_tag_2"
"my_tag_2",
"tags_*",
"tag*"
]

## Array of glob pattern strings keys that should be added as string fields.
Expand Down
44 changes: 27 additions & 17 deletions plugins/parsers/json/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type Config struct {

type Parser struct {
metricName string
tagKeys []string
tagKeys filter.Filter
stringFields filter.Filter
nameKey string
query string
Expand All @@ -53,9 +53,14 @@ func New(config *Config) (*Parser, error) {
return nil, err
}

tagKeyFilter, err := filter.Compile(config.TagKeys)
if err != nil {
return nil, err
}

return &Parser{
metricName: config.MetricName,
tagKeys: config.TagKeys,
tagKeys: tagKeyFilter,
nameKey: config.NameKey,
stringFields: stringFilter,
query: config.Query,
Expand Down Expand Up @@ -104,15 +109,15 @@ func (p *Parser) parseObject(data map[string]interface{}, timestamp time.Time) (

name := p.metricName

//checks if json_name_key is set
// checks if json_name_key is set
if p.nameKey != "" {
switch field := f.Fields[p.nameKey].(type) {
case string:
name = field
}
}

//if time key is specified, set timestamp to it
// if time key is specified, set timestamp to it
if p.timeKey != "" {
if p.timeFormat == "" {
err := fmt.Errorf("use of 'json_time_key' requires 'json_time_format'")
Expand All @@ -131,7 +136,7 @@ func (p *Parser) parseObject(data map[string]interface{}, timestamp time.Time) (

delete(f.Fields, p.timeKey)

//if the year is 0, set to current year
// if the year is 0, set to current year
if timestamp.Year() == 0 {
timestamp = timestamp.AddDate(time.Now().Year(), 0, 0)
}
Expand All @@ -145,32 +150,37 @@ func (p *Parser) parseObject(data map[string]interface{}, timestamp time.Time) (
return []telegraf.Metric{metric}, nil
}

//will take in field map with strings and bools,
//search for TagKeys that match fieldnames and add them to tags
//will delete any strings/bools that shouldn't be fields
//assumes that any non-numeric values in TagKeys should be displayed as tags
// will take in field map with strings and bools,
// search for TagKeys that match fieldnames and add them to tags
// will delete any strings/bools that shouldn't be fields
// assumes that any non-numeric values in TagKeys should be displayed as tags
func (p *Parser) switchFieldToTag(tags map[string]string, fields map[string]interface{}) (map[string]string, map[string]interface{}) {
for _, name := range p.tagKeys {
//switch any fields in tagkeys into tags
if fields[name] == nil {

for name, value := range fields {
if p.tagKeys == nil {
continue
}
// skip switch statement if tagkey doesn't match fieldname
if !p.tagKeys.Match(name) {
continue
}
switch value := fields[name].(type) {
// switch any fields in tagkeys into tags
switch t := value.(type) {
case string:
tags[name] = value
tags[name] = t
delete(fields, name)
case bool:
tags[name] = strconv.FormatBool(value)
tags[name] = strconv.FormatBool(t)
delete(fields, name)
case float64:
tags[name] = strconv.FormatFloat(value, 'f', -1, 64)
tags[name] = strconv.FormatFloat(t, 'f', -1, 64)
delete(fields, name)
default:
log.Printf("E! [parsers.json] Unrecognized type %T", value)
}
}

//remove any additional string/bool values from fields
// remove any additional string/bool values from fields
for fk := range fields {
switch fields[fk].(type) {
case string, bool:
Expand Down
Loading