How to output logs from Script shell running in Java in log4j RollingFileAppender?

I have a Java Webapplication application running on Tomcat, running shell scripts at runtime, in which many echo commands are executed.

My problem is that I would like all my logs to appear in log4j RollingFileAppender, i.e.:

  • Java Log4j logs (easy to do)
  • Shell echo commands as well (for me, this is the hard part)

Shell scripts are run through the java.lang.Process class. So far, I have managed to output the inputStream and errorStream of the process to System.out thanks to the StreamUtils.copy () method provided by log4j.

But then it's fine to get ConsoleAppender output, but not RollingFileAppender output.

Is there a convenient way to redirect process threads in RollingFileAppender? In Log4j configuration or from Java code?

Here is my 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} | &#x25;-21.21X{applicationId}| %-40.40t| %-5p |%-25.25c{1}| - %m%n" /> </layout> </appender> 

Here is my script launch code:

  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); 
+4
source share
2 answers

Do you use stream? if so, you need to see fooobar.com/questions/644980 / ... for it to work with glidants .

In this regard, your thread can use this method, which you can use to pass to an array of strings (your command with args if any arguments) and return the result of this command to you. Of course, just use the string that it returns to add to your log :)

 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 ""; } 

}

+1
source

Here is a piece of code that I used to register the output of my process. Pretty simple and seems to work. Thanks @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."); } } } 
+3
source

Source: https://habr.com/ru/post/1382538/


All Articles