diff --git a/plugins/parsers/json_v2/parser.go b/plugins/parsers/json_v2/parser.go index de977fafc..c195cf103 100644 --- a/plugins/parsers/json_v2/parser.go +++ b/plugins/parsers/json_v2/parser.go @@ -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 @@ -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 @@ -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 @@ -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 @@ -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() { diff --git a/plugins/parsers/json_v2/testdata/nested_objects_optional/expected.out b/plugins/parsers/json_v2/testdata/nested_objects_optional/expected.out new file mode 100644 index 000000000..65b35d138 --- /dev/null +++ b/plugins/parsers/json_v2/testdata/nested_objects_optional/expected.out @@ -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 \ No newline at end of file diff --git a/plugins/parsers/json_v2/testdata/nested_objects_optional/nested_objects_nest.json b/plugins/parsers/json_v2/testdata/nested_objects_optional/nested_objects_nest.json new file mode 100644 index 000000000..709d596dc --- /dev/null +++ b/plugins/parsers/json_v2/testdata/nested_objects_optional/nested_objects_nest.json @@ -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" + } + ] +} \ No newline at end of file diff --git a/plugins/parsers/json_v2/testdata/nested_objects_optional/nested_objects_single.json b/plugins/parsers/json_v2/testdata/nested_objects_optional/nested_objects_single.json new file mode 100644 index 000000000..6f54bf5ba --- /dev/null +++ b/plugins/parsers/json_v2/testdata/nested_objects_optional/nested_objects_single.json @@ -0,0 +1,6 @@ +{ + "timestamp": 1695679022882.0, + "value": 0.20791169081775931, + "name": "inlet-1/temperature", + "datatype": "float" +} \ No newline at end of file diff --git a/plugins/parsers/json_v2/testdata/nested_objects_optional/telegraf.conf b/plugins/parsers/json_v2/testdata/nested_objects_optional/telegraf.conf new file mode 100644 index 000000000..78e6a9fa0 --- /dev/null +++ b/plugins/parsers/json_v2/testdata/nested_objects_optional/telegraf.conf @@ -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'