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

fix(parsers.json_v2): Properly handle optional fields #14008

Merged
merged 7 commits into from
Oct 2, 2023
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
30 changes: 13 additions & 17 deletions plugins/parsers/json_v2/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ func (p *Parser) processMetric(input []byte, data []DataSet, tag bool, timestamp
return nil, fmt.Errorf("GJSON path is required")
}
result := gjson.GetBytes(input, c.Path)
if skip, err := p.checkResult(result, c.Path, c.Optional); err != nil {
if skip {
if err := p.checkResult(result, c.Path); err != nil {
if c.Optional {
continue
}
return nil, err
Expand Down Expand Up @@ -456,8 +456,8 @@ func (p *Parser) processObjects(input []byte, objects []Object, timestamp time.T
}

result := gjson.GetBytes(input, c.Path)
if skip, err := p.checkResult(result, c.Path, c.Optional); err != nil {
if skip {
if err := p.checkResult(result, c.Path); err != nil {
if c.Optional {
continue
}
return nil, err
Expand All @@ -467,8 +467,8 @@ func (p *Parser) processObjects(input []byte, objects []Object, timestamp time.T
for _, f := range c.FieldPaths {
var r PathResult
r.result = gjson.GetBytes(scopedJSON, f.Path)
if skip, err := p.checkResult(r.result, f.Path, f.Optional); err != nil {
if skip {
if err := p.checkResult(r.result, f.Path); err != nil {
if f.Optional {
continue
}
return nil, err
Expand All @@ -480,8 +480,8 @@ func (p *Parser) processObjects(input []byte, objects []Object, timestamp time.T
for _, f := range c.TagPaths {
var r PathResult
r.result = gjson.GetBytes(scopedJSON, f.Path)
if skip, err := p.checkResult(r.result, f.Path, f.Optional); err != nil {
if skip {
if err := p.checkResult(r.result, f.Path); err != nil {
if f.Optional {
continue
}
return nil, err
Expand Down Expand Up @@ -700,18 +700,14 @@ func (p *Parser) convertType(input gjson.Result, desiredType string, name string
return input.Value(), nil
}

func (p *Parser) checkResult(result gjson.Result, path string, optional bool) (bool, error) {
// Check if gjson result exists and return error if it does not
func (p *Parser) checkResult(result gjson.Result, path string) error {
if !result.Exists() {
if optional {
// If path is marked as optional don't error if path doesn't return a result
p.Log.Debugf("the path %q doesn't exist", path)
return true, nil
}

return false, fmt.Errorf("the path %q doesn't exist", path)
p.Log.Debugf("the path %q doesn't exist", path)
return fmt.Errorf("the path %q doesn't exist", path)
}

return false, nil
return nil
}

func init() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
file,datatype=float,name=inlet-1/temperature value_f=0.20791169081775931 1695679023000000000
file,datatype=float value_f=-0.3090169943749477,name="inlet-1/temperature" 1695679077000000000
file,datatype=string value_s="-0.3090169943749477",name="inlet-3/flow" 1695679077000000000
file,datatype=int value_i=95i,name="inlet-2/temperature" 1695679077000000000
file,datatype=bool value_b=true,name="inlet-2/flow" 1695679077000000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"timestamp": 1695679077118.0,
"metrics": [
{
"value": -0.3090169943749477,
"name": "inlet-1/temperature",
"datatype": "float"
},
{
"value": 95,
"name": "inlet-2/temperature",
"datatype": "int"
},
{
"value": true,
"name": "inlet-2/flow",
"datatype": "bool"
},
{
"value": "-0.3090169943749477",
"name": "inlet-3/flow",
"datatype": "string"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"timestamp": 1695679022882.0,
"value": 0.20791169081775931,
"name": "inlet-1/temperature",
"datatype": "float"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Example taken from: https://github.com/influxdata/telegraf/issues/13990

# Parse String types from JSON
[[inputs.file]]

files = ["./testdata/nested_objects_optional/nested_objects_single.json", "./testdata/nested_objects_optional/nested_objects_nest.json"]
data_format = "json_v2"

[[inputs.file.json_v2]]
timestamp_path = 'timestamp'
timestamp_format = 'unix_ms'

[[inputs.file.json_v2.tag]]
path = 'name'
optional = true
[[inputs.file.json_v2.tag]]
path = 'datatype'
optional = true
[[inputs.file.json_v2.field]]
path = 'value'
rename = 'value_f'
optional = true

[[inputs.file.json_v2.object]]
path = 'metrics.#(datatype=="float")#'
optional = true
tags = ['datatype']
[inputs.file.json_v2.object.renames]
value = 'value_f'
[inputs.file.json_v2.object.fields]
value = 'float'

[[inputs.file.json_v2.object]]
path = 'metrics.#(datatype=="string")#'
optional = true
tags = ['datatype']
[inputs.file.json_v2.object.renames]
value = 'value_s'
[inputs.file.json_v2.object.fields]
value = 'string'

[[inputs.file.json_v2.object]]
path = 'metrics.#(datatype=="int")#'
optional = true
tags = ['datatype']
[inputs.file.json_v2.object.renames]
value = 'value_i'
[inputs.file.json_v2.object.fields]
value = 'int'

[[inputs.file.json_v2.object]]
path = 'metrics.#(datatype=="bool")#'
optional = true
tags = ['datatype']
[inputs.file.json_v2.object.renames]
value = 'value_b'
[inputs.file.json_v2.object.fields]
value = 'bool'