Skip to content

Commit

Permalink
Relax GELF codec by accepting strings for "timestamp" (#4031)
Browse files Browse the repository at this point in the history
* Add test for #4027

* Relax GELF codec by accepting strings for "timestamp"

Fixes #4027
  • Loading branch information
joschi authored and bernd committed Jul 25, 2017
1 parent e233284 commit 9091388
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 13 deletions.
Expand Up @@ -99,15 +99,20 @@ private static int intValue(final JsonNode json, final String fieldName) {
return -1; return -1;
} }


private static double doubleValue(final JsonNode json, final String fieldName) { private static double timestampValue(final JsonNode json) {
if (json != null) { final JsonNode value = json.path(Message.FIELD_TIMESTAMP);
final JsonNode value = json.get(fieldName); if (value.isNumber()) {

return value.asDouble(-1.0);
if (value != null) { } else if (value.isTextual()) {
return value.asDouble(-1.0); try {
return Double.parseDouble(value.asText());
} catch (NumberFormatException e) {
log.debug("Unable to parse timestamp", e);
return -1.0;
} }
} else {
return -1.0;
} }
return -1.0;
} }


@Nullable @Nullable
Expand All @@ -129,7 +134,7 @@ public Message decode(@Nonnull final RawMessage rawMessage) {
validateGELFMessage(node, rawMessage.getId(), rawMessage.getRemoteAddress()); validateGELFMessage(node, rawMessage.getId(), rawMessage.getRemoteAddress());


// Timestamp. // Timestamp.
final double messageTimestamp = doubleValue(node, Message.FIELD_TIMESTAMP); final double messageTimestamp = timestampValue(node);
final DateTime timestamp; final DateTime timestamp;
if (messageTimestamp <= 0) { if (messageTimestamp <= 0) {
timestamp = rawMessage.getTimestamp(); timestamp = rawMessage.getTimestamp();
Expand Down Expand Up @@ -259,7 +264,7 @@ private void validateGELFMessage(JsonNode jsonNode, UUID id, ResolvableInetSocke


final JsonNode timestampNode = jsonNode.path("timestamp"); final JsonNode timestampNode = jsonNode.path("timestamp");
if (timestampNode.isValueNode() && !timestampNode.isNumber()) { if (timestampNode.isValueNode() && !timestampNode.isNumber()) {
throw new IllegalArgumentException(prefix + "has invalid \"timestamp\": " + timestampNode.asText()); log.warn(prefix + "has invalid \"timestamp\": {} (type: {})", timestampNode.asText(), timestampNode.getNodeType().name());
} }
} }


Expand Down
Expand Up @@ -21,6 +21,7 @@
import org.graylog2.plugin.Message; import org.graylog2.plugin.Message;
import org.graylog2.plugin.configuration.Configuration; import org.graylog2.plugin.configuration.Configuration;
import org.graylog2.plugin.journal.RawMessage; import org.graylog2.plugin.journal.RawMessage;
import org.joda.time.DateTime;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
Expand All @@ -31,6 +32,7 @@


import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.DateTimeException;
import java.util.Collections; import java.util.Collections;


import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -327,7 +329,7 @@ public void decodeFailsWithBlankMessage() throws Exception {
} }


@Test @Test
public void decodeFailsWithWrongTypeForTimestamp() throws Exception { public void decodeSucceedsWithWrongTypeForTimestamp() throws Exception {
final String json = "{" final String json = "{"
+ "\"version\": \"1.1\"," + "\"version\": \"1.1\","
+ "\"host\": \"example.org\"," + "\"host\": \"example.org\","
Expand All @@ -337,9 +339,7 @@ public void decodeFailsWithWrongTypeForTimestamp() throws Exception {


final RawMessage rawMessage = new RawMessage(json.getBytes(StandardCharsets.UTF_8)); final RawMessage rawMessage = new RawMessage(json.getBytes(StandardCharsets.UTF_8));


assertThatIllegalArgumentException().isThrownBy(() -> codec.decode(rawMessage)) assertThat(rawMessage).isNotNull();
.withNoCause()
.withMessageMatching("GELF message <[0-9a-f-]+> has invalid \"timestamp\": Foobar");
} }


@Test @Test
Expand All @@ -361,4 +361,36 @@ public void decodeSucceedsWithMinimalMessages() throws Exception {
assertThat(codec.decode(new RawMessage("{\"short_message\":\"0\"}".getBytes(StandardCharsets.UTF_8)))).isNotNull(); assertThat(codec.decode(new RawMessage("{\"short_message\":\"0\"}".getBytes(StandardCharsets.UTF_8)))).isNotNull();
assertThat(codec.decode(new RawMessage("{\"message\":\"0\"}".getBytes(StandardCharsets.UTF_8)))).isNotNull(); assertThat(codec.decode(new RawMessage("{\"message\":\"0\"}".getBytes(StandardCharsets.UTF_8)))).isNotNull();
} }

@Test
public void decodeSucceedsWithValidTimestampIssue4027() throws Exception {
// https://github.com/Graylog2/graylog2-server/issues/4027
final String json = "{"
+ "\"version\": \"1.1\","
+ "\"short_message\": \"A short message that helps you identify what is going on\","
+ "\"host\": \"example.org\","
+ "\"timestamp\": 1500646980.661"
+ "}";
final RawMessage rawMessage = new RawMessage(json.getBytes(StandardCharsets.UTF_8));

final Message message = codec.decode(rawMessage);
assertThat(message).isNotNull();
assertThat(message.getTimestamp()).isEqualTo(DateTime.parse("2017-07-21T14:23:00.661Z"));
}

@Test
public void decodeSucceedsWithValidTimestampAsStringIssue4027() throws Exception {
// https://github.com/Graylog2/graylog2-server/issues/4027
final String json = "{"
+ "\"version\": \"1.1\","
+ "\"short_message\": \"A short message that helps you identify what is going on\","
+ "\"host\": \"example.org\","
+ "\"timestamp\": \"1500646980.661\""
+ "}";
final RawMessage rawMessage = new RawMessage(json.getBytes(StandardCharsets.UTF_8));

final Message message = codec.decode(rawMessage);
assertThat(message).isNotNull();
assertThat(message.getTimestamp()).isEqualTo(DateTime.parse("2017-07-21T14:23:00.661Z"));
}
} }

0 comments on commit 9091388

Please sign in to comment.