System.setErr() 干扰 Logger

2024-02-18

在较大的程序中,我使用静态java.util.logging.Logger实例,但重定向System.err连续到几个不同的文件。这Logger第二次尝试重定向时无法记录System.err.

这是一个显示问题的测试程序:

import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.logging.Logger;

class TestRedirect {
    static final Logger logger = Logger.getLogger("test");

    public static void main(String[] args) throws FileNotFoundException {
        for (int i = 1; i <= 2; i++) {
            TestRedirect ti = new TestRedirect();
            ti.test(i);
        }
    }

    void test(int i) throws FileNotFoundException {
        PrintStream filePrintStream = new PrintStream("test" + i + ".log");
        PrintStream stderr = System.err; // Save stderr stream.
        System.setErr(filePrintStream);  // Redirect stderr to file.
        System.err.println("about to log " + i);
        logger.info("at step " + i);
        System.setErr(stderr);           // Restore stderr stream.
        filePrintStream.close();
    }
}

这是输出:

测试1.log:

about to log 1
Jan 28, 2014 4:34:20 PM TestRedirect test
INFO: at step 1

测试2.日志:

about to log 2

我以为我会看到一个Logger- 生成的消息测试2.log以及。为什么Logger停止工作,我能做些什么呢?


默认情况下,JRE 配置为在根记录器上加载 ConsoleHandler。默认情况下,您的日志消息将传输到根记录器处理程序。根记录器处理程序是按需加载的。在您当前的程序中,根记录器 ConsoleHandler 的延迟加载正在捕获您的第一个重定向的 System.err。之后,根记录器处理程序永远不会重新加载,这就是为什么您永远不会在日志 2 中看到日志消息的原因。加上第一个重定向流已关闭,因此现在根 ConsoleHandler 正在写入关闭的流。

为了证明这一点,请将以下内容添加为测试用例主方法的第一行并运行该程序。

Logger.getLogger("").getHandlers(); //Force load root logger handlers.
Logger.getLogger("").removeHandler((Handler) null);

您会看到现在没有记录任何记录器消息。如果您好奇为什么会这样,您可以阅读java.util.logging.LogManager$RootLogger源代码了解详细信息。

你需要做的是创建一个流处理器 http://docs.oracle.com/javase/7/docs/api/java/util/logging/StreamHandler.html使用重定向的 System.err 流,然后add http://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#addHandler%28java.util.logging.Handler%29 and remove http://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#removeHandler%28java.util.logging.Handler%29来自记录器的 StreamHandler。您还可以切换使用父处理程序 http://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#setUseParentHandlers%28boolean%29在您的记录器配置上以避免写入原始 System.err。

Another possible solution would be to find all ConsoleHandler instances. Remove and close all of them. Perform the remap System.err. Then create and attach new ConsoleHandlers.

JDK 方面,ConsoleHandler 和 ErrorManager 应该被设计为使用java.io.FileDescriptor http://docs.oracle.com/javase/7/docs/api/java/io/FileDescriptor.html永远不会被重定向。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

System.setErr() 干扰 Logger 的相关文章

  • 如何在由子控件组成的 SWT 复合材料上跟踪鼠标?

    我创建了自己的控件 我想跟踪鼠标并添加一个MouseTrackListener 很遗憾MouseEnter and MouseLeave当鼠标移动到我的合成部分 即标签和按钮 上时 也会生成事件 Mouse enter mouse ente
  • java.lang.ClassNotFoundException:javax.mail.MessagingException

    我想使用 eclipse 将电子邮件从我的 gmail 帐户发送到另一个邮件帐户 我使用 apache tomcat 7 0 34 作为我的 Web 服务器 并使用端口 8080 作为 apache 服务器 HTTP 1 1 并使用 JRE
  • 如何在java中将数组值排序为循环格式?

    我的数组值如下 String value 1 2 3 4 5 6 7 8 9 10 假设如果我将值 5 传递给 tat 数组 它应该按如下顺序排序 5 6 7 8 9 10 1 2 3 4 怎么办 有人帮忙吗 感谢你 你需要的就是所谓的轮换
  • Thymeleaf 3 Spring 5 映射加载字符串而不是 HTML

    我正在尝试将 Spring 5 和 Thymeleaf 3 一起配置 我正在 Eclipse 上工作 我使用 全新安装 构建并使用 springboot run 运行应用程序 我已经设置了一个控制器和几个模板 但 Thymeleaf 似乎找
  • Runtime.exec 处理包含多个空格的参数

    我怎样才能进行以下运行 public class ExecTest public static void main String args try Notice the multiple spaces in the argument Str
  • 提供节点名或服务名,或未知 Java

    最近我尝试运行我的 Java 项目 每当我运行它并将其打开到我得到的服务器地址时 Unable to determine host name java net UnknownHostException Caused by java net
  • 如何在 Spring 中使 @PropertyResource 优先于任何其他 application.properties ?

    我正在尝试在类路径之外添加外部配置属性资源 它应该覆盖任何现有的属性 但以下方法不起作用 SpringBootApplication PropertySource d app properties public class MyClass
  • 如何使用 JMagick 转换色彩空间?

    如何使用 JMagick API 转换色彩空间 例如 CMYK gt RGB 和 RGB gt CMYK None
  • 提高 PostgreSQL 1 亿数据左连接查询性能

    我在用Postgresql 9 2 version Windows 7 64 bit RAM 6GB 这是一个Java企业项目 我必须在我的页面中显示订单相关信息 有三个表通过左连接连接在一起 Tables TV HD 389772 行 T
  • 在Java中运行bat文件并等待

    您可能会认为从 Java 启动 bat 文件是一项简单的任务 但事实并非如此 我有一个 bat 文件 它对从文本文件读取的值循环执行一些 sql 命令 它或多或少是这样的 FOR F x in CD listOfThings txt do
  • 蓝牙发送和接收文本数据

    我是 Android 开发新手 我想制作一个使用蓝牙发送和接收文本的应用程序 我得到了有关发送文本的所有内容逻辑工作 但是当我尝试在手机中测试它时 我看不到界面 这是Main Activity Code import android sup
  • 不可变的最终变量应该始终是静态的吗? [复制]

    这个问题在这里已经有答案了 在java中 如果一个变量是不可变的并且是final的 那么它应该是一个静态类变量吗 我问这个问题是因为每次类的实例使用它时创建一个新对象似乎很浪费 因为无论如何它总是相同的 Example 每次调用方法时都会创
  • hibernate 6.0.2.Final 和 spring boot 2.7.0 的entityManagerFactory bean 未配置问题

    所以最近我想升级我的 Spring Boot 项目项目的一些依赖项 特别是这些组件 雅加达 EE 9 弹簧靴2 7 休眠 6 0 2 Final 完成此操作后 所有更新和代码折射 更新将 javax 导入到 jakarta 以及一些 hib
  • 将 JScrollPane 添加到 JFrame

    我有一个关于向 Java 框架添加组件的问题 我有一个带有两个按钮的 JPanel 和一个添加了 JTable 的 JScrollPane 我想将这两个添加到 JFrame 中 我可以将 JPanel 添加到 JFrame 或将 JScro
  • Hibernate 本机查询 - char(3) 列

    我在 Oracle 中有一个表 其中列 SC CUR CODE 是 CHAR 3 当我做 Query q2 em createNativeQuery select sc cur code sc amount from sector cost
  • java XMLSerializer 避免复杂的空元素

    我有这个代码 DocumentBuilderFactory factory DocumentBuilderFactory newInstance DocumentBuilder builder factory newDocumentBuil
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • Spring RESTful控制器方法改进建议

    我是 Spring REST 和 Hibernate 的新手 也就是说 我尝试组合一个企业级控制器方法 我计划将其用作未来开发的模式 您认为可以通过哪些方法来改进 我确信有很多 RequestMapping value user metho
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐