logstash
logstash copied to clipboard
Fix JSON filter @timestamp parsing to match JSON codec behavior
Type of change
Release notes
- Fixes an issue where JSON filter leaves
@timestampas a String. It now parses ISO8601 strings into a Timestamp, matching JSON codec behavior. On parse failure, adds_timestampparsefailureand preserves the original value in"_@timestamp".
What does this PR do?
- Adds special handling for
@timestampinEvent.setField() - Ensures
@timestampset viasetFieldis converted to aTimestamp - Aligns
@timestamphandling between JSON codec and JSON filter - Adds failure tagging and preserves the original value on invalid formats
- Fixes a bug where JSON filter would not parse
@timestampto a Timestamp object
Why is it important/What is the impact to the user?
- Guarantees consistent
@timestamphandling across input (codec) and filter paths - Simplifies pipelines that receive JSON with embedded
@timestampby removing the need for a separatedatefilter in common cases - Improves visibility on parse failures (tag + original value preserved)
Implementation notes
- Detects
FieldReference.TIMESTAMP_REFERENCE("@timestamp") insideEvent.setField()and uses the sameinitTimestamp()logic used by the constructor, then callssetTimestamp() - On parse failure, adds
_timestampparsefailureand stores the original value in"_@timestamp" - Applies only to the root
@timestamp; no impact to other fields or[@metadata] - Negligible performance impact (one conditional + parse only when applicable)
Checklist
- [x] My code follows the style guidelines of this project
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] I have made corresponding change to the default configuration files (and/or docker env variables)
- [ ] I have added tests that prove my fix is effective or that my feature works
Author's Checklist
- [x] Uses the same parsing path (
initTimestamp) as the constructor - [x] Verified tagging/original-value preservation on invalid formats
- [x] No impact to fields other than root
@timestampand no impact to[@metadata] - [x] Backward compatibility maintained (root
@timestampcoerced to Timestamp as intended)
How to test this PR locally
- Pipeline (A) – JSON filter path
input { stdin {} }
filter { json { source => "message" } }
output { stdout { codec => rubydebug } }
Input:
{"@timestamp":"2023-12-01T10:30:00.000Z","foo":"bar"}
Expected:
-
@timestamp: 2023-12-01T10:30:00.000Z (Timestamp object) -
foo: "bar"
- Pipeline (B) – JSON codec path (for comparison)
input { stdin { codec => json } }
output { stdout { codec => rubydebug } }
With the same input, should produce the same result as Pipeline (A).
- Failure case
{"@timestamp":"invalid-timestamp","foo":"bar"}
Expected:
-
tagsincludes_timestampparsefailure -
"_@timestamp"contains"invalid-timestamp" -
@timestampis set to the current time
Related issues
- Closes elastic/logstash#17931
Use cases
- Services/agents that emit JSON with
@timestampcan rely on consistent application of the timestamp without a separatedatefilter - Consistency between codec/json and filter/json in mixed environments
Screenshots
- N/A
Logs
- Success:
@timestampappears as a time object (e.g.,2023-12-01T10:30:00.000Z) - Failure:
_timestampparsefailureintags, original value preserved in"_@timestamp"
💚 CLA has been signed
:robot: GitHub comments
Expand to view the GitHub comments
Just comment with:
-
rundocs-build: Re-trigger the docs validation. (use unformatted text in the comment!)
This pull request does not have a backport label. Could you fix it @groge? 🙏 To fixup this pull request, you need to add the backport labels for the needed branches, such as:
-
backport-8./dis the label to automatically backport to the8./dbranch./dis the digit. - If no backport is necessary, please add the
backport-skiplabel
/backport 8.17 8.18 8.19 9.0 9.1
run docs-build