Skip to content

Commit bc4dc8b

Browse files
authored
Merge pull request #127 from jglick/showSlaveLogs
Added JenkinsRule.showAgentLogs utility
2 parents e135e97 + e6b4b04 commit bc4dc8b

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/main/java/org/jvnet/hudson/test/JenkinsRule.java

+49
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,10 @@
223223
import java.nio.channels.ClosedByInterruptException;
224224
import java.util.concurrent.ExecutionException;
225225
import java.util.logging.ConsoleHandler;
226+
import java.util.logging.Formatter;
226227
import java.util.logging.Handler;
227228
import jenkins.model.ParameterizedJobMixIn;
229+
import jenkins.security.MasterToSlaveCallable;
228230
import org.hamcrest.core.IsInstanceOf;
229231
import org.junit.rules.DisableOnDebug;
230232
import org.junit.rules.Timeout;
@@ -988,6 +990,53 @@ public void waitOnline(Slave s) throws Exception {
988990
}
989991
}
990992

993+
/**
994+
* Same as {@link #showAgentLogs(Slave, Map)} but taking a preconfigured list of loggers as a convenience.
995+
*/
996+
public void showAgentLogs(Slave s, LoggerRule loggerRule) throws Exception {
997+
showAgentLogs(s, loggerRule.getRecordedLevels());
998+
}
999+
1000+
/**
1001+
* Forward agent logs to standard error of the test process.
1002+
* Otherwise log messages would be sent only to {@link Computer#getLogText} etc.,
1003+
* or discarded entirely (if below {@link Level#INFO}).
1004+
* @param s an <em>online</em> agent
1005+
* @param loggers {@link Logger#getName} tied to log level
1006+
*/
1007+
public void showAgentLogs(Slave s, Map<String, Level> loggers) throws Exception {
1008+
s.getChannel().call(new RemoteLogDumper(s.getNodeName(), loggers));
1009+
}
1010+
1011+
private static final class RemoteLogDumper extends MasterToSlaveCallable<Void, RuntimeException> {
1012+
private final String name;
1013+
private final Map<String, Level> loggers;
1014+
private final TaskListener stderr = StreamTaskListener.fromStderr();
1015+
RemoteLogDumper(String name, Map<String, Level> loggers) {
1016+
this.name = name;
1017+
this.loggers = loggers;
1018+
}
1019+
@Override public Void call() throws RuntimeException {
1020+
Handler handler = new Handler() {
1021+
final Formatter formatter = new SupportLogFormatter();
1022+
@Override public void publish(LogRecord record) {
1023+
if (isLoggable(record)) {
1024+
stderr.getLogger().print(formatter.format(record).replaceAll("(?m)^", "[" + name + "] "));
1025+
}
1026+
}
1027+
@Override public void flush() {}
1028+
@Override public void close() throws SecurityException {}
1029+
};
1030+
handler.setLevel(Level.ALL);
1031+
loggers.entrySet().forEach(e -> {
1032+
Logger logger = Logger.getLogger(e.getKey());
1033+
logger.setLevel(e.getValue());
1034+
logger.addHandler(handler);
1035+
});
1036+
return null;
1037+
}
1038+
}
1039+
9911040
/**
9921041
* Blocks until the ENTER key is hit.
9931042
* This is useful during debugging a test so that one can inspect the state of Hudson through the web browser.

src/main/java/org/jvnet/hudson/test/LoggerRule.java

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.logging.LogRecord;
3737
import java.util.logging.Logger;
3838
import java.util.logging.SimpleFormatter;
39+
import java.util.stream.Collectors;
3940
import javax.annotation.CheckForNull;
4041
import javax.annotation.Nonnull;
4142
import org.hamcrest.Matcher;
@@ -138,6 +139,10 @@ public LoggerRule recordPackage(Class<?> clazz, Level level) {
138139
return record(clazz.getPackage().getName(), level);
139140
}
140141

142+
Map<String, Level> getRecordedLevels() {
143+
return loggers.keySet().stream().collect(Collectors.toMap(Logger::getName, Logger::getLevel));
144+
}
145+
141146
/**
142147
* Obtains all log records collected so far during this test case.
143148
* You must have first called {@link #capture}.

0 commit comments

Comments
 (0)