2012-09-18 43 views
0

我创建了一个具有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是一个漫长的过程,在应用程序处理过程中我可以看到这些日志非常重要。

回答

0

您的代码似乎在实际写入日志(在进程退出时发生)之前似乎正在等待logStream到达EOF。尝试重构它逐字符读取它,然后每当看到换行符时记录累积的字符缓冲区(当然,因此您可以获得最后一行)。

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

+1被搞砸了。另外,如果你直接使用System.out.println而不是'debug',那么日志会更简单:否则你最终会在两行中产生两个时间戳等等,以及其他日志记录。 – artbristol

+0

良好的捕捉:)我没想到除非他使用“空白”布局来摆脱第二次日志调用的格式化(这很奇怪),并且使用了其他一些appender来调试'debug()'而不是'System.out' – Raffaele

+0

主要想法是我想使用“Runtime.exec()”。我确实执行了一些必须在Jar1中的代码。我已经试过你的代码,但它仍然在Jar2过程完成后打印所有日志,这是合乎逻辑的。如你所说;因为“代码等待子流程完成,因为您在流结束后登录了该行”! – Brad