From 21e95c8db5ae40ab1e93070b3490629f57450f7c Mon Sep 17 00:00:00 2001 From: Jon Marius Venstad Date: Thu, 23 Aug 2018 14:57:35 +0200 Subject: Get sub-list of LogEntry from TesterCloud --- .../controller/api/integration/LogEntry.java | 75 ++++++++++++++++++++++ .../api/integration/deployment/TesterCloud.java | 7 +- .../api/integration/stubs/MockTesterCloud.java | 20 ++++-- 3 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/LogEntry.java (limited to 'controller-api') diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/LogEntry.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/LogEntry.java new file mode 100644 index 00000000000..7424b0409c9 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/LogEntry.java @@ -0,0 +1,75 @@ +package com.yahoo.vespa.hosted.controller.api.integration; + +import com.yahoo.log.LogLevel; + +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +import static java.util.Objects.requireNonNull; + +/** Immutable, simple log entries. */ +public class LogEntry { + + private final long id; + private final long at; + private final Level level; + private final String message; + + public LogEntry(long id, long at, Level level, String message) { + if (id < 0) + throw new IllegalArgumentException("Id must be non-negative, but was " + id + "."); + + this.id = id; + this.at = at; + this.level = LogLevel.getVespaLogLevel(requireNonNull(level)); + this.message = requireNonNull(message); + } + + public static LogEntry of(LogRecord record) { + return new LogEntry(record.getSequenceNumber(), record.getMillis(), record.getLevel(), record.getMessage()); + } + + public long id() { + return id; + } + + public long at() { + return at; + } + + public Level level() { + return level; + } + + public String message() { + return message; + } + + @Override + public String toString() { + return "LogEntry{" + + "id=" + id + + ", at=" + at + + ", level=" + level + + ", message='" + message + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof LogEntry)) return false; + LogEntry entry = (LogEntry) o; + return id == entry.id && + at == entry.at && + Objects.equals(level, entry.level) && + Objects.equals(message, entry.message); + } + + @Override + public int hashCode() { + return Objects.hash(id, at, level, message); + } + +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java index f1d07fc9097..f2dbcda54b6 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/TesterCloud.java @@ -1,6 +1,9 @@ package com.yahoo.vespa.hosted.controller.api.integration.deployment; +import com.yahoo.vespa.hosted.controller.api.integration.LogEntry; + import java.net.URI; +import java.util.List; /** * Allows running some predefined tests -- typically remotely. @@ -12,8 +15,8 @@ public interface TesterCloud { /** Signals the tester to run its tests. */ void startTests(URI testerUrl, Suite suite, byte[] config); - /** Returns the currently stored logs from the tester. */ - byte[] getLogs(URI testerUrl); + /** Returns the log entries from the tester with ids after the given threshold. */ + List getLog(URI testerUrl, long after); /** Returns the current status of the tester. */ Status getStatus(URI testerUrl); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockTesterCloud.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockTesterCloud.java index ff3f168a978..176fa8ae683 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockTesterCloud.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/MockTesterCloud.java @@ -1,16 +1,21 @@ package com.yahoo.vespa.hosted.controller.api.integration.stubs; +import com.google.common.collect.ImmutableList; +import com.yahoo.vespa.hosted.controller.api.integration.LogEntry; import com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud; import java.net.URI; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; import static com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud.Status.NOT_STARTED; import static com.yahoo.vespa.hosted.controller.api.integration.deployment.TesterCloud.Status.RUNNING; public class MockTesterCloud implements TesterCloud { - private byte[] logs = new byte[0]; + private List log = new ArrayList<>(); private Status status = NOT_STARTED; private byte[] config; private URI testerUrl; @@ -23,8 +28,8 @@ public class MockTesterCloud implements TesterCloud { } @Override - public byte[] getLogs(URI testerUrl) { - return Arrays.copyOf(logs, logs.length); + public List getLog(URI testerUrl, long after) { + return log.stream().filter(entry -> entry.id() > after).collect(Collectors.toList()); } @Override @@ -32,8 +37,11 @@ public class MockTesterCloud implements TesterCloud { return status; } - public void set(byte[] logs, Status status) { - this.logs = Arrays.copyOf(logs, logs.length); + public void add(LogEntry entry) { + log.add(entry); + } + + public void set(Status status) { this.status = status; } -- cgit v1.2.3 From 48cf0d0a45a14c38607267acbd47a7dd94e82c34 Mon Sep 17 00:00:00 2001 From: Jon Marius Venstad Date: Fri, 24 Aug 2018 09:18:48 +0200 Subject: Use controller clock when job controller logs, and include traces --- .../vespa/hosted/controller/api/integration/LogEntry.java | 4 ---- .../hosted/controller/deployment/InternalStepRunner.java | 11 ++++++++++- .../vespa/hosted/controller/deployment/JobController.java | 6 ++++-- 3 files changed, 14 insertions(+), 7 deletions(-) (limited to 'controller-api') diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/LogEntry.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/LogEntry.java index 7424b0409c9..026e9250cef 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/LogEntry.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/LogEntry.java @@ -26,10 +26,6 @@ public class LogEntry { this.message = requireNonNull(message); } - public static LogEntry of(LogRecord record) { - return new LogEntry(record.getSequenceNumber(), record.getMillis(), record.getLevel(), record.getMessage()); - } - public long id() { return id; } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java index 40696909eec..91cffabeb12 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java @@ -27,7 +27,9 @@ import com.yahoo.vespa.hosted.controller.application.ApplicationVersion; import com.yahoo.vespa.hosted.controller.application.DeploymentJobs; import com.yahoo.yolean.Exceptions; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.PrintStream; import java.io.UncheckedIOException; import java.net.URI; import java.time.Duration; @@ -536,7 +538,14 @@ public class InternalStepRunner implements StepRunner { LogRecord record = new LogRecord(level, message); record.setThrown(thrown); logger.log(record); - controller.jobController().log(id, step, record); + + if (thrown != null) { + ByteArrayOutputStream traceBuffer = new ByteArrayOutputStream(); + thrown.printStackTrace(new PrintStream(traceBuffer)); + message += "\n" + traceBuffer; + } + + controller.jobController().log(id, step, level, message); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java index 4759c03e9bb..ed844b96eda 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java @@ -30,6 +30,7 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.UnaryOperator; +import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.stream.Stream; @@ -93,9 +94,10 @@ public class JobController { } /** Stores the given log record for the given run and step. */ - public void log(RunId id, Step step, LogRecord record) { + public void log(RunId id, Step step, Level level, String message) { locked(id, __ -> { - logs.append(id.application(), id.type(), step, Collections.singletonList(LogEntry.of(record))); + LogEntry entry = new LogEntry(0, controller.clock().millis(), level, message); + logs.append(id.application(), id.type(), step, Collections.singletonList(entry)); return __; }); } -- cgit v1.2.3