为什么每个后续日志条目都会重复(使用java.util.logging)?
我有一个测试,我想记录一些测试信息。我使用基本java logger成功地做到了这一点,但我做错了什么。每个后续条目日志消息都会成倍增加,即第一条消息记录一次,第二条消息记录两次,第三条消息记录三次,等等。我不确定我做错了什么。消息也被推送到控制台,但只有一次为什么每个后续日志条目都会重复(使用java.util.logging)?,java,java.util.logging,Java,Java.util.logging,我有一个测试,我想记录一些测试信息。我使用基本java logger成功地做到了这一点,但我做错了什么。每个后续条目日志消息都会成倍增加,即第一条消息记录一次,第二条消息记录两次,第三条消息记录三次,等等。我不确定我做错了什么。消息也被推送到控制台,但只有一次 public class MyExampleTest { private FileHandler fh = null; private static final Logger logger = Logger.getLogg
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(格式化程序);
记录器.addHandler(fh)代码>
由于方法调用,这些语句被多次设置。请尝试在infoPackage()方法中的语句下方移动
fh.setFormatter(格式化程序);
记录器.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
现在有点毫无意义,因为它只是一行。我会去掉这个函数。每次添加消息时,都会添加相同的处理程序。你应该只做一次。我建议使用静态初始化器
我已经注释掉了您不再需要的行:
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);
}
另一方面,断言没有任何东西的测试方法没有真正的意义。每次调用writeEntryToLogFile()
时,都会添加一个处理程序
因此,每次调用时都会有额外的重复输出
您应该添加一个设置方法,在其中为每个执行的测试设置上下文
您正在使用的JUnit允许它与@Before
注释一起使用:
@Before
public void setup() {
fh = new FileHandler("test.log", true);
formatter = new SimpleFormatter();
fh.setFormatter(formatter);
logger.addHandler(fh);
}
作为旁注,断言没有任何东西的测试方法没有真正的意义。请详细说明Krishna Kuntala所说的,当您查看该类时,add处理程序正在添加一个
private final CopyOnWriteArrayList处理程序
由于第三次调用add处理程序是在条目3上,因此它将使用输出到同一文件的三个处理程序记录同一条语句。只是为了详细说明Krishna Kuntala所说的,当您查看该类时,add处理程序是在
private final CopyOnWriteArrayList处理程序
由于您在条目3上第三次调用add处理程序,因此它将使用输出到同一文件的三个处理程序记录相同的语句。问题在于您多次调用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);
}
问题是因为您多次调用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);
}
作为进一步的补充说明,打印大量文本的测试方法可能会很烦人,并且会降低测试速度。这是一种selenium测试。它确实有用,但我从代码中删掉了它,因为它与我所面临的问题无关。这不是很多文本,但我想有一些随机生成的值记录下来。无论如何,您的解决方案看起来不错,但它抛出了一个空指针。我猜这是因为文件处理程序是在@test?@tom中稍后声明的。您的操作是正确的。它使问题更加明显。现在,为了指示切割代码,添加…
更好。否则,您是对的。fh=newfilehandler(“test.log”,true)代码>应在setup()方法中执行。我更新为正确。“一些随机生成的值记录”在测试中不使用随机生成的值。当您的测试失败时,您需要相当确定这是因为某些内容被破坏或更改,而不是因为您正在测试的内容发生了更改。另外,打印大量文本的测试方法可能会很烦人,也会减慢您的测试速度。这是一种selenium测试。它确实有用,但我从代码中删掉了它,因为它与我所面临的问题无关。这不是很多文本,但我想有一些随机生成的值记录下来。无论如何,您的解决方案看起来不错,但它抛出了一个空指针。我猜这是因为文件处理程序是在@test?@tom中稍后声明的。您的操作是正确的。它使问题更加明显。现在,为了指示切割代码,添加…
更好。否则,您是对的。fh=newfilehandler(“test.log”,true)代码>应在setup()方法中执行。我更新为正确。“一些随机生成的值记录”在测试中不使用随机生成的值。当你的测试失败时,你要相当确定这是因为某些东西被破坏或改变了,而不是因为你正在测试的东西改变了。