Skip to content

Commit

Permalink
Add strict mode to JSON parser (influxdata#6536)
Browse files Browse the repository at this point in the history
  • Loading branch information
rawkode authored and idohalevi committed Sep 23, 2020
1 parent 73b97e5 commit b9c67be
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 1 deletion.
4 changes: 4 additions & 0 deletions plugins/parsers/json/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
##
Expand Down
8 changes: 7 additions & 1 deletion plugins/parsers/json/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Config struct {
TimeFormat string
Timezone string
DefaultTags map[string]string
Strict bool
}

type Parser struct {
Expand All @@ -44,6 +45,7 @@ type Parser struct {
timeFormat string
timezone string
defaultTags map[string]string
strict bool
}

func New(config *Config) (*Parser, error) {
Expand All @@ -62,6 +64,7 @@ func New(config *Config) (*Parser, error) {
timeFormat: config.TimeFormat,
timezone: config.Timezone,
defaultTags: config.DefaultTags,
strict: config.Strict,
}, nil
}

Expand All @@ -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:
Expand Down
36 changes: 36 additions & 0 deletions plugins/parsers/json/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 = `
Expand Down Expand Up @@ -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{
Expand Down
4 changes: 4 additions & 0 deletions plugins/parsers/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ type Config struct {
// default timezone
JSONTimezone string `toml:"json_timezone"`

// Whether to continue if a JSON object can't be coerced
JSONStrict bool `toml:"json_strict"`

// Authentication file for collectd
CollectdAuthFile string `toml:"collectd_auth_file"`
// One of none (default), sign, or encrypt
Expand Down Expand Up @@ -164,6 +167,7 @@ func NewParser(config *Config) (Parser, error) {
TimeFormat: config.JSONTimeFormat,
Timezone: config.JSONTimezone,
DefaultTags: config.DefaultTags,
Strict: config.JSONStrict,
},
)
case "value":
Expand Down

0 comments on commit b9c67be

Please sign in to comment.