in brooklyn-server/core/src/main/java/org/apache/brooklyn/util/core/task/system/internal/ExecWithLoggingHelpers.java [109:197]
public int execWithLogging(Map<String,?> props, final String summaryForLogging, final List<String> commands,
final Map<String,?> env, String expectedCommandHeaders, final ExecRunner execCommand) {
if (commandLogger!=null && commandLogger.isDebugEnabled()) {
String allcmds = (Strings.isBlank(expectedCommandHeaders) ? "" : expectedCommandHeaders + " ; ") + Strings.join(commands, " ; ");
commandLogger.debug("{}, initiating "+shortName.toLowerCase()+" on machine {}{}: {}",
new Object[] {summaryForLogging, getTargetName(),
env!=null && !env.isEmpty() ? " (env "+env+")": "", allcmds});
}
if (commands.isEmpty()) {
if (commandLogger!=null && commandLogger.isDebugEnabled())
commandLogger.debug("{}, on machine {}, ending: no commands to run", summaryForLogging, getTargetName());
return 0;
}
final ConfigBag execFlags = new ConfigBag().putAll(props);
// some props get overridden in execFlags, so remove them from the tool flags
final ConfigBag toolFlags = new ConfigBag().putAll(props).removeAll(
LOG_PREFIX, STDOUT, STDERR, ShellTool.PROP_NO_EXTRA_OUTPUT);
execFlags.configure(ShellTool.PROP_SUMMARY, summaryForLogging);
PipedOutputStream outO = null;
PipedOutputStream outE = null;
StreamGobbler gO=null, gE=null;
try {
preExecChecks();
String logPrefix = execFlags.get(LOG_PREFIX);
if (logPrefix==null) logPrefix = constructDefaultLoggingPrefix(execFlags);
if (!execFlags.get(NO_STDOUT_LOGGING)) {
PipedInputStream insO = new PipedInputStream();
outO = new PipedOutputStream(insO);
String stdoutLogPrefix = "["+(logPrefix != null ? logPrefix+":stdout" : "stdout")+"] ";
gO = new StreamGobbler(insO, execFlags.get(STDOUT), commandLogger).setLogPrefix(stdoutLogPrefix);
gO.start();
execFlags.put(STDOUT, outO);
}
if (!execFlags.get(NO_STDERR_LOGGING)) {
PipedInputStream insE = new PipedInputStream();
outE = new PipedOutputStream(insE);
String stderrLogPrefix = "["+(logPrefix != null ? logPrefix+":stderr" : "stderr")+"] ";
gE = new StreamGobbler(insE, execFlags.get(STDERR), commandLogger).setLogPrefix(stderrLogPrefix);
gE.start();
execFlags.put(STDERR, outE);
}
Tasks.setBlockingDetails(shortName+" executing, "+summaryForLogging);
try {
return execWithTool(MutableMap.copyOf(toolFlags.getAllConfig()), new Function<ShellTool, Integer>() {
public Integer apply(ShellTool tool) {
int result = execCommand.exec(tool, MutableMap.copyOf(execFlags.getAllConfig()), commands, env);
if (commandLogger!=null && commandLogger.isDebugEnabled())
commandLogger.debug("{}, on machine {}, completed: return status {}",
new Object[] {summaryForLogging, getTargetName(), result});
return result;
}});
} finally {
Tasks.setBlockingDetails(null);
}
} catch (IOException e) {
if (commandLogger!=null && commandLogger.isDebugEnabled())
commandLogger.debug("{}, on machine {}, failed: {}", new Object[] {summaryForLogging, getTargetName(), e});
throw Throwables.propagate(e);
} finally {
// Must close the pipedOutStreams, otherwise input will never read -1 so StreamGobbler thread would never die
if (outO!=null) try { outO.flush(); } catch (IOException e) {}
if (outE!=null) try { outE.flush(); } catch (IOException e) {}
Streams.closeQuietly(outO);
Streams.closeQuietly(outE);
try {
if (gE!=null) { gE.join(); }
if (gO!=null) { gO.join(); }
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Throwables.propagate(e);
}
}
}