我在Tomcat上运行Java Web应用程序,在运行时执行Shell脚本,执行许多“echo”命令。
我的问题是我希望我的所有日志都出现在log4j RollingFileAppender中,即:
Shell脚本通过java.lang.Process类运行。 到目前为止,由于log4j提供的StreamUtils.copy()方法,我已设法将进程的inputStream和errorStream输出到System.out。
但是这样可以获得一些ConsoleAppender输出,但不是RollingFileAppender输出。
有没有方便的方法将Process流重定向到RollingFileAppender?在Log4j配置中还是从Java代码?
这是我的LOG4J appender 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} | %-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);
答案 0 :(得分: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.");
}
}
}
答案 1 :(得分: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 "";
}
}