Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FIXED JENKINS-26122] Prepend parallel step execution logs with the b…
…ranch label

Originally-Committed-As: 26c0b445561881be1296309e19a6ed5eb6b8e0ea
  • Loading branch information
tfennelly committed Mar 6, 2015
1 parent 583fc1f commit a5083cc
Showing 1 changed file with 89 additions and 10 deletions.
Expand Up @@ -24,6 +24,9 @@

package org.jenkinsci.plugins.workflow.job;

import hudson.console.LineTransformationOutputStream;
import org.jenkinsci.plugins.workflow.actions.BodyExecutionLabelAction;
import org.jenkinsci.plugins.workflow.actions.BodyInvocationAction;
import org.jenkinsci.plugins.workflow.actions.TimingAction;
import org.jenkinsci.plugins.workflow.flow.FlowExecutionList;
import com.google.common.util.concurrent.ListenableFuture;
Expand All @@ -50,6 +53,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -243,16 +247,32 @@ private void copyLogs() {
AnnotatedLargeText<? extends FlowNode> logText = la.getLogText();
try {
long old = entry.getValue();
long revised = logText.writeRawLogTo(old, listener.getLogger());
if (revised != old) {
entry.setValue(revised);
modified = true;
OutputStream logger;

String prefix = getLogPrefix(node);
if (prefix != null) {
logger = new LogLinePrefixOutputFilter(listener.getLogger(), "[" + prefix + "] ");
} else {
logger = listener.getLogger();
}
if (logText.isComplete()) {
logText.writeRawLogTo(entry.getValue(), listener.getLogger()); // defend against race condition?
assert !node.isRunning() : "LargeText.complete yet " + node + " claims to still be running";
it.remove();
modified = true;

try {
long revised = logText.writeRawLogTo(old, logger);
if (revised != old) {
entry.setValue(revised);
modified = true;
}
if (logText.isComplete()) {
logText.writeRawLogTo(entry.getValue(), logger); // defend against race condition?
assert !node.isRunning() : "LargeText.complete yet " + node + " claims to still be running";
it.remove();
modified = true;
}
} finally {
if (prefix != null) {
// It's a LogLinePrefixOutputFilter (see above). Force an EOL by closing.
logger.close();
}
}
} catch (IOException x) {
LOGGER.log(Level.WARNING, null, x);
Expand All @@ -272,6 +292,50 @@ private void copyLogs() {
}
}
}

private String getLogPrefix(FlowNode node) {
BodyInvocationAction bodyInvocationAction = node.getAction(BodyInvocationAction.class);

if (bodyInvocationAction != null) {
BodyExecutionLabelAction bodyLabelAction = node.getAction(BodyExecutionLabelAction.class);

if (bodyLabelAction != null) {
return bodyLabelAction.getBodyLabel();
} else {
// This exec body does not have a body label. Stop now.
return null;
}
}

List<FlowNode> parents = node.getParents();
if (parents != null && !parents.isEmpty()) {
for (FlowNode parent : parents) {
String prefix = getLogPrefix(parent);
if (prefix != null) {
return prefix;
}
}
}

return null;
}

protected static final class LogLinePrefixOutputFilter extends LineTransformationOutputStream {

private final PrintStream logger;
private final String prefix;

protected LogLinePrefixOutputFilter(PrintStream logger, String prefix) {
this.logger = logger;
this.prefix = prefix;
}

@Override
protected void eol(byte[] b, int len) throws IOException {
logger.append(prefix);
logger.write(b, 0, len);
}
}

private static final Map<String,WorkflowRun> LOADING_RUNS = new HashMap<String,WorkflowRun>();

Expand Down Expand Up @@ -575,7 +639,7 @@ private final class GraphL implements GraphListener {
}
node.addAction(new TimingAction());

listener.getLogger().println("Running: " + node.getDisplayName());
logNodeMessage(node, "Running: " + node.getDisplayName());
if (node instanceof FlowEndNode) {
finish(((FlowEndNode) node).getResult());
} else {
Expand All @@ -588,6 +652,21 @@ private final class GraphL implements GraphListener {
}
}

private void logNodeMessage(FlowNode node, String message) {
PrintStream logger = listener.getLogger();
String prefix = getLogPrefix(node);
if (prefix != null) {
logger.println(String.format("[%s] %s", prefix, message));
} else {
logger.println(message);
}
// Flushing to keep logs printed in order as much as possible. The copyLogs method uses
// LargeText and possibly LogLinePrefixOutputFilter. Both of these buffer and flush, causing strange
// out of sequence writes to the underlying log stream (and => things being printed out of sequence)
// if we don't flush the logger here.
logger.flush();
}

static void alias() {
Run.XSTREAM2.alias("flow-build", WorkflowRun.class);
new XmlFile(null).getXStream().aliasType("flow-owner", Owner.class); // hack! but how else to set it for arbitrary Descriptor’s?
Expand Down

0 comments on commit a5083cc

Please sign in to comment.