- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
请注意大多数其他调用 Logger
调用是如何工作的,以及所有 System.out.println()
是如何工作的,但请有人向我解释为什么
调用永远不会与日志的其余部分一起打印,因为这些函数显然正在运行! ?对于 java12,甚至 stop()
和 destroy()
中的 >Logger.info()destroy()
也不会显示。这是一个错误吗?我使用它是否很奇怪,还是什么?
package test;
import java.util.logging.Logger;
public class Test {
private static Logger LOGGER = Logger.getLogger(Test.class.getCanonicalName());
public static void main(String[] args) {
System.out.println("main()");
LOGGER.info("main()");
new Test();
}
private Test() {
LOGGER.info("Test()");
System.out.println("Test()");
Runtime.getRuntime().addShutdownHook(new ShutdownThread());
}
public void shutdown() throws Exception {
LOGGER.info("shutdown()");
System.out.println("shutdown()");
stop();
destroy();
}
public void stop() throws Exception {
LOGGER.info("stop()");
System.out.println("stop()");
}
public void destroy() {
LOGGER.info("destroy()");
System.out.println("destroy()");
}
class ShutdownThread extends Thread {
ShutdownThread() {
super("app-shutdown-hook");
}
@Override
public void run() {
try {
shutdown();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Bye! 🙇♂️👋🖖");
}
}
}
使用 java 10 和 java 11 (OpenJDK) 的输出:
main()
Mar 14, 2020 1:53:59 PM test.Test main
INFO: main()
Mar 14, 2020 1:53:59 PM test.Test <init>
INFO: Test()
Test()
Mar 14, 2020 1:53:59 PM test.Test shutdown
INFO: shutdown()
shutdown()
stop()
destroy()
Bye! 🙇♂️👋🖖
使用 java 12 (OpenJDK) 输出:
main()
Mar 14, 2020 2:17:13 PM test.Test main
INFO: main()
Mar 14, 2020 2:17:13 PM test.Test <init>
INFO: Test()
Test()
shutdown()
stop()
destroy()
Bye! 🙇♂️👋🖖
最佳答案
此问题隐藏在:JDK-8161253 - LogManager$Cleaner() can prevent logging in other shutdown hooks .
每张票:
As a workaround to creating a custom shutdown hook you can create a custom handler and install it on the root logger. The first action of the LogManager$Cleaner is to close all the installed handlers on the logger. Once the cleaner calls the close on the custom handler you can then do one of the following:
这是解决方案#1:
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
public class Test {
private static Logger LOGGER = Logger.getLogger(Test.class.getCanonicalName());
public static void main(String[] args) {
System.out.println("main()");
LOGGER.info("main()");
new Test();
}
private Test() {
LOGGER.info("Test()");
System.out.println("Test()");
addShutdownHandler();
}
private void addShutdownHandler() {
Logger root = Logger.getLogger("");
Handler[] handlers = root.getHandlers();
for(Handler h : handlers) {
if (h.getClass() == ShutdownHandler.class) {
return;
}
}
for(Handler h : handlers) {
root.removeHandler(h);
}
root.addHandler(new ShutdownHandler());
for(Handler h : handlers) {
root.addHandler(h);
}
}
public void shutdown() throws Exception {
LOGGER.info("shutdown()");
System.out.println("shutdown()");
stop();
destroy();
}
public void stop() throws Exception {
LOGGER.info("stop()");
System.out.println("stop()");
}
public void destroy() {
LOGGER.info("destroy()");
System.out.println("destroy()");
}
class ShutdownHandler extends Handler {
ShutdownHandler() {
}
@Override
public void close() {
final Thread t = Thread.currentThread();
final String old = t.getName();
t.setName("app-shutdown-hook");
try {
shutdown();
System.out.println("Bye! 🙇♂️👋🖖");
} catch (Exception e) {
e.printStackTrace();
} finally {
t.setName(old);
}
}
@Override
public void flush() {
}
@Override
public void publish(LogRecord r) {
isLoggable(r);
}
}
}
解决方案 #2 变得很棘手,因为我们无法确保从一个关闭 Hook 启动了另一个关闭 Hook 。如果您想使用 Thread::join,这意味着需要额外的编码。因此,为了解决这个问题,我们只需使用 Future API:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.logging.ErrorManager;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
public class Test {
private static Logger LOGGER = Logger.getLogger(Test.class.getCanonicalName());
public static void main(String[] args) {
System.out.println("main()");
LOGGER.info("main()");
new Test();
}
private Test() {
LOGGER.info("Test()");
System.out.println("Test()");
addShutdownHandler();
}
private void addShutdownHandler() {
Logger root = Logger.getLogger("");
Handler[] handlers = root.getHandlers();
for(Handler h : handlers) {
if (h.getClass() == CleanerJoin.class) {
return;
}
}
for(Handler h : handlers) {
root.removeHandler(h);
}
root.addHandler(new CleanerJoin());
for(Handler h : handlers) {
root.addHandler(h);
}
}
public void shutdown() throws Exception {
LOGGER.info("shutdown()");
System.out.println("shutdown()");
stop();
destroy();
}
public void stop() throws Exception {
LOGGER.info("stop()");
System.out.println("stop()");
}
public void destroy() {
LOGGER.info("destroy()");
System.out.println("destroy()");
}
class ShutdownTask implements Callable<Void> {
ShutdownTask() {
}
@Override
public Void call() throws Exception {
shutdown();
System.out.println("Bye! 🙇♂️👋🖖");
return null;
}
}
class CleanerJoin extends Handler {
private final FutureTask<Void> sdt = new FutureTask<>(new ShutdownTask());
CleanerJoin() {
Runtime.getRuntime().addShutdownHook(new Thread(sdt, "app-shutdown-hook"));
}
@Override
public void close() {
boolean interrupted = false;
try {
for(;;) {
try { //Could use LogManager to lookup timeout values and use a timed join.
sdt.get();
break;
} catch (ExecutionException e) {
reportError("Shutdown hook failed.", e, ErrorManager.CLOSE_FAILURE);
break;
} catch (InterruptedException retry) {
interrupted = true;
}
}
} finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}
@Override
public void flush() {
}
@Override
public void publish(LogRecord r) {
isLoggable(r);
}
}
}
关于java - 为什么新的 Java Logger 在这里无法一致工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60687511/
作为一个新人中的菜鸡,最近在看一个项目的代码其中有这么一段看得我很是费解 public class AssembleMsgService { private static Logger logger
我已更改 Gradle 构建脚本以使用 Spring 2.0.1 而不是 1.5.9。当我运行 gradle build 时,出现错误:找不到符号 Logger logger = Logger.get
这是我的示例代码: public class Logs { private static Logs logHandler; public static Logs handler() {
我目前正在使用 Java 日志记录。我有一个记录器 cwh.A 和 cwh.B。是否可以通过 Java 从记录器 cwh 获取这些记录器,而不知道它们的名称? 最佳答案 可以通过日志管理器获取所有记录
在我的应用程序中,有一次我将 java.util.logging 的根 Logger 及其所有处理程序设置为 Level.FINEST,如下所示: Logger.getLogger("").setLe
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 7 年前。 Improv
我刚刚将 Java 插件升级到 1.7.0_25,这导致我几年前编写的一个小程序出现 fatal error (此后一直在维护)。 在小程序的 init() 方法的早期,我调用了 logger = L
logger.debug 和 logger.info 有什么区别? logger.debug什么时候打印? 最佳答案 我建议你看看这篇名为 "Short Introduction to log4j"
Fixed I tried reinstalling the plugin but that didn't work so i completely cleared my inteljii idea
我定义了一个记录器实例如下: private static final Logger LOGGER = Logger.getLogger(Main.class.getName()); 我有一个要记录的
我正在 Windows 下使用 Python 3.4.2。就我而言, import logging logger = logging.getLogger('logger') logger.setLev
我目前正在使用 C# 开发一个新的 Prism 项目,并想在我的 Bootstrapper 类中创建一个 NLog Logger。不幸的是,无论我做什么,它都拒绝构建,并告诉我... 'Logger.
我已经有几年没有使用 Log4J 了。我现在正在使用 org.jboss.logging 包在 JBoss 5 下开发一个应用程序。当我以前这样做时,将 logger.info() 消息包含在日志记录
ActiveRecord::Base.logger = Logger.new(STDOUT) 的 redis 等价物是什么?我想看看redis在做什么。 最佳答案 $redis.client.logg
我正在尝试使用 log4js 创建日志文件。完成所有配置后运行 Node app.js 时,我收到以下错误。 错误: TypeError: logger.setLevel is not a funct
我在一个拥有大约 50 多名开发人员的 IT 部门工作。它曾经有大约 100 多名开发人员,但由于经济衰退而被削减。 当我们的部门规模扩大时,我们雄心勃勃地努力建立一个特殊的架构小组。 这个小组决定做
我正在尝试找出跨多个模块使用 python 日志记录的最佳实践。我在这里看到:http://docs.python.org/2/howto/logging#logging-from-multiple-
我想将 Logger 注入(inject)到在 WildFly 10 上运行的 Maven 动态 Web 项目中的 bean 中。 我在 POM 中添加了依赖项。 WildFly 中提供了范围:
Java 9 引入了一个新的记录器,即 java.lang.System.Logger但我们总是有java.util.logging.Logger . 此记录器有什么新功能以及它有何改进? 最佳答案
我在 eclipse Mars 中配置了我的环境,但是 log4j 出现错误。我使用 spring 4 和 Maven 作为依赖管理器。部分代码: Eclipse 在这一行显示了一个错误,等于后的第二
我是一名优秀的程序员,十分优秀!