diff options
author | Jon Marius Venstad <jvenstad@yahoo-inc.com> | 2018-08-16 13:28:30 +0200 |
---|---|---|
committer | Jon Marius Venstad <jvenstad@yahoo-inc.com> | 2018-08-16 13:28:30 +0200 |
commit | 92ebb03d116b01c5439acf7cbec9980212744d92 (patch) | |
tree | 4a744c7f1dcfaaf97535ff1ef97808f2721f7b2b | |
parent | 700830b1e92e8e54c2181e3b289c773c5e954868 (diff) |
Add serialisation of LogRecord objects, with Vespa log levels
4 files changed, 153 insertions, 2 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/LogRecordSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/LogRecordSerializer.java index 4377a5a4ab4..f582b240260 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/LogRecordSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/LogRecordSerializer.java @@ -1,5 +1,64 @@ package com.yahoo.vespa.hosted.controller.persistence; -public class LogRecordSerializer { +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.yahoo.log.LogLevel; +import com.yahoo.slime.ArrayTraverser; +import com.yahoo.slime.Cursor; +import com.yahoo.slime.Inspector; +import com.yahoo.slime.ObjectTraverser; +import com.yahoo.slime.Slime; +import com.yahoo.vespa.hosted.controller.deployment.Step; + +import java.util.List; +import java.util.Map; +import java.util.logging.LogRecord; + +/** + * Serialisation of LogRecord objects. Not all fields are stored! + * + * @author jonmv + */ +class LogRecordSerializer { + + private static final String idField = "id"; + private static final String levelField = "level"; + private static final String timestampField = "at"; + private static final String messageField = "message"; + + Slime recordsToSlime(Map<Step, List<LogRecord>> stepRecords) { + Slime root = new Slime(); + Cursor recordsObject = root.setObject(); + stepRecords.forEach((step, records) -> { + Cursor recordsArray = recordsObject.setArray(RunSerializer.valueOf(step)); + records.forEach(record -> toSlime(record, recordsArray.addObject())); + }); + return root; + } + + void toSlime(LogRecord record, Cursor recordObject) { + recordObject.setLong(idField, record.getSequenceNumber()); + recordObject.setString(levelField, LogLevel.getVespaLogLevel(record.getLevel()).getName()); + recordObject.setLong(timestampField, record.getMillis()); + recordObject.setString(messageField, record.getMessage()); + } + + Map<Step, List<LogRecord>> recordsFromSlime(Slime slime) { + ImmutableMap.Builder<Step, List<LogRecord>> stepRecords = ImmutableMap.builder(); + slime.get().traverse((ObjectTraverser) (step, recordsArray) -> { + ImmutableList.Builder<LogRecord> records = ImmutableList.builder(); + recordsArray.traverse((ArrayTraverser) (__, recordObject) -> records.add(fromSlime(recordObject))); + stepRecords.put(RunSerializer.stepOf(step), records.build()); + }); + return stepRecords.build(); + } + + private LogRecord fromSlime(Inspector recordObject) { + LogRecord record = new LogRecord(LogLevel.parse(recordObject.field(levelField).asString()), + recordObject.field(messageField).asString()); + record.setSequenceNumber(recordObject.field(idField).asLong()); + record.setMillis(recordObject.field(timestampField).asLong()); + return record; + } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java index 7342874d724..a71e6a393ac 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java @@ -51,7 +51,7 @@ import static com.yahoo.vespa.hosted.controller.deployment.Step.endTests; * * @author jonmv */ -public class RunSerializer { +class RunSerializer { private static final String stepsField = "steps"; private static final String applicationField = "id"; diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/LogSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/LogSerializerTest.java index 964c723a8b9..554e30637f9 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/LogSerializerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/LogSerializerTest.java @@ -1,5 +1,65 @@ package com.yahoo.vespa.hosted.controller.persistence; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.yahoo.log.LogLevel; +import com.yahoo.vespa.config.SlimeUtils; +import com.yahoo.vespa.hosted.controller.deployment.Step; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +import static com.yahoo.vespa.hosted.controller.deployment.Step.deployReal; +import static com.yahoo.vespa.hosted.controller.deployment.Step.deployTester; +import static org.junit.Assert.assertEquals; + +/** + * @author jonmv + */ public class LogSerializerTest { + private static final LogRecordSerializer serializer = new LogRecordSerializer(); + private static final Path logsFile = Paths.get("src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/logs.json"); + + @Test + public void testSerialization() throws IOException { + // Local, because it's not supposed to be used for anything else than verifying equality here! + class EgalitarianLogRecord extends LogRecord { + private EgalitarianLogRecord(Level level, String msg) { + super(level, msg); + } + @Override + public boolean equals(Object o) { + if ( ! (o instanceof LogRecord)) return false; + LogRecord record = (LogRecord) o; + return getSequenceNumber() == record.getSequenceNumber() + && getLevel() == record.getLevel() + && getMillis() == record.getMillis() + && getMessage().equals(record.getMessage()); + } + @Override + public int hashCode() { throw new AssertionError(); } + } + + LogRecord first = new EgalitarianLogRecord(LogLevel.INFO, "First"); first.setMillis( 0); first.setSequenceNumber(1); + LogRecord second = new EgalitarianLogRecord(LogLevel.INFO, "Second"); second.setMillis( 0); second.setSequenceNumber(2); + LogRecord third = new EgalitarianLogRecord(LogLevel.DEBUG, "Third"); third.setMillis(1000); third.setSequenceNumber(3); + LogRecord fourth = new EgalitarianLogRecord(LogLevel.WARNING, "Fourth"); fourth.setMillis(2000); fourth.setSequenceNumber(4); + + Map<Step, List<LogRecord>> expected = ImmutableMap.of(deployReal, ImmutableList.of(first, third), + deployTester, ImmutableList.of(second, fourth)); + + Map<Step, List<LogRecord>> stepRecords = serializer.recordsFromSlime(SlimeUtils.jsonToSlime(Files.readAllBytes(logsFile))); + assertEquals(expected, stepRecords); + + assertEquals(expected, serializer.recordsFromSlime(serializer.recordsToSlime(stepRecords))); + } + } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/logs.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/logs.json index e69de29bb2d..1135e63e464 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/logs.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/testdata/logs.json @@ -0,0 +1,32 @@ +{ + "deployReal": + [ + { + "id": 1, + "level": "info", + "at": 0, + "message": "First" + }, + { + "id": 3, + "level": "debug", + "at": 1000, + "message": "Third" + } + ], + "deployTester": + [ + { + "id": 2, + "level": "info", + "at": 0, + "message": "Second" + }, + { + "id": 4, + "level": "warning", + "at": 2000, + "message": "Fourth" + } + ] +}
\ No newline at end of file |