2011-11-22 2 views
4

나는 많은 "echo"명령이 실행되는 런타임에 쉘 스크립트를 실행하여 Tomcat에서 실행되는 Java Webapplication을 가지고있다.log4j RollingFileAppender에서 Java 내에서 시작된 쉘 스크립트에서 로그를 출력하는 방법?

  • 쉘 에코뿐만 아니라 로그 명령 (쉽게 할 수있다)
  • 자바의 log4j 로그 (:

    내 문제는 내 모든 로그 즉, log4j에 RollingFileAppender에 표시 할 것입니다 어느 날 까다로운 부분입니다)

쉘 스크립트는 java.lang.Process 클래스를 통해 실행됩니다. 지금까지 log4j에서 제공 한 StreamUtils.copy() 메소드 덕분에 System.out에 프로세스의 inputStream 및 errorStream을 출력 할 수있었습니다.

그러나 ConsoleAppender 출력을 얻는 것이 좋지만 RollingFileAppender 출력은 아닙니다.

프로세스 스트림을 RollingFileAppender로 리디렉션하는 편리한 방법이 있습니까? Log4j 구성 또는 Java 코드에서?

다음
<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

당신이 스레드를 사용하고 여기에

내 LOG4J의 펜더의 ​​conf입니까? 그렇다면 롤링 어 펜더와 함께 작동 시키려면 https://stackoverflow.com/q/8229913/458901을 볼 필요가 있습니다.

이와 함께 스레드는 문자열 배열 (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."); 
    } 
} 
} 
관련 문제