Selenium many Logs (How to remove)
You have to pin your loggers in memory or setup a logging.properties
config file. From the java.util.logging.Logger docs:
Logger objects may be obtained by calls on one of the getLogger factory methods. These will either create a new Logger or return a suitable existing Logger. It is important to note that the Logger returned by one of the getLogger factory methods may be garbage collected at any time if a strong reference to the Logger is not kept.
When a new logger is returned the log level is determined by the LogManager which by default uses settings from a logging.properties
file. In your example, it is possible to see the following:
- Call to getLogger creates a new logger and sets level from LogManager.
- Your code sets the logger level to OFF.
- G.C. runs and destroys your logger along with settings you just applied.
- Selenium calls getLogger and creates a new logger and sets level from LogManager.
Here is an example test case to prove the point:
public static void main(String[] args) { String name = "com.gargoylesoftware.htmlunit"; for (int i = 0; i < 5; i++) { System.out.println(Logger.getLogger(name).getLevel()); Logger.getLogger(name).setLevel(Level.OFF); System.runFinalization(); System.gc(); System.runFinalization(); Thread.yield(); } }
Which will output null
instead of OFF
.
If you pin your logger by holding a strong reference then step #3 never happens and Selenium should instead find the logger you created which has the level set to OFF.
private static final Logger[] pin;static { pin = new Logger[]{ Logger.getLogger("com.gargoylesoftware.htmlunit"), Logger.getLogger("org.apache.commons.httpclient"), Logger.getLogger("org.openqa.selenium.remote.ProtocolHandshake") }; for (Logger l : pin) { l.setLevel(Level.OFF); }}