public class ExecSource extends AbstractSource implements EventDrivenSource,Configurable
关键静态内部类private static class ExecRunnable implements Runnable
public ExecRunnable(String command, ChannelProcessor channelProcessor,
CounterGroup counterGroup, boolean restart, long restartThrottle,
boolean logStderr, int bufferCount) {
this.command = command;
this.channelProcessor = channelProcessor;
this.counterGroup = counterGroup;
this.restartThrottle = restartThrottle;
this.bufferCount = bufferCount;
this.restart = restart;
this.logStderr = logStderr;
}
private String command;
private ChannelProcessor channelProcessor;
private CounterGroup counterGroup;
private volatile boolean restart;
private long restartThrottle;
private int bufferCount;
private boolean logStderr;
@Override
public void run() {
do {
String exitCode = "unknown";
BufferedReader reader = null;
Process process = null;
try {
String[] commandArgs = command.split("\\s+");
process = new ProcessBuilder(commandArgs).start();
reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
// StderrLogger dies as soon as the input stream is invalid
StderrReader stderrReader = new StderrReader(new BufferedReader(
new InputStreamReader(process.getErrorStream())), logStderr);
stderrReader.setName("StderrReader-[" + command + "]");
stderrReader.setDaemon(true);
stderrReader.start();
String line = null;
List<Event> eventList = new ArrayList<Event>();
while ((line = reader.readLine()) != null) {
counterGroup.incrementAndGet("exec.lines.read");
eventList.add(EventBuilder.withBody(line.getBytes()));
if(eventList.size() >= bufferCount) {
channelProcessor.processEventBatch(eventList);
eventList.clear();
}
}
if(!eventList.isEmpty()) {
channelProcessor.processEventBatch(eventList);
}
} catch (Exception e) {
logger.error("Failed while running command: " + command, e);
if(e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
logger.error("Failed to close reader for exec source", ex);
}
}
if(process != null) {
process.destroy();
try {
exitCode = String.valueOf(process.waitFor());
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
if(restart) {
logger.info("Restarting in {}ms, exit code {}", restartThrottle, exitCode);
try {
Thread.sleep(restartThrottle);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} while(restart);
通过Process来监听命令执行之后的数据流