我正在制作的程序设计为无人值守运行,因此我已将 stdout 和 stderr 流重定向到日志文件。虽然这没有任何问题,但我仍在制作和调试软件,我希望它也能在屏幕上显示。这可能吗?
重定向我使用过的流
System.setErr(logWriter);
System.setOut(logWriter);
谢谢。
是的。日志框架(即 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)
. 当事情运行良好时提高日志级别并在不部署调试版本的情况下降低日志级别是很棒的。
也许有点粗糙,但你可以试试这个:
private static final isDebugMode = true;
...
if (!isDebugMode) {
System.setErr(logWriter);
System.setOut(logWriter);
}
或者,您可以编写自己的 PrintStream 实现,该实现同时写入您的日志文件和屏幕。听起来你不需要这种行为,除非在开发中,所以后者虽然实际上对你的问题的更准确的答案可能不是你真正想要的。
不,使用您的设置这是不可能的。可能的解决方案:
less
有一个“跟随”模式 (Shift-F),用于跟踪日志文件。其他系统应该有类似的代码。这具有在调试和生产中使用相同设置的优势。如果您在 UNIX 上,您可以使用tail -f logfile
查看写入日志文件的行
如果你不想要一个合适的日志框架
标准的 Unix 方式是重定向输出流
即以 exe > log 运行程序 exex 会将 stdout 重定向到 log 但 exe 本身会将输出留给控制台。
如果您想在程序中执行此操作,您将需要一个变量来测试,如果不测试则只重定向流
在 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 秒。