为什么每个后续日志条目都会重复(使用 java.util.logging)?
Why each subsequent log entry is repeated (using java.util.logging)?
我有一个测试,我想记录一些测试信息。我设法使用基本的 java 记录器做到了这一点,但我做错了。每个后续条目日志消息都会成倍增加,即。第一条消息被记录一次,第二条被记录两次,第三条被记录三次,等等,我不确定我做错了什么。消息也被推送到控制台,但只有一次。
public class MyExampleTest {
private FileHandler fh = null;
private static final Logger logger = Logger.getLogger(MyExampleTest.class.getName());
SimpleFormatter formatter = new SimpleFormatter();
@Test
public void infoPackage() throws Exception {
fh = new FileHandler("test.log", true);
// do some test stuff
writeEntryToLogFile("entry one");
// do some more test stuff
writeEntryToLogFile("entry two");
// do even more test stuff
writeEntryToLogFile("entry three");
}
private void writeEntryToLogFile(String message) throws Exception {
fh.setFormatter(formatter);
logger.addHandler(fh);
logger.info(message);
}
}
我的日志文件最终是这样的:
entry one
entry two
entry two
entry three
entry three
entry three
我想我把文件处理程序弄乱了,但我不知道是什么。
尝试在 infoPackage()
方法中移动下面的语句
fh.setFormatter(formatter);
logger.addHandler(fh);
由于方法调用,这些设置被多次设置。
您每次添加消息时都会添加相同的处理程序。你应该只做一次。我建议使用静态初始化程序。
我已经注释掉了您不再需要的行:
public class MyExampleTest {
//private FileHandler fh = null;
private static final Logger logger;
//SimpleFormatter formatter = new SimpleFormatter();
static {
logger = Logger.getLogger(MyExampleTest.class.getName());
FileHandler fh = new FileHandler("test.log", true);
fh.setFormatter(new SimpleFormatter());
logger.addHandler(fh);
}
@Test
public void infoPackage() throws Exception {
//fh = new FileHandler("test.log", true);
// do some test stuff
writeEntryToLogFile("entry one");
// do some more test stuff
writeEntryToLogFile("entry two");
// do even more test stuff
writeEntryToLogFile("entry three");
}
private void writeEntryToLogFile(String message) throws Exception {
//fh.setFormatter(formatter);
//logger.addHandler(fh);
logger.info(message);
}
}
值得注意的是,writeEntryToLogFile
现在有点毫无意义,因为它只有一行。我会摆脱那个功能。
每次调用 writeEntryToLogFile()
时添加一个处理程序。
所以每次调用都会有一个额外的重复输出。
您应该添加一个设置方法,您可以在其中为每个执行的测试设置上下文。
您使用的 JUnit 允许使用 @Before
注释:
@Before
public void setup() {
fh = new FileHandler("test.log", true);
formatter = new SimpleFormatter();
fh.setFormatter(formatter);
logger.addHandler(fh);
}
附带说明一下,不断言任何内容的测试方法没有任何意义。
只是详细说明 Krishna Kuntala 所说的话,当您查看 Logger class, the add handler is adding on an ArrayList。
private final CopyOnWriteArrayList <Handler> handlers
由于您是在条目三上第三次调用添加处理程序,因此它将使用输出到同一文件的三个处理程序记录相同的语句。
问题是因为您多次调用 writeEntryToLogFile()
并多次设置 fileHandler
。
将调用方法中的两行移动为:
@Test
public void infoPackage() throws Exception {
fh = new FileHandler("test.log", true);
fh.setFormatter(formatter);
logger.addHandler(fh);
// do some test stuff
writeEntryToLogFile("entry one");
// do some more test stuff
writeEntryToLogFile("entry two");
// do even more test stuff
writeEntryToLogFile("entry three");
}
private void writeEntryToLogFile(String message) throws Exception {
logger.info(message);
}
我有一个测试,我想记录一些测试信息。我设法使用基本的 java 记录器做到了这一点,但我做错了。每个后续条目日志消息都会成倍增加,即。第一条消息被记录一次,第二条被记录两次,第三条被记录三次,等等,我不确定我做错了什么。消息也被推送到控制台,但只有一次。
public class MyExampleTest {
private FileHandler fh = null;
private static final Logger logger = Logger.getLogger(MyExampleTest.class.getName());
SimpleFormatter formatter = new SimpleFormatter();
@Test
public void infoPackage() throws Exception {
fh = new FileHandler("test.log", true);
// do some test stuff
writeEntryToLogFile("entry one");
// do some more test stuff
writeEntryToLogFile("entry two");
// do even more test stuff
writeEntryToLogFile("entry three");
}
private void writeEntryToLogFile(String message) throws Exception {
fh.setFormatter(formatter);
logger.addHandler(fh);
logger.info(message);
}
}
我的日志文件最终是这样的:
entry one
entry two
entry two
entry three
entry three
entry three
我想我把文件处理程序弄乱了,但我不知道是什么。
尝试在 infoPackage()
方法中移动下面的语句
fh.setFormatter(formatter);
logger.addHandler(fh);
由于方法调用,这些设置被多次设置。
您每次添加消息时都会添加相同的处理程序。你应该只做一次。我建议使用静态初始化程序。
我已经注释掉了您不再需要的行:
public class MyExampleTest {
//private FileHandler fh = null;
private static final Logger logger;
//SimpleFormatter formatter = new SimpleFormatter();
static {
logger = Logger.getLogger(MyExampleTest.class.getName());
FileHandler fh = new FileHandler("test.log", true);
fh.setFormatter(new SimpleFormatter());
logger.addHandler(fh);
}
@Test
public void infoPackage() throws Exception {
//fh = new FileHandler("test.log", true);
// do some test stuff
writeEntryToLogFile("entry one");
// do some more test stuff
writeEntryToLogFile("entry two");
// do even more test stuff
writeEntryToLogFile("entry three");
}
private void writeEntryToLogFile(String message) throws Exception {
//fh.setFormatter(formatter);
//logger.addHandler(fh);
logger.info(message);
}
}
值得注意的是,writeEntryToLogFile
现在有点毫无意义,因为它只有一行。我会摆脱那个功能。
每次调用 writeEntryToLogFile()
时添加一个处理程序。
所以每次调用都会有一个额外的重复输出。
您应该添加一个设置方法,您可以在其中为每个执行的测试设置上下文。
您使用的 JUnit 允许使用 @Before
注释:
@Before
public void setup() {
fh = new FileHandler("test.log", true);
formatter = new SimpleFormatter();
fh.setFormatter(formatter);
logger.addHandler(fh);
}
附带说明一下,不断言任何内容的测试方法没有任何意义。
只是详细说明 Krishna Kuntala 所说的话,当您查看 Logger class, the add handler is adding on an ArrayList。
private final CopyOnWriteArrayList <Handler> handlers
由于您是在条目三上第三次调用添加处理程序,因此它将使用输出到同一文件的三个处理程序记录相同的语句。
问题是因为您多次调用 writeEntryToLogFile()
并多次设置 fileHandler
。
将调用方法中的两行移动为:
@Test
public void infoPackage() throws Exception {
fh = new FileHandler("test.log", true);
fh.setFormatter(formatter);
logger.addHandler(fh);
// do some test stuff
writeEntryToLogFile("entry one");
// do some more test stuff
writeEntryToLogFile("entry two");
// do even more test stuff
writeEntryToLogFile("entry three");
}
private void writeEntryToLogFile(String message) throws Exception {
logger.info(message);
}