将STDOUT复制到文件而不停止显示在屏幕上

时间:2009-08-31 09:46:37

标签: java stdout stderr

我正在制作的程序旨在无人值守运行,因此我已将stdout和stderr流重定向到日志文件。虽然这没有任何问题,但我仍在制作和调试软件,我希望它也显示在屏幕上。这可能吗?

重定向我使用的流

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

感谢。

7 个答案:

答案 0 :(得分:8)

是。记录框架(即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)更易于管理。当事情运行良好时提高日志级别并在没有部署调试版本时降低级别是很好的。

答案 1 :(得分:4)

或许有点粗糙,但你可以试试这个:

private static final isDebugMode = true;

...

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

或者,您可以编写自己的PrintStream实现,同时写入日志文件和屏幕。听起来你不需要这种行为,除了在开发中,所以后者虽然实际上对你的问题更准确的答案可能不是你真正想要的。

答案 2 :(得分:4)

如果您使用的是类Unix平台(Windows以外的任何平台),您可以使用tee程序:

java myprogram | tee output

这会将标准输出写入控制台以及名为output的文件。

答案 3 :(得分:2)

不,您的设置无法实现。可能的解决方案:

  • 使用某些软件监控日志文件。在Linux / Unix上,less有一个“跟随”模式(Shift-F),它跟踪日志文件。其他系统应该有类似的代码。这具有在调试和使用中使用相同设置的优点。生产。
  • 您应该考虑使用正确的日志框架(java.util.logging,Log4j或类似)。这使您的日志记录设置更加灵活。在许多优点中,您可以灵活地配置(无需更改代码)日志的位置。

答案 4 :(得分:1)

如果您使用的是UNIX,则可以使用tail -f logfile查看写入日志文件的行

答案 5 :(得分:0)

如果您不想要正确的日志框架

标准的Unix方法是重定向输出流

即运行程序exex as exe>日志 将stdout重定向到日志 但 可执行程序 单独将输出留给控制台。

如果你想在程序中执行此操作,则需要一个变量来测试,如果没有测试则只重定向流

答案 6 :(得分:0)

在Linux和Windows上(安装了cygwin)我总是使用log4j登录到文件,然后使用“tail”来显示它。默认情况下,tail -f(和less -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秒。