java.util.logging.Logger:"timeout" 后文件扩展名的增量
java.util.logging.Logger: increment of file-extension after a "timeout"
我正在使用 java.util.logging.Logger 并将其包装在一个单例中。所以我可以在我的程序中(也在线程中)以一种很好的方式访问它。
import java.util.logging.*;
import java.io.*;
public class LogTest
{
public static void init () throws Exception
{
LogManager.getLogManager().reset ();
}
public static Logger get () throws Exception
{
Logger l = LogManager.getLogManager ().getLogger ("test");
if (l == null)
{
l = Logger.getLogger ("test");
FileHandler fh = new FileHandler ("test.log", 100000, 1, true);
l.addHandler (fh);
l.setLevel (Level.parse ("INFO"));
}
return l;
}
}
我认为这比全局引用或传递引用要好得多。
我在我的main.c中一开始就调用了LogTest.init()。
然后我在需要记录的任何地方调用 LogTest.get () 。哪怕是一个线程。
LogTest.get().info ("blabla");
效果很好。但是我认识到,在 1-2 分钟后,当我没有将一些行打印到日志文件时,文件扩展名增加了 1。
test.log -> test.log.1
....
test.log.1 -> test.log.2
我希望只有文件大小超过最大值(100k 的 FileHandler)
知道这是与线程还是 FileHandler 相关的问题吗?为什么会有这种行为?我不希望更改日志文件。
与您的问题无关,您的代码更像是 class 具有静态方法,而不是单例。
来自When is a singleton not a singleton:
The Singleton is a useful Design Pattern for allowing only one
instance of your class, but common mistakes can inadvertently allow
more than one instance to be created.
使用您的代码,您仍然可以根据需要多次调用 new LogTest()
,因此允许创建超过 one
个实例。
你的单例代码看起来像这样:
public class LogTest {
private static LogTest theInstance;
private LogTest() {
LogManager.getLogManager().reset();
}
public static synchronized LogTest getInstance() {
if(theInstance == null) {
theInstance = new LogTest();
}
return theInstance;
}
public Logger getLogger() throws Exception {
Logger l = LogManager.getLogManager().getLogger("test");
if (l == null) {
l = Logger.getLogger("test");
FileHandler fh = new FileHandler("test.log", 100000, 1, true);
l.addHandler(fh);
l.setLevel(Level.parse("INFO"));
}
return l;
}
}
何时使用:
LogTest.getInstance().getLogger().log(...);
发生这种情况的原因可能在于:
It is also important to note that the Logger associated with the String name may be garbage collected at any time if there is no strong reference to the Logger. The caller of this method must check the return value for null in order to properly handle the case where the Logger has been garbage collected.
由于您在一分钟或几分钟内没有访问记录器,并且您的代码中没有对记录器对象的引用,它可能已被垃圾收集,当您稍后调用 getLogger()
时,它可能 returns null.
如果@Mark 有一个合适的 Singleton 作为指针,它就不会被垃圾回收。
我正在使用 java.util.logging.Logger 并将其包装在一个单例中。所以我可以在我的程序中(也在线程中)以一种很好的方式访问它。
import java.util.logging.*;
import java.io.*;
public class LogTest
{
public static void init () throws Exception
{
LogManager.getLogManager().reset ();
}
public static Logger get () throws Exception
{
Logger l = LogManager.getLogManager ().getLogger ("test");
if (l == null)
{
l = Logger.getLogger ("test");
FileHandler fh = new FileHandler ("test.log", 100000, 1, true);
l.addHandler (fh);
l.setLevel (Level.parse ("INFO"));
}
return l;
}
}
我认为这比全局引用或传递引用要好得多。
我在我的main.c中一开始就调用了LogTest.init()。 然后我在需要记录的任何地方调用 LogTest.get () 。哪怕是一个线程。
LogTest.get().info ("blabla");
效果很好。但是我认识到,在 1-2 分钟后,当我没有将一些行打印到日志文件时,文件扩展名增加了 1。
test.log -> test.log.1 .... test.log.1 -> test.log.2
我希望只有文件大小超过最大值(100k 的 FileHandler)
知道这是与线程还是 FileHandler 相关的问题吗?为什么会有这种行为?我不希望更改日志文件。
与您的问题无关,您的代码更像是 class 具有静态方法,而不是单例。
来自When is a singleton not a singleton:
The Singleton is a useful Design Pattern for allowing only one instance of your class, but common mistakes can inadvertently allow more than one instance to be created.
使用您的代码,您仍然可以根据需要多次调用 new LogTest()
,因此允许创建超过 one
个实例。
你的单例代码看起来像这样:
public class LogTest {
private static LogTest theInstance;
private LogTest() {
LogManager.getLogManager().reset();
}
public static synchronized LogTest getInstance() {
if(theInstance == null) {
theInstance = new LogTest();
}
return theInstance;
}
public Logger getLogger() throws Exception {
Logger l = LogManager.getLogManager().getLogger("test");
if (l == null) {
l = Logger.getLogger("test");
FileHandler fh = new FileHandler("test.log", 100000, 1, true);
l.addHandler(fh);
l.setLevel(Level.parse("INFO"));
}
return l;
}
}
何时使用:
LogTest.getInstance().getLogger().log(...);
发生这种情况的原因可能在于:
It is also important to note that the Logger associated with the String name may be garbage collected at any time if there is no strong reference to the Logger. The caller of this method must check the return value for null in order to properly handle the case where the Logger has been garbage collected.
由于您在一分钟或几分钟内没有访问记录器,并且您的代码中没有对记录器对象的引用,它可能已被垃圾收集,当您稍后调用 getLogger()
时,它可能 returns null.
如果@Mark 有一个合适的 Singleton 作为指针,它就不会被垃圾回收。