Как вывести журналы из сценария оболочки, запущенного в Java, в log4j RollingFileAppender? - PullRequest
4 голосов
/ 22 ноября 2011

У меня есть веб-приложение Java, работающее на Tomcat, выполняющее сценарии Shell во время выполнения, в котором выполняется много команд "echo".

Моя проблема заключается в том, что я хочу, чтобы все мои журналы отображались в log4j RollingFileAppender, т.е.:

  • Журналы Java Log4j (что легко сделать)
  • Журналы команд эха оболочки также (что для меня сложно)

Сценарии оболочки запускаются через класс java.lang.Process.До сих пор мне удалось вывести inputStream и errorStream процесса в System.out благодаря предоставленному log4j методу StreamUtils.copy ().

Но тогда это нормально, чтобы получить некоторый вывод ConsoleAppender,но не вывод RollingFileAppender.

Есть ли удобный способ перенаправления потоков процессов в RollingFileAppender?В конфигурации Log4j или из кода Java?

Вот мой conf приложения LOG4J:

<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);

Ответы [ 2 ]

3 голосов
/ 01 декабря 2011

Вот фрагмент кода, который я использовал для записи результатов моего процесса.Довольно просто и похоже на работу.Спасибо @ 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 голос
/ 22 ноября 2011

Вы используете тему? если это так, вам нужно увидеть https://stackoverflow.com/q/8229913/458901, чтобы он работал с подвижными приложениями.

В связи с этим ваш поток может использовать этот метод, который вы можете использовать для передачи массива строк (ваша команда с аргументами, если таковые имеются) и вернет вам вывод этой команды. Конечно, просто используйте строку, которую он возвращает, чтобы добавить в ваш журнал:)

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

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...