-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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 parser plugin can sometimes output records as strings rather than Hash
#4100
Comments
Thanks for reporting! <source>
@type sample
tag test.hoge
sample {"message": "{\"k\":\"v\"}"}
</source>
<source>
@type sample
tag test.fuga
sample {"message": "\"HELLO\""}
</source>
<filter test.**>
@type parser
key_name message
<parse>
@type json
</parse>
</filter>
<filter test.**>
@type record_transformer
enable_ruby true
<record>
class ${record.class}
</record>
</filter>
<match test.**>
@type stdout
</match> Output
|
I think this is probably a bug.
Thanks for your consideration on this point! |
Thanks for looking at this so quickly! Sounds like you can reproduce it alright, but let me know if there is anything I can do to help 😄 (also sorry, hadn't realised you could use the |
Sorry for the delay!
This is not only an issue for So we should fix fluentd/lib/fluent/plugin/parser_json.rb Lines 72 to 81 in d5df992
This should return The root cause of this is that sometimes the Ruby library does not parse a given string as require "json"
JSON.load('"hoge"')
=> "hoge" I don't understand the reason for this Ruby specification. |
I have fixed this in |
This is a more complicated issue than I initially thought... It is also necessary to take into account that the value is parsed as an The current implementation of |
We need to consider carefully the specification of the case where raw data can not be parsed as I think the currently intended usecases are I think we should consider only these 2 patterns as parsable for now. |
<source>
@type sample
tag test.hash
sample {"message": "{\"k\":\"v\"}"}
</source>
<source>
@type sample
tag test.string
sample {"message": "\"HELLO\""}
</source>
<source>
@type sample
tag test.array
sample {"message": "[{\"k\":\"v\"}, {\"k2\":\"v2\"}]"}
</source>
<filter test.**>
@type parser
key_name message
<parse>
@type json
</parse>
</filter>
<filter test.**>
@type record_transformer
enable_ruby true
<record>
class ${record.class}
</record>
</filter>
<match test.**>
@type stdout
</match>
|
Has there been any progress on this? |
#4474 partially fixes this issue but not yet complete for |
Thanks folks! |
The remaining problem is From #4478
|
@daipom maybe i can check this out but i am not getting the context of problem fully The ask in this problem is we need to facilitate multiple hashes being emitted ? |
@Athishpranav2003 Thanks!! Since this is a significant problem with Fluentd, I would be very happy if it could be fixed! That's right! Currently, Fluentd outputs the warning message. This will not be just a fluentd/lib/fluent/plugin/filter.rb Lines 82 to 104 in 4a94271
We need to be careful not to affect other filter plugins or break the compatibility. |
Correct me if I am wrong |
https://docs.fluentd.org/plugin-development/api-plugin-filter#methods Filter plugins can have 3 methods:
Currently, A and B should receive and return one record of Hash. Only a few Filter plugins, such as I said the following,
but given this point, I am beginning to think that it would be wrong for
|
@daipom makes sense. I guess the change is specific to |
Describe the bug
The JSON parser plugin can sometimes emit records as a string rather than as a
Hash
. Similar to #1279, the expectation of plugins further down the line is that the record it receives is always aHash
, but this contract is broken in some circumstances by the JSON plugin leading to some very difficult to diagnose bugs.This happens because a string is considered valid JSON (SO) and the JSON parser (Oj at least) treats it as such and parses it successfully. But the thing it outputs from it's parsing is not a
Hash
type, it is a string, and at no point in the JSON parser does it throw if the record it is returning isn't aHash
object.To Reproduce
If you setup a fluentd configmap which a super simple JSON filter setup:
When presented with a record which has
{"message": "\"HELLO\""}
it will parse it so that the resulting record is"HELLO"
(i.e. not aHash
type, but just a string. This then causes errors in plugins further down the line (for example in my example this was followed by the Prometheus plugin which threw an errorundefined method
map' for #String:0x00007fdbb6b32308\nDid you mean? tap` which was rather hard to debug).Expected behavior
I would of expected the parser plugin to call error out if the thing it was parsing is a string (i.e. the same behaviour you see if the parser failed to parse the JSON).
Potentially I would just expect us to check if
values
is aHash
onfluentd/lib/fluent/plugin/filter_parser.rb
Line 74 in d5df992
But that might change behaviour in an unexpected way for people, so it might need to be a configuration value. It is this question what led me to doing an Issue rather than a PR
Your Environment
Your Configuration
Note the plugin which causes the error is the JSON plugin because it is emitting records of string type, but it is the Prometheus plugin which is throwing the error because it is the next thing handling the records (and is not designed to be able to)
Your Error Log
dump an error event: error_class=NoMethodError error="undefined method `map' for #<String:0x00007fdbb6b32308>\nDid you mean? tap" location="/usr/local/bundle/gems/fluent-plugin-prometheus-2.0.3/lib/fluent/plugin/prometheus.rb:90:in `stringify_keys'" tag="gearset.x" time=2023-03-14 12:48:13.381801632 +0000 record="HELLO"
Additional context
No response
The text was updated successfully, but these errors were encountered: