Скопируйте STDOUT в файл, не останавливая его, показывая на экране - PullRequest
4 голосов
/ 31 августа 2009

Программа, которую я создаю, предназначена для запуска без присмотра, поэтому я перенаправил потоки stdout и stderr в файл журнала. Хотя это работает без проблем, хотя я все еще создаю и отлаживаю программное обеспечение, я бы хотел, чтобы оно также отображалось на экране. Возможно ли это?

Для перенаправления потоков, которые я использовал

System.setErr(logWriter);
System.setOut(logWriter);

Спасибо.

Ответы [ 7 ]

8 голосов
/ 24 апреля 2012

Да. Фреймворки журналирования (то есть log4j) являются лучшими, isDebugMode удобен в среде разработки , но , если вам действительно нужно "подать" ваш стандартный вывод, вам может понравиться.

import java.io.PrintStream;
import java.io.File;
public class TeeStream extends PrintStream {
    PrintStream out;
    public TeeStream(PrintStream out1, PrintStream out2) {
        super(out1);
        this.out = out2;
    }
    public void write(byte buf[], int off, int len) {
        try {
            super.write(buf, off, len);
            out.write(buf, off, len);
        } catch (Exception e) {
        }
    }
    public void flush() {
        super.flush();
        out.flush();
    }
}

http://www.exampledepot.com/egs/java.lang/Redirect.html

// import java.io.FileOutputStream;
String dateString = new SimpleDateFormat("yyyyMMdd").format(new Date());
File logFile = new File("mylogfile_" + dateString +".log");
PrintStream logOut = new PrintStream(new FileOutputStream(logFile, true));

PrintStream teeStdOut = new TeeStream(System.out, logOut);
PrintStream teeStdErr = new TeeStream(System.err, logOut);

System.setOut(teeStdOut);
System.setErr(teeStdErr);

Вы скоро найдете LOG.somelevel(msg) гораздо более управляемым, чем System.out.println(msg). Замечательно поднимать уровень журнала, когда все работает хорошо, и понижать уровень, когда это не так, без развертывания отладочной сборки.

4 голосов
/ 31 августа 2009

Если вы на Unix-подобной платформе (что угодно, кроме Windows), вы можете использовать программу tee:

java myprogram | tee output

Это запишет стандартный вывод на консоль, а также файл с именем output.

4 голосов
/ 31 августа 2009

возможно, немного грубовато, но вы можете попробовать это:

private static final isDebugMode = true;

...

if (!isDebugMode) {
  System.setErr(logWriter);
  System.setOut(logWriter);
} 

В качестве альтернативы вы можете написать свою собственную реализацию PrintStream, которая одновременно записывает как в ваш файл журнала, так и на экран. Не похоже, что вам нужно такое поведение, кроме как в процессе разработки, хотя последнее, хотя на самом деле более точный ответ на ваш вопрос, вероятно, не тот, который вы на самом деле хотите.

2 голосов
/ 31 августа 2009

Нет, с вашей настройкой это невозможно. Возможные решения:

  • Используйте некоторое программное обеспечение для мониторинга файла журнала. В Linux / Unix less имеет режим «follow» (Shift-F), который отслеживает файл журнала. Другие системы должны иметь аналогичный код. Это дает преимущество использования той же настройки при отладке и производстве.
  • Вам действительно следует подумать об использовании надлежащей инфраструктуры ведения журналов (java.util.logging, Log4j или аналогичной). Это делает ваши настройки регистрации намного более гибкими. Среди многих преимуществ вы можете гибко настраивать (без изменений кода), куда должны идти ваши журналы.
1 голос
/ 31 августа 2009

Если вы работаете в UNIX, вы можете использовать tail -f logfile, чтобы увидеть строки, когда они записаны в ваш лог-файл

0 голосов
/ 31 августа 2009

В Linux и Windows (с установленным cygwin) я всегда использую log4j для входа в файл, а затем использую «tail» для его отображения. По умолчанию tail -f (и меньше -F) обновляется каждую секунду, что я считаю слишком медленным. Кроме того, часто есть несколько интересных файлов журналов, которые стоит посмотреть, и некоторые из них включают дату как часть их имени. Вот команда, которую я использую на одной из моих систем:

( cd /var/log/myapp/; tail -Fq --lines=0 -s 0.05 $(find . -type f -name "*$(date '+%Y-%m-%d').log" ) ) &

Это одновременно хвост каждого файла журнала в / var / log / myapp /, который содержит сегодняшнюю дату в имени файла. Очень удобно с журнальными файлами log4j. И -s 0,05 означает только паузу 0,05 секунды между проверками нового выхода.

0 голосов
/ 31 августа 2009

Если вам не нужна надлежащая структура ведения журнала

Стандартный способ Unix - перенаправить выходные потоки

т.е. запустить программу exex как exe> log перенаправит стандартный вывод в журнал но EXE самостоятельно оставит вывод на консоль.

Если вы хотите сделать это в программе, вам понадобится переменная для тестирования и перенаправить потоки только если не тестировать

...