如何逐行打印另一个罐子里的日志?

时间:2012-09-18 12:11:31

标签: java logging jar log4j

我创建了一个包含2个Jar文件的Java应用程序。 Jar1用于初始化和运行Jar2,使用以下代码:

Process process = runtime.exec( "java -jar Jar2.jar" );
printLogs( process );
.
.
.
private static boolean printLogs( Process process ) {
    try {
        BufferedInputStream logStream = new BufferedInputStream( process.getInputStream() );
        String logs = "";
        int buffer = 0;

        while ( ( buffer = logStream.read() ) != -1 ) {
            logs += (char)buffer;
        }

        if( !logs.isEmpty() ) logger.debug( logs );
    } catch (IOException e) {}  

    return true;
}

我使用Log4J从Jar2打印了许多日志,即

logger.debug( "..." );

但Jar2中的所有日志都没有打印到控制台。我弄明白了,因为日志被返回到Jar1而不是控制台,所以我使用上面的代码打印了返回的流。现在日志打印正常,但在所有Jar2进程结束后,所有日志都会立即打印在Jar1中。

问题是:我可以及时打印Jar2中的每个日志行而不是等待所有Jar2进程结束吗?

因为Jar2是一个漫长的过程,所以在应用程序处理过程中我能看到这些日志非常重要。

3 个答案:

答案 0 :(得分:2)

整件事情搞得一团糟。您不需要两个单独的档案和Runtime.exec()

但是,通常使用BufferedReader.readLines来读取文本行。请注意,如果您在读取每一行时记录问题,问题就会消失:

BufferedReader input = new BufferedReader(
  new InputStreamReader(process.getInputStream())
);
String line = null;

while ((line = input.readLine()) != null) {
  System.out.println(line);
}

您的代码等待子进程完成,因为您在流结束后记录了该行(即在子进程终止后)

这是一个演示程序,它使用长时间运行的Ruby程序作为监视过程

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Subprocess {

    static final String[] program = new String[] {
        "ruby",
        "-e" ,
        "(1..5).each{|i|sleep 1;puts i;STDOUT.flush}"
    };

    public static void main(String[] args) throws IOException {
        ProcessBuilder builder = new ProcessBuilder(program);
        builder.redirectErrorStream();

        Process child = builder.start();

        String line = null;
        BufferedReader in = new BufferedReader(
                new InputStreamReader(child.getInputStream()));

        while ((line = in.readLine()) != null)
            System.out.println(line);
    }

}

答案 1 :(得分:0)

您的代码似乎在等待logStream在实际编写日志之前到达EOF(在进程退出时会发生)。尝试重构它以逐个字符地读取它,然后在看到换行符时记录累积的字符缓冲区(当然还有EOF - 所以你得到最后一行)。

答案 2 :(得分:0)

在这篇文章的帮助下,我能够解决这个问题:

Runtime.exec never returns when reading system.in

我也使用了 ProcessBuilder