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

发布于 2024-08-03 05:29:04 字数 209 浏览 5 评论 0原文

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

重定向我使用过的流,

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

谢谢。

The program I am making is designed to be run unattended, because of this I have redirected the stdout and stderr streams to a log file. While this works without any problems, while I am still making and debugging the software I would like it to show on the screen as well. Is this possible?

To redirect the streams I have used

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

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

挽梦忆笙歌 2024-08-10 05:29:04

是的。日志框架(即 log4j)是最好的,isDebugMode 在开发环境中很方便但是如果您确实需要“tee”您的标准输出,您可以这样做。

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) 更易于管理。在不部署调试版本的情况下,当事情运行良好时提高日志级别并在运行不佳时降低日志级别是非常好的。

Yes. Logging frameworks (i.e. log4j) are best, isDebugMode is handy in a development environment but if you really need to "tee" your stdout you can like so.

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

You'll soon find LOG.somelevel(msg) much more manageable than System.out.println(msg). It is great to raise the log level when things are working well and lower the level when they aren't without deploying a debug build.

输什么也不输骨气 2024-08-10 05:29:04

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

private static final isDebugMode = true;

...

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

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

a bit crude perhaps, but you could try this:

private static final isDebugMode = true;

...

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

Alternatively you could write your own PrintStream implementation which simultaneously writes to both your log file and the screen. It doesn't sound like you need this behaviour except in development though so the latter whilst actually a more accurate answer to your question is probably not what you actually want.

两相知 2024-08-10 05:29:04

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

java myprogram | tee output

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

If you're on a Unix-like platform (anything except Windows) you can use the tee program:

java myprogram | tee output

This will write the standard output to the console as well as the file called output.

冰火雁神 2024-08-10 05:29:04

不,根据您的设置,这是不可能的。可能的解决方案:

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

No, with your setup this is not possible. Possible solutions:

  • Use some software to monitor the log file. On Linux/Unix, less has a "follow"-mode (Shift-F), which tracks the log file. Other systems should have similar code. This has the advantage of using the same setup in debugging & production.
  • You should really consider using a proper logging framework (java.util.logging, Log4j or similar). This makes your logging setup much more flexible. Among many advantages, you can flexibly configure (without code changes), where your logs should go.
苏别ゝ 2024-08-10 05:29:04

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

If you're on UNIX you could use tail -f logfile to see lines as they are written to your logfile

沒落の蓅哖 2024-08-10 05:29:04

如果你不需要合适的日志框架,

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

,即运行程序 exex
执行程序>日志
将重定向标准输出到日志

EXE文件
其本身会将输出留在控制台。

如果您想在程序中执行此操作,则需要一个变量来测试,并且仅在不测试时重定向流

If you don't want a proper logging framework

Standard Unix way is to redirect the output streams

ie run the program exex as
exe > log
will redirect stdout to log
but
exe
on its own will leave the output to the console.

If you want to do this in the program you would need a variable to test on and only redirect the streams if not testing

久隐师 2024-08-10 05:29:04

在 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 秒。

On both Linux and Windows (with cygwin installed) I always use log4j to log to a file and then use "tail" to display it. By default, tail -f (and less -F) update every second which I find too slow. Also, there are often several interesting log files that are worth looking at, and some of them include the date as part of their name. Here's the command I use on one of my systems:

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

This simultaneously tails each log file under /var/log/myapp/ which contains today's date in the file name. Very handy with log4j rolling log files. And -s 0.05 means only pause 0.05 seconds between checks for new output.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文