From e67fe860e5cfe6b76c8df84c06d7a25483abfd93 Mon Sep 17 00:00:00 2001 From: Bjørn Christian Seime Date: Fri, 29 Mar 2019 15:55:36 +0100 Subject: Improve parsing of timestamps --- .../java/com/yahoo/log/InvalidLogFormatException.java | 4 ++++ vespalog/src/main/java/com/yahoo/log/LogMessage.java | 11 ++++++++--- .../src/test/java/com/yahoo/log/LogMessageTestCase.java | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) (limited to 'vespalog/src') diff --git a/vespalog/src/main/java/com/yahoo/log/InvalidLogFormatException.java b/vespalog/src/main/java/com/yahoo/log/InvalidLogFormatException.java index 37d43b37952..49e0ced7a57 100644 --- a/vespalog/src/main/java/com/yahoo/log/InvalidLogFormatException.java +++ b/vespalog/src/main/java/com/yahoo/log/InvalidLogFormatException.java @@ -13,6 +13,10 @@ public class InvalidLogFormatException extends Exception super(msg); } + public InvalidLogFormatException (String msg, Throwable cause) { + super(msg, cause); + } + public InvalidLogFormatException () { } } diff --git a/vespalog/src/main/java/com/yahoo/log/LogMessage.java b/vespalog/src/main/java/com/yahoo/log/LogMessage.java index ac5b4fcfa0e..1736352493e 100644 --- a/vespalog/src/main/java/com/yahoo/log/LogMessage.java +++ b/vespalog/src/main/java/com/yahoo/log/LogMessage.java @@ -120,10 +120,15 @@ public class LogMessage private static Instant parseTimestamp(String timeStr) throws InvalidLogFormatException { try { - long nanoseconds = (long) (Double.parseDouble(timeStr) * 1_000_000_000L); - return Instant.ofEpochSecond(0, nanoseconds); + int decimalSeparator = timeStr.indexOf('.'); + if (decimalSeparator == -1) { + return Instant.ofEpochSecond(Long.parseLong(timeStr)); + } + long seconds = Long.parseLong(timeStr.substring(0, decimalSeparator)); + long nanoseconds = Long.parseLong(String.format("%1$-9s", timeStr.substring(decimalSeparator + 1)).replace(' ', '0')); // right pad with zeros + return Instant.ofEpochSecond(seconds, nanoseconds); } catch (NumberFormatException e) { - throw new InvalidLogFormatException("Invalid time string: " + timeStr); + throw new InvalidLogFormatException(String.format("Failed to parse timestamp: %s. Timestamp string: '%s'", e.getMessage(), timeStr), e); } } diff --git a/vespalog/src/test/java/com/yahoo/log/LogMessageTestCase.java b/vespalog/src/test/java/com/yahoo/log/LogMessageTestCase.java index 5c6474314fc..15618329ba3 100644 --- a/vespalog/src/test/java/com/yahoo/log/LogMessageTestCase.java +++ b/vespalog/src/test/java/com/yahoo/log/LogMessageTestCase.java @@ -9,6 +9,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** @@ -46,5 +47,21 @@ public class LogMessageTestCase { } } + + @Test + public void testParsingTimestampAndRendering() throws InvalidLogFormatException { + { + LogMessage message = LogMessage.parseNativeFormat("1096639280.524133935\tmalfunction\t26851\t-\tlogtest\tinfo\tStarting up, called as ./log/logtest"); + assertEquals(1096639280L, message.getTimestamp().getEpochSecond()); + assertEquals(524133935L, message.getTimestamp().getNano()); + assertEquals("1096639280.524133\tmalfunction\t26851\t-\tlogtest\tinfo\tStarting up, called as ./log/logtest\n", message.toString()); + } + { + LogMessage message = LogMessage.parseNativeFormat("1096639280.524\tmalfunction\t26851\t-\tlogtest\tinfo\tbackslash: \\\\"); + assertEquals(1096639280L, message.getTimestamp().getEpochSecond()); + assertEquals(524_000_000L, message.getTimestamp().getNano()); + assertEquals("1096639280.524000\tmalfunction\t26851\t-\tlogtest\tinfo\tbackslash: \\\\\n", message.toString()); + } + } } -- cgit v1.2.3