tom
tom

Reputation: 1223

Why each subsequent log entry is repeated (using java.util.logging)?

I have a test and I would like to log some information from the test. I manage to do that using basic java logger, but I'm doing something wrong. Each subsequent entry log message gets multiplied, ie. first message is logged once, second one two times, third one three times, etc. and I'm not sure what I'm doing wrong. The messages are pushed to the console also, but there only once.

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);
    }

}

My log file ends up like this :

entry one
entry two
entry two
entry three
entry three
entry three

I guess I'm messing something up with the file handler, but I don't know what.

Upvotes: 1

Views: 889

Answers (5)

user2969367
user2969367

Reputation:

The problem is because you are calling writeEntryToLogFile() multiple times and setting the fileHandler multiple times.

Move the 2 lines in the calling method as:

@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);
}

Upvotes: 2

davidxxx
davidxxx

Reputation: 131396

You add an handler each time you invoke writeEntryToLogFile().
So you have an additional duplicated output at each call.

You should add a setup method where you set the context for each executed test.
JUnit you are using allows it with the @Before annotation:

@Before
public void setup() {
    fh = new FileHandler("test.log", true);
    formatter = new SimpleFormatter();
    fh.setFormatter(formatter); 
    logger.addHandler(fh);
}

And as a side note, a testing method that asserts nothing doesn't make really sense.

Upvotes: 4

Norrey Okumu
Norrey Okumu

Reputation: 21

Just to elaborate on what Krishna Kuntala said, when you look at the Logger class, the add handler is adding on an ArrayList.

private final CopyOnWriteArrayList <Handler> handlers

Since you are calling the add handler the third time when you are on the entry three, it will log the same statement using the three handlers which output to the same file.

Upvotes: 1

Michael
Michael

Reputation: 44150

You're adding the same handler every time you add a message. You should only do this once. I suggest a static initialiser.

I've commented out the lines that you no longer need:

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);
    }
}

It's worth noting that writeEntryToLogFile is now a little bit pointless because it's only a single line. I'd get rid of that function.

Upvotes: 2

kk.
kk.

Reputation: 3945

Try moving below statements inside infoPackage() method

fh.setFormatter(formatter); logger.addHandler(fh);

As these are getting set multiple times because of method calls.

Upvotes: 3

Related Questions