为什么java.util.logging在我记录消息时显示错误的类



我正在测试java.util.logging,当我记录消息时,它显示了错误的类。这是我的代码:

我有一个界面MyLogger:

package ptest2;
public interface MyLogger {
public void info(String message);
}

我有一个实现类MyLoggerImpl,它使用java.util.logging:实现接口MyLogger

package ptest2;
import java.util.logging.Logger;
public class MyLoggerImpl implements MyLogger { 
private Logger logger;
public MyLoggerImpl(String name) {
logger = Logger.getLogger(name);
}   
@Override
public void info(String message) {
logger.info(message);
}
}

我有一个类MyLoggerFactory,它有一个静态方法,接受String name参数并给出MyLogger:

package ptest2;
public class MyLoggerFactory {
public static MyLogger getMyLogger(String name) {
MyLogger myLogger = new MyLoggerImpl(name);
return myLogger;
}
}

现在我创建了一个类ClientClass2,它使用日志记录。它有一个显示INFO级别消息的方法:

package ptest2;
public class ClientClass2 {
private static MyLogger LOGGER = MyLoggerFactory.getMyLogger("ClientClass2");
public void method2() {
LOGGER.info("This is INFO level message");
}
}

为了测试它,我创建了一个类TestLoggingClientClass2:

package ptest2;
public class TestLoggingClientClass2 {
public static void main(String[] args) {
ClientClass2 clientClass2 = new ClientClass2();
clientClass2.method2();
}
}

我运行它,这就是我得到的:

2015年4月10日下午12:17:18 ptest2.MyLoggerImpl信息
信息:这是信息液位信息

但这是我应该得到的:

2015年4月10日下午12:17:18 ptest2.ClientClass2信息
信息:这是信息液位信息

我认为代码没有任何问题。我做错了什么?如何获得所需的结果?

更新

其他问题是格式化邮件。但我对消息的格式没意见。我担心的是为什么消息显示错误的类。

我已经看了java.util.logging的源代码(感谢Oracle)。

该消息采用SimpleFormatter类的public synchronized String format(LogRecord record)方法进行格式化。对于类名,此方法使用相关LogRecordsourceClassName属性;并且只有当该属性为空时,它才使用相关CCD_ 12 的CCD_

Logger类中,当调用public void info(String msg)方法时,它会设置相关LogRecordloggerName属性。

Logger类中,当调用public void logp(Level level, String sourceClass, String sourceMethod, String msg)方法时,它会设置相关LogRecordsourceClassName属性

所以在MyLoggerImpl类中,而不是我调用

@Override
public void info(String message) {
logger.info(message);
}

我换成

@Override
public void info(String message) {
logger.logp(Level.INFO, logger.getName(), "info", message);
}

它起作用了。奇怪的你们怎么看?

java.util.logging.Logger是从MyLoggerImpl调用的,这就是打印其名称的原因。要检查这一点,您可以直接从ClientClass2使用它进行测试,然后(并且只有在那时)它才会打印ptest2.ClientClass2

顺便说一句,我不知道你为什么要创建自己的Logger API,看看slf2j或logback,没有必要重新发明轮子。

更新:您已经更新了记录器以使用logger name,其中class name应作为logp方法的参数,因此它将根据当前日志记录模式进行打印。你可以遵循这种方法,也可以改变模式。在前一种情况下,您可以更改MyLoggerFactory以接受Class<?>参数:

public static MyLogger getMyLogger(Class<?> clazz) {
return new MyLoggerImpl(clazz.getSimpleName());
}

最新更新