-
Notifications
You must be signed in to change notification settings - Fork 403
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
remove FastDateFormat #365
remove FastDateFormat #365
Conversation
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.
Thanks for the PR! I really appreciate contributions.
Unfortunately, I cannot accept these changes as-is. This change has removed the ability for logstash-logback-encoder to output timestamps as a json number (for number of milliseconds since unix epoch), and to output timestamps as a json string (representing the number of milliseconds since unix epoch), as documented here. Both of these are backwards-incompatible changes. I would rather not remove this functionality.
The switch from FastDateFormat
to DateTimeFormatter
is also a backwards-incompatible change due to the subtle differences between the patterns used by the two formatters, but I'm willing to accept this change in the next major release of logstash-logback-encoder. However, since logback does not support higher-precision timestamps yet, there is no rush to including this change in logstash-logback-encoder yet.
@@ -160,11 +96,11 @@ protected String getFormattedTimestamp(Event event) { | |||
*/ | |||
private void updateTimestampWriter() { | |||
if (UNIX_TIMESTAMP_AS_NUMBER.equals(pattern)) { | |||
timestampWriter = new NumberTimestampWriter(); | |||
timestampWriter = null; |
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 a backwards incompatible change that I won't be able to accept.
logstash-logback-encoder still needs to optionally support writing timestamps as numbers indicating the number of milliseconds since unix epoch
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.
For this one, you have to take a close look at the overall change, or maybe I should remove UNIX_TIMESTAMP_AS_NUMBER completely because currently its only used in 2 test cases for it....
However, what was done previously, you would take the timestamp as milliseconds, convert them to a String, and then write it to the Json (inside the NumberTimestampWriter).
So actually im not using it anymore, I will remove it to clear confusion.
(Nothing lost 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.
We cannot remove the UNIX_TIMESTAMP_AS_NUMBER, or the NumberTimestampWriter
.
The FormattedTimestampJsonProvider
supports three scenarios:
UNIX_TIMESTAMP_AS_NUMBER will write the timestamp value as a json number indicating the number of milliseconds since unix epoch, like this:
{
"@timestamp" : 1570901563
}
UNIX_TIMESTAMP_AS_STRING will write the timestamp value as a json string indicating the number of milliseconds since unix epoch, like this:
{
"@timestamp" : "1570901563"
}
And any other pattern will be used as a format string. e.g.
{
"@timestamp" : "2011-12-03T10:15:30+01:00"
}
From what I can tell, the new code always writes the timestamp value as a json string, which has effectively removed support for UNIX_TIMESTAMP_AS_NUMBER.
} else if (UNIX_TIMESTAMP_AS_STRING.equals(pattern)) { | ||
timestampWriter = new StringTimestampWriter(); | ||
timestampWriter = DateTimeFormatter.ofPattern(DEFAULT_PATTERN).withZone(TimeZone.getDefault().toZoneId()); |
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 a backwards incompatible change that I won't be able to accept.
logstash-logback-encoder still needs to optionally support writing timestamps as strings indicating the number of milliseconds since unix epoch
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 missunderstood the StringTimestampWriter, I will take a second look
} else { | ||
timestampWriter = new PatternTimestampWriter(FastDateFormat.getInstance(pattern, timeZone)); | ||
timestampWriter = DateTimeFormatter.ofPattern(pattern, Locale.getDefault()).withZone(TimeZone.getDefault().toZoneId()); |
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 there are subtle differences in the pattern strings used by DateTimeFormatter
and FastDateFormat
, this is a backwards incompatible change. I'm willing to accept this change, but this will need a major version bump of logstash-logback-encoder.
I'll probably hold off on this until logback supports timestamps with higher precision.
@@ -200,7 +200,7 @@ public void unixTimestampAsNumber() throws Exception { | |||
|
|||
JsonNode node = MAPPER.readTree(encoded); | |||
|
|||
assertThat(node.get("@timestamp").numberValue()).isEqualTo(timestamp); | |||
assertThat(node.get("@timestamp").asLong()).isEqualTo(timestamp); |
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.
Per my previous comment, this change will need to be reverted to ensure backwards compatibility. The json node should be a number value, not a string value that needs to be converted to a Long
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.
Sorry, Long is a type of Number? Its just the correct one already.
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.
They are not quite the same.
numberValue()
will return the number if and only if the JsonNode represents a JSON number. This is the expected condition of this test case.
asLong()
will convert String JsonNode values to a number. In this test case, the JsonNode is not expected contain a String value, so the test would incorrectly pass if the json node contained a string value.
In other words, the test should only pass if the json looks like this:
{
"@timestamp" : 1570901563
}
The test should fail if the json looks like this:
{
"@timestamp" : "1570901563"
}
@@ -70,12 +66,12 @@ | |||
public class LogstashEncoderTest { | |||
|
|||
private static Logger LOG = LoggerFactory.getLogger(LogstashEncoderTest.class); | |||
|
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.
Would you be willing to revert all these whitespace changes?
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 one is annoying me aswell, I didnt had this change until I commited, something wrong in my Settings I guess, I will look into it.
assertThat(node.get("@timestamp").textValue()).isEqualTo(FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZZ").format | ||
(timestamp)); | ||
|
||
assertThat(node.get("@timestamp").textValue()).isEqualTo(String.valueOf(timestamp)); |
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.
Same comment as above. Why is the expected value here a long value converted to a 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.
I missunderstood the StringTimestampWriter, as a result I've done some wrong changes here
assertThat(output).isEqualTo(String.format( | ||
"{%n" | ||
+ " @timestamp : \"" + FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZZ").format(timestamp) + "\",%n" | ||
+ " @timestamp : \"" + String.valueOf(timestamp) + "\",%n" |
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.
Same comment as above. Why is the expected value here a long value converted to a 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.
I missunderstood the StringTimestampWriter, as a result I've done some wrong changes here
JsonNode node = MAPPER.readTree(encoded); | ||
|
||
assertThat(node.get("@timestamp").textValue()).isEqualTo(FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZZ").format | ||
(timestamp)); | ||
assertThat(node.get("@timestamp").textValue()).isEqualTo(String.valueOf(timestamp)); |
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.
Same comment as above. Why is the expected value here a long value converted to a 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.
I missunderstood the StringTimestampWriter, as a result I've done some wrong changes here
assertThat(node.get("@timestamp").textValue()).isEqualTo(FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZZ", TimeZone.getTimeZone("UTC")).format | ||
(timestamp)); | ||
|
||
assertThat(node.get("@timestamp").textValue()).isEqualTo(String.valueOf(timestamp)); |
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.
Same comment as above. Why is the expected value here a long value converted to a 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.
I missunderstood the StringTimestampWriter, as a result I've done some wrong changes here
} else { | ||
timestampWriter = new PatternTimestampWriter(FastDateFormat.getInstance(pattern, timeZone)); | ||
timestampWriter = DateTimeFormatter.ofPattern(pattern, Locale.getDefault()).withZone(TimeZone.getDefault().toZoneId()); |
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 new code is always using the default timezone. It needs to take the configured timeZone
into consideration like the old code.
Closing this in favor of #377 Thanks @J-Jimmy for filing the issue, and contributing the PR. Even though I'm not accepting this PR directly, I used your contribution as a guide. I'll definitely call out your effort in the release notes when this is released. |
Replace FastDateFormat with DateTimeFormatter and Instant from java.time package