Add strict mode to JSON parser (#6536)
This commit is contained in:
committed by
Daniel Nelson
parent
41d6a1a787
commit
a9a0d4048a
@@ -18,6 +18,10 @@ ignored unless specified in the `tag_key` or `json_string_fields` options.
|
||||
## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
|
||||
data_format = "json"
|
||||
|
||||
## When strict is true and a JSON array is being parsed, all objects within the
|
||||
## array must be valid
|
||||
strict = false
|
||||
|
||||
## Query is a GJSON path that specifies a specific chunk of JSON to be
|
||||
## parsed, if not specified the whole document will be parsed.
|
||||
##
|
||||
|
||||
@@ -32,6 +32,7 @@ type Config struct {
|
||||
TimeFormat string
|
||||
Timezone string
|
||||
DefaultTags map[string]string
|
||||
Strict bool
|
||||
}
|
||||
|
||||
type Parser struct {
|
||||
@@ -44,6 +45,7 @@ type Parser struct {
|
||||
timeFormat string
|
||||
timezone string
|
||||
defaultTags map[string]string
|
||||
strict bool
|
||||
}
|
||||
|
||||
func New(config *Config) (*Parser, error) {
|
||||
@@ -62,6 +64,7 @@ func New(config *Config) (*Parser, error) {
|
||||
timeFormat: config.TimeFormat,
|
||||
timezone: config.Timezone,
|
||||
defaultTags: config.DefaultTags,
|
||||
strict: config.Strict,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -73,7 +76,10 @@ func (p *Parser) parseArray(data []interface{}) ([]telegraf.Metric, error) {
|
||||
case map[string]interface{}:
|
||||
metrics, err := p.parseObject(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if p.strict {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
results = append(results, metrics...)
|
||||
default:
|
||||
|
||||
@@ -17,6 +17,7 @@ const (
|
||||
validJSONArrayMultiple = "[{\"a\": 5, \"b\": {\"c\": 6}}, {\"a\": 7, \"b\": {\"c\": 8}}]"
|
||||
invalidJSON = "I don't think this is JSON"
|
||||
invalidJSON2 = "{\"a\": 5, \"b\": \"c\": 6}}"
|
||||
mixedValidityJSON = "[{\"a\": 5, \"time\": \"2006-01-02T15:04:05\"}, {\"a\": 2}]"
|
||||
)
|
||||
|
||||
const validJSONTags = `
|
||||
@@ -152,6 +153,41 @@ func TestParseInvalidJSON(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestParseJSONImplicitStrictness(t *testing.T) {
|
||||
parserImplicitNoStrict, err := New(&Config{
|
||||
MetricName: "json_test",
|
||||
TimeKey: "time",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = parserImplicitNoStrict.Parse([]byte(mixedValidityJSON))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestParseJSONExplicitStrictnessFalse(t *testing.T) {
|
||||
parserNoStrict, err := New(&Config{
|
||||
MetricName: "json_test",
|
||||
TimeKey: "time",
|
||||
Strict: false,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = parserNoStrict.Parse([]byte(mixedValidityJSON))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestParseJSONExplicitStrictnessTrue(t *testing.T) {
|
||||
parserStrict, err := New(&Config{
|
||||
MetricName: "json_test",
|
||||
TimeKey: "time",
|
||||
Strict: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = parserStrict.Parse([]byte(mixedValidityJSON))
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestParseWithTagKeys(t *testing.T) {
|
||||
// Test that strings not matching tag keys are ignored
|
||||
parser, err := New(&Config{
|
||||
|
||||
Reference in New Issue
Block a user