我想以编程方式配置我的 java.util.logging.Logger
。根据Oracle Docs , 这似乎是可能的。
但是这个例子表明这里有问题:
public static void main(String[] args) {
Logger logger = Logger.getLogger("org.acme.project");
logger.setLevel(Level.SEVERE);
logger = null;
System.gc();
logger = Logger.getLogger("org.acme.project");
logger.warning("You shouldn't see this warning!");
logger.severe("But this error!");
}
如果您运行代码,您将看到这两条消息。但是,如果您删除 logger = null;
或 System.gc();
您只会看到正确的第二个,这证明垃圾收集器只是删除了配置的记录器Logger.getLogger(String)
创建一个新的(默认)。
为了“解决”这个问题,我可以只在某处保留对该特定记录器的引用,但我认为这不是一个好主意。
那么如何以编程方式定义记录器?
最佳答案
To "solve" this, I could just hold a reference to that particular logger somewhere, but I don't think that's a good idea.
在 JDK6u18 之前的版本中LogManager 持有对记录器的强烈引用。在那个补丁之后,java.util.logging.Logger.getLogger()方法指向读者持有一个强有力的引用:
Note: The LogManager may only retain a weak reference to the newly created Logger. It is important to understand that a previously created Logger with the given name may be garbage collected at any time if there is no strong reference to the Logger. In particular, this means that two back-to-back calls like getLogger("MyLogger").log(...) may use different Logger objects named "MyLogger" if there is no strong reference to the Logger named "MyLogger" elsewhere in the program.
一个常见的习语是使用:
private static final String CLASS_NAME = Foo.class.getName();
private static final Logger logger = Logger.getLogger(CLASS_NAME);
你定义 CLASS_NAME
的原因是你将把它用于日志跟踪方法或 logp
方法
此外,像 FindBugs 这样的工具会检测到这种丢失的记录器模式:
LG: Potential lost logger changes due to weak reference in OpenJDK (LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE)
关于java - 以编程方式配置记录器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43541482/