【问题标题】:How to output logs from a Shell Script launched within Java in a log4j RollingFileAppender?如何在 log4j RollingFileAppender 中从 Java 中启动的 Shell 脚本输出日志?
【发布时间】:2011-12-02 02:00:16
【问题描述】:

我有一个在 Tomcat 上运行的 Java Web 应用程序,在运行时执行 Shell 脚本,其中执行了许多“echo”命令。

我的问题是我希望我的所有日​​志都出现在 log4j RollingFileAppender 中,即:

  • Java Log4j 日志(很容易做到)
  • Shell 回显命令日志也是如此(这对我来说是个棘手的部分)

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} | &#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);

【问题讨论】:

    标签: java shell logging log4j echo


    【解决方案1】:

    这是我用来记录进程输出的代码的 sn-p。非常简单,似乎有效。谢谢@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.");
        }
    }
    }
    

    【讨论】:

      【解决方案2】:

      你在使用线程吗?如果是这样,您需要查看 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 "";
      }
      

      }

      【讨论】:

      • 谢谢,我从你的回答中得到启发(参见我自己对代码的回答)。奇怪的是它不是 log4j 的默认功能。如果周围有 Apache 人... ;)
      猜你喜欢
      • 2022-11-24
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2020-09-23
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 2010-09-21
      相关资源
      最近更新 更多