-
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
json_v2 parser and NULL values #10670
Comments
I'll leave this to @sspaink... :-) |
So in the PR to introduce |
From parser.go func (p *Parser) processMetric(input []byte, data []DataSet, tag bool, timestamp time.Time) ([]telegraf.Metric, error) {
if len(data) == 0 {
return nil, nil
}
p.iterateObjects = false
var metrics [][]telegraf.Metric
for _, c := range data {
if c.Path == "" {
return nil, fmt.Errorf("GJSON path is required")
}
result := gjson.GetBytes(input, c.Path)
if result.Type == gjson.Null {
return nil, fmt.Errorf(GJSONPathNUllErrorMSG)
} This is in An example is a basic JSON: {
"weight_ROWKEY": "123",
"weight_serialNumber": "AX00",
"weight_createdAt": 1644708158939,
"weight_weight": 289.799,
"sensor_imei": "123",
"sensor_distributor_name": null,
"sensor_customer_name": "Customer",
"sensor_dist_name": null
} Given the config
This will throw an error. And every time As far as I can see from the GJSON library, there are no way to distinguish if a path do not exists or the value is NULL, since both vill return NULL. Does this make sense? |
I'm thinking the early returns from #10468 are the issue when checking against For example in telegraf/plugins/parsers/json_v2/parser.go Lines 414 to 423 in 2ca5cfe
1.21.3 would proceed to the next object if the path doesn't match, but 1.21.4 will bail out on the first non-match. Since Should the code instead be:
Similarly in
I guess the alternative is to change to having multiple copies of |
Note: I changed my file from
into each object having its own:
This seems to be working, albeit the debug logs are now full of |
@kitlaan , I think It's important to stress that a metric tag (which is processed in I think the problem here is, we have no way of knowing if the path is doesn't exist or the value of the path is actually NULL. This is concerning, since the value very well could be So, can we distinguish between non existing path and Also, But I would hope theres a way to differentiate non existing path and Example of valid json with { "valid": null, "ts": 1234, "value": 82 } The same json buth non existing path: { "ts": 1234, "value": 82 } So configured with |
My use case is slightly different than yours, but the end result is the same -- brokenness Paging through the gjson docs+code... I think this should solve both our cases (this seem right, @sspaink ?) I still think that the new code shouldn't have early-returned and instead |
I’ll run a few tests and see if it’s a viable option to use Exists(). If
so, it should solve the problem. I’ll let you know.
On Sun, 20 Feb 2022 at 18:49, Ted M Lin ***@***.***> wrote:
My use case is slightly different than yours, but the end result is the
same.
Paging through the gjson docs+code... I think this should solve both our
cases:
Any place that the recent change added a check for result.Type ==
gjson.Null, it really should be !result.Exists().
I still think that the new code shouldn't have early-returned and instead
continue the loop.
—
Reply to this email directly, view it on GitHub
<#10670 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA2HVXWHKJN37UTD43TPQ7TU4ESULANCNFSM5OUE5OXA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you authored the thread.Message ID:
***@***.***>
--
Kristian Grimsby
47 29 85 38
***@***.***
http://www.grimsby.us
|
(Sorry for the random train of thought. This plus random MQTT disconnects has been plaguing me this morning.) On second thought, some of the places should still be telegraf/plugins/parsers/json_v2/parser.go Lines 114 to 119 in 2ca5cfe
This is proper; a null TimestampPath is a problem. telegraf/plugins/parsers/json_v2/parser.go Lines 181 to 187 in 2ca5cfe
If !Exists, continue the for loop. If you reach the end of processMetric() and len(metrics) == 0 , then error?
telegraf/plugins/parsers/json_v2/parser.go Lines 414 to 423 in 2ca5cfe
If !Exists, continue the for loop. If you reach the end of processObjects() and len(t) == 0 , then error?
telegraf/plugins/parsers/json_v2/parser.go Lines 428 to 431 in 2ca5cfe
I'm assuming that Telegraf semantics are "if someone explicitly codes a field/tag", then they're expecting data. In which case, this is proper; can't do anything with a null. telegraf/plugins/parsers/json_v2/parser.go Lines 438 to 440 in 2ca5cfe
Ditto for this one. Side thoughtsAlternatively for the telegraf/plugins/parsers/json_v2/parser.go Lines 136 to 149 in 2ca5cfe
Instead of just checking err != nil , could in addition len(fields) == 0 && !c.Optional trigger the error?
Or maybe a check at the very end... telegraf/plugins/parsers/json_v2/parser.go Line 166 in 2ca5cfe
If len(metrics) == 0 && !p.Optional .
Honestly, I'm not sure if the default behavior for "not matching any paths" is to ignore errors (aka only just debug print), or to be explicit and make sure some output metric happens... |
I ran a quick test just to check if Exists returns expected out put and it does. 1package main
2
3import "fmt"
4import "github.com/tidwall/gjson"
5
6var json []byte = []byte(`{ "var1": null, "var2": "test" }`)
7
8func main() {
9 fmt.Println("Fetching json.")
10
11 fmt.Println(gjson.GetBytes(json, "var1").Exists())
12 fmt.Println(gjson.GetBytes(json, "var2").Exists())
13 fmt.Println(gjson.GetBytes(json, "var3").Exists())
14
15 fmt.Println(gjson.GetBytes(json, "var1").Type)
16 fmt.Println(gjson.GetBytes(json, "var2").Type)
17 fmt.Println(gjson.GetBytes(json, "var3").Type)
18} Gives this output Fetching json.
true
true
false
Null
String
Null I can start a PR with the changes. As you're saying, timestamp path should not allow |
This update completely broke my setup, I am now constantly getting GJSON Path returned null errors. |
@shrx I can imagine. I’m working on a fix, but been down with covid the last week. Hope to resume the work on monday. |
Thank you everyone for diving into this problem, I really appreciate all the effort to provide so much detail. It does seem using |
@sspaink I haven't got around to a PR so you might as well put one up. I only played around with the code to confirm that Also, you have to add/move the |
Hi, I'm running arm64 build of telegraf, and looks like the artifact is not available for this arch. I'll wait for the released build, until then I reverted to 1.21.3. |
I tested the new version and while I don't get the "GJSON Path returned null" error anymore, I get a new ones instead:
The first two come from a tradfri lightbulb, which indeed doesn't have a battery field, and the last one is from a sonoff temperature sensor, which obviously doesn't have the color_temp field. This is my relevant config:
|
Appears to be fixed when I add |
Relevant telegraf.conf
None
Logs from Telegraf
None
System info
Telegraf 1.21.4
Docker
No response
Steps to reproduce
None
Expected behavior
None
Actual behavior
None
Additional info
The new release includes #10468 , which I find a little bit inconsistent.
This PR also include throwing exceptins on values being NULL, not just paths.
The setting is also introduced into "objects", but does indeed apply to non-objects as well.
Intended behaviour should be clarified:
The text was updated successfully, but these errors were encountered: