-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
[Filebeat] - Add raw json field when unmarshaling fails #6591
[Filebeat] - Add raw json field when unmarshaling fails #6591
Conversation
Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually? |
jenkins, test it |
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.
I would like to see the raw JSON contained in the message
field on error. Would that be possible to implement?
@andrewkroh I think you are right, |
filebeat/harvester/reader/json.go
Outdated
if jsonFields == nil { | ||
jsonFields = common.MapStr{} | ||
} | ||
jsonFields["message"] = fmt.Sprintf("Raw json data: %s", string(text)) |
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.
I think this is going to produce json.message
in the final event and I'd like to have just message
. It looks to me like the message.Content
field is being populated with the text
(raw json) when an error occurs.
So I think something upstream in the harvester needs to change to allow the fields["message"] = message.Content
to be set. I think the issue lies within this code:
beats/filebeat/input/log/harvester.go
Lines 272 to 307 in a93acbd
text := string(message.Content) | |
// Check if data should be added to event. Only export non empty events. | |
if !message.IsEmpty() && h.shouldExportLine(text) { | |
fields := common.MapStr{ | |
"source": state.Source, | |
"offset": state.Offset, // Offset here is the offset before the starting char. | |
} | |
fields.DeepUpdate(message.Fields) | |
// Check if json fields exist | |
var jsonFields common.MapStr | |
if f, ok := fields["json"]; ok { | |
jsonFields = f.(common.MapStr) | |
} | |
data.Event = beat.Event{ | |
Timestamp: message.Ts, | |
} | |
if h.config.JSON != nil && len(jsonFields) > 0 { | |
ts := reader.MergeJSONFields(fields, jsonFields, &text, *h.config.JSON) | |
if !ts.IsZero() { | |
// there was a `@timestamp` key in the event, so overwrite | |
// the resulting timestamp | |
data.Event.Timestamp = ts | |
} | |
} else if &text != nil { | |
if fields == nil { | |
fields = common.MapStr{} | |
} | |
fields["message"] = text | |
} | |
data.Event.Fields = fields | |
} |
@ruflin I think we need your Filebeat expertise on this modification.
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.
I think what you want is to append a message key in the final event. That should be pretty straightforward to implement. I have done that change but it seems too hackish.
7f084c2
to
496ad20
Compare
496ad20
to
eedc6f3
Compare
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.
LGTM. It would be good to have a test case added to json_test.go that exercises the new code you added.
filebeat/harvester/reader/json.go
Outdated
@@ -30,7 +30,8 @@ func (r *JSON) decodeJSON(text []byte) ([]byte, common.MapStr) { | |||
err := unmarshal(text, &jsonFields) | |||
if err != nil || jsonFields == nil { | |||
if !r.cfg.IgnoreDecodingError { | |||
logp.Err("Error decoding JSON: %v", err) | |||
|
|||
logp.Err("Error decoding JSON: %v. Raw data: %s", err, string(text)) |
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.
Maybe we shouldn't put this raw message into the error logs. I'm worried about sensitive information being leaked inside of the Filebeat logs.
// handle the case in which r.cfg.AddErrorKey is set and len(jsonFields) == 1 | ||
// and only thing it contains is `error` key due to error in json decoding | ||
// which results in loss of message key in the main beat event | ||
if len(jsonFields) == 1 && jsonFields["error"] != nil { |
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.
That looks like it accomplishes it. 👍
@andrewkroh I don't think we can write a test case for same in |
ca9253d
to
2372894
Compare
jenkins, test it |
jenkins, test it |
Fixes #6516.