-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Feature/1363: Additional configuration for JSON parser #4351
Conversation
plugins/parsers/registry.go
Outdated
@@ -129,11 +131,13 @@ func NewParser(config *Config) (Parser, error) { | |||
func NewJSONParser( | |||
metricName string, | |||
tagKeys []string, | |||
fieldKeys []string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally we want to avoid changing exported function signatures, as it destabilizes packages. Perhaps what we could do is add a newJSONParser
that takes different (or functional) parameters. We could then update those things that call NewJSONParser
directly to call NewParser
, which will in turn call newJSONParser
.
@maxunt As we discussed, let's have this be |
plugins/parsers/json/parser.go
Outdated
nTime := time.Now().UTC() | ||
if p.JSONTimeKey != "" { | ||
if p.JSONTimeFormat == "" { | ||
err := fmt.Errorf("E! If 'json_time_key' is specified, there must be a 'json_time_format'") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is an error and not a log message, don't include the E!
. As a nitpick, it would probably be good to try to come up with a shorter error string, perhaps: use of 'json_time_key' requires 'json_time_format'
?
Remember to do this for the other errors, here is some more info on how "standard" Go error strings should look: https://github.com/golang/go/wiki/CodeReviewComments#error-strings
plugins/parsers/json/parser.go
Outdated
@@ -114,6 +137,7 @@ func (p *JSONParser) switchFieldToTag(tags map[string]string, fields map[string] | |||
|
|||
func (p *JSONParser) Parse(buf []byte) ([]telegraf.Metric, error) { | |||
|
|||
//if json_query is specified |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this comment, it doesn't provide any new information on why and the what can be determined by looking at the code.
docs/DATA_FORMATS_INPUT.md
Outdated
## List of field names to extract from JSON and add as string fields | ||
# string_fields = [] | ||
|
||
## gjson query path to specify a specific chunk of JSON to be parsed with the above configuration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrap comments before 78 chars for readability.
plugins/parsers/json/parser.go
Outdated
return nil, err | ||
} | ||
|
||
nTime, err = time.Parse(p.JSONTimeFormat, f.Fields[p.JSONTimeKey].(string)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to test the type assertion since it comes from input and could be any type.
plugins/parsers/json/parser_test.go
Outdated
} | ||
|
||
_, err := parser.Parse([]byte(testString)) | ||
assert.Error(t, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use require instead of assert (almost) everywhere. Doesn't really matter here but this will prevent confusing chained errors.
plugins/parsers/json/parser_test.go
Outdated
metrics, err := parser.Parse([]byte(testString)) | ||
assert.NoError(t, err) | ||
assert.Equal(t, metrics[0].Fields()["last"], "Murphy") | ||
assert.Equal(t, 3, len(metrics)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check the length before indexing, this will make the test easier to understand if it fails.
plugins/parsers/json/parser_test.go
Outdated
} | ||
metrics, err := parser.Parse([]byte(testString)) | ||
assert.NoError(t, err) | ||
assert.Equal(t, false, metrics[0].Time() == metrics[1].Time()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check len(metrics) first, add some more tests to check error cases.
docs/DATA_FORMATS_INPUT.md
Outdated
|
||
The JSON data format also supports extracting time values through the config "json_time_key" and "json_time_format". | ||
If "json_time_key" is set, "json_time_format" must be specified. The "json_time_key" describes the name of the field containing time information. The "json_time_format" must be a recognized Go time format. | ||
More info on time formats can be found here: https://golang.org/src/time/format.go |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use https://golang.org/pkg/time/#Parse
as the link. This other link is still not great but the audience of this documentation is not Go developers.
Try to wrap around 78 chars
docs/DATA_FORMATS_INPUT.md
Outdated
|
||
## gjson query path to specify a specific chunk of JSON to be parsed with | ||
## the above configuration. If not specified, the whole file will be parsed. | ||
## gjson query paths are described here: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add link to where gjson query paths are described
plugins/parsers/registry.go
Outdated
// MetricName applies to JSON & value. This will be the name of the measurement. | ||
MetricName string | ||
|
||
//holds a gjson path for json parser |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When adding comments, add a space before starting comment text (// This is my comment
)
plugins/parsers/registry.go
Outdated
timeKey string, | ||
timeFormat string, | ||
defaultTags map[string]string, | ||
) (Parser, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning an error isn't useful here. Where it's an unexported function not matching any interface, I'd remove it, or remove the function altogether and just instantiate a JSONParser
on line 120
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No error is ever returned by the new_Parser functions, but i thought i'd include it here to match the format of the rest of the parsers
plugins/parsers/json/parser.go
Outdated
@@ -126,7 +177,7 @@ func (p *JSONParser) ParseLine(line string) (telegraf.Metric, error) { | |||
} | |||
|
|||
if len(metrics) < 1 { | |||
return nil, fmt.Errorf("Can not parse the line: %s, for data format: influx ", line) | |||
return nil, fmt.Errorf("can not parse the line: %s, for data format: influx ", line) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the copypasta, s/influx/json
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you clarify what you mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace "influx" with "json", it appears to be copy paste code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah i see. good catch thanks
json_time_key = "b_time" | ||
|
||
## holds the format of timestamp to be parsed | ||
json_time_format = "02 Jan 06 15:04 MST" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an interesting example time format because there it doesn't include a year. This results in a pared time that is in year 0. I think after parsing the time we should do something similar to what we did in logparser and use the current year. While this would be pretty annoying if you actually want to store in a metric from year 0, I think it is much more likely to be what is wanted:
if ts.Year() == 0 {
ts = ts.AddDate(timestamp.Year(), 0, 0)
}
closes: #2986
Required for all PRs: