2011-11-22 86 views
4

我在Tomcat上运行Java Web应用程序,在运行时执行Shell脚本,其中执行许多“回显”命令。如何通过log4j RollingFileAppender从Java中启动的Shell脚本输出日志?

我的问题是,我想我所有的日志出现在log4j的RollingFileAppender进行,即:

  • Java的Log4j的日志(这是很容易做到)
  • 壳牌回声命令日志以及(这对我来说是棘手的部分)

Shell脚本通过java.lang.Process类运行。 到目前为止,我已经设法将进程的inputStream和errorStream输出到System.out,这要感谢log4j提供的StreamUtils.copy()方法。

但是,这可以很好地获得一些ConsoleAppender输出,但不是RollingFileAppender输出。

是否有任何方便的方法将流程流重定向到RollingFileAppender?在Log4j配置中还是从Java代码?

这里是我的Log4j追加的conf:

<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> 
    <param name="Target" value="System.out" /> 
    <param name="Threshold" value="DEBUG" /> 
    <layout class="org.apache.log4j.PatternLayout"> 
     <param name="ConversionPattern" value="%d{ABSOLUTE} [%-20.20t] %-5p [%-25.25c{1}] - %m%n" /> 
    </layout> 
</appender> 

<appender name="FILE" class="org.apache.log4j.RollingFileAppender"> 
    <param name="Threshold" value="DEBUG" /> 
    <param name="File" value="&LOG_DIR;/&PROJECT_NAME;.log" /> 
    <param name="Append" value="&APPEND;" /> 
    <param name="MaxFileSize" value="&MAX_SIZE;" /> 
    <param name="MaxBackupIndex" value="&MAX_BACKUP;" /> 
    <layout class="org.apache.log4j.PatternLayout"> 
     <param name="ConversionPattern" value="%d{ISO8601} | &#x25;-21.21X{applicationId}| %-40.40t| %-5p |%-25.25c{1}| - %m%n" /> 
    </layout> 
</appender> 

这里是我的启动脚本代码:

ProcessBuilder pb = new ProcessBuilder("sh", "script.sh"); 
    Process p = pb.start(); 
    StreamUtils.copy(p.getInputStream(), System.out); 
    StreamUtils.copy(p.getErrorStream(), System.out); 
    int result = p.waitFor(); 
    LOG.info("Script ended with result " + result); 
    return (result == 0); 

回答

1

您是否使用一个线程?如果是这样,你需要看到https://stackoverflow.com/q/8229913/458901使它与滚动appender一起工作。

与之相关的是,你的线程可以使用这个方法来传递一个字符串数组(你的命令带有args,如果有的话)并且会返回那个命令的输出。当然,仅仅用它返回字符串添加到您的日志:)

private String execute(String[] command){ 
    //System.out.println(command); 
    try{ 
     process = Runtime.getRuntime().exec(command); 
     InputStream istream = process.getInputStream(); 
     Writer writer = new StringWriter(); 
     char[] buffer = new char[1024]; 
     Reader reader = new BufferedReader(new InputStreamReader(istream)); 
     int n; 
     while ((n = reader.read(buffer)) != -1) { 
      writer.write(buffer, 0, n); 
     } 
     reader.close(); 
     istream.close(); 
     return writer.toString(); 
    } 
    catch (IOException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return ""; 
} 

}

+0

谢谢,我的灵感来自你的回答(参考我自己对代码的回答)。奇怪的是,它不是log4j的默认功能。如果阿帕奇人在......附近;) –

3

这里是我用来记录我的过程的输出的代码片断。非常简单,似乎工作。谢谢@mezzie。

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

import org.apache.log4j.Logger; 

public class ProcessLoggerThread extends Thread { 

private final static Logger LOGGER = Logger.getLogger(ProcessLoggerThread.class); 

private InputStream inputStream; 


public ProcessLoggerThread(InputStream inputStream) { 
    super(); 

    this.inputStream = inputStream; 
} 


public void run() { 
    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 
     String line = reader.readLine(); 
     while (line != null) { 
      LOGGER.debug(line); 
      line = reader.readLine(); 
     } 
     reader.close(); 
     LOGGER.debug("End of logs"); 
    } catch (IOException e) { 
     LOGGER.error("The log reader died unexpectedly."); 
    } 
} 
}