为什么每个后续日志条目都会重复(使用 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);
}