Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to send the stdout of a Process to SLF4J?

Tags:

java

slf4j

I'm essentially doing the following:

Process process = new ProcessBuilder().command( ... ).start();
InputStream stdout = process.getInputStream();
LoggerFactory.getLogger( this.class ).debug...?

Is there any way to write the InputStream to the logger so that it's managed by my logging settings? Or is there another approach I should take to capture the process output?

update: I've rewritten this because I just realized I had read the Process/ProcessBuilder API wrong and that getInputStream() is STDOUT

update 2 Ideally the way that this would be achieved would allow me to process both stdout/stderr as they come (line at a time) and not some time later.

like image 442
xenoterracide Avatar asked Jul 17 '16 00:07

xenoterracide


2 Answers

Here is an edited snippet of the class that I use

public class CommandLineLogger {
  private static final Logger logger = LoggerFactory.getLogger(CommandLineLogger.class);

  public void logStandardOutput(InputStream inputStream) {
    display("stdout", inputStream);    
  }

  private void display(String identifier, InputStream inputStream) {
    logger.debug("Printing output from {}", identifier);
    try {
      String formattedIdentifier = identifier + ":";
      logInputStream(formattedIdentifier, inputStream);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private void logInputStream(String outputType, InputStream inputStream) throws Exception {
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    BufferedReader bufferReader = new BufferedReader(inputStreamReader);
    while (true) {
      String line = bufferReader.readLine();
      if (line != null) {
        logger.debug(outputType + ": " + line);
      } else {
        break;
      }
    }
  }
}
like image 63
pizzaisdavid Avatar answered Oct 15 '22 20:10

pizzaisdavid


If you're willing to use a library, zt-exec is very convenient and can redirect the stdout and stderr of the process to SLF4J.

For example, to redirect stdout to info level and stderr to error level of the logger of the calling class:

new ProcessExecutor().command("java", "-version")
        .redirectOutput(Slf4jStream.ofCaller().asInfo())
        .redirectError(Slf4jStream.ofCaller().asError())
        .execute();
like image 26
Dario Seidl Avatar answered Oct 15 '22 19:10

Dario Seidl