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);
}
}
Remove console logs from selenium webdriver
Generally, logging could be implemented using different libraries and each one of them should be controlled separately. It seems that PhantomJS is using java.util.logging
so you can try doing:
LogManager.getLogManager().reset();
This should switch off all logging that comes from java.util.logging
.
How to disable logging after migration to Selenium 4
If you are using logback for logging purpose, then create logback.xml
configuration file under src/main/resources
as below:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOGS" value="./logs" />
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>
%d{yyyy-MM-dd HH:mm.ss} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="Console" />
</root>
</configuration>
So basically setting the root level as "info" will solve the issue. Selenium 4 by default prints with root level as "debug".
How to disable cutting logs by selenium Chromedriver?
From my point of view, looking at the chromedriver sources, it is not possible.
I can't see the way to override this behaviour.
Truncation is made by chromedriver itself. If logged value is string - it's getting truncated to 200 chars, see partial sources below. FormatValueForDisplay
is calling TruncateString
for string values
Status DevToolsClientImpl::ProcessEvent(const internal::InspectorEvent& event) {
if (IsVLogOn(1)) {
VLOG(1) << "DEVTOOLS EVENT " << event.method << " "
<< FormatValueForDisplay(*event.params);
}
std::string FormatValueForDisplay(const base::Value& value) {
scoped_ptr<base::Value> copy(SmartDeepCopy(&value));
return PrettyPrintValue(*copy);
}
scoped_ptr<base::Value> SmartDeepCopy(const base::Value* value) {
//skipped code
} else if (value->GetAsString(&data)) {
TruncateString(&data);
return scoped_ptr<base::Value>(new base::StringValue(data));
}
void TruncateString(std::string* data) {
const size_t kMaxLength = 200;
if (data->length() > kMaxLength) {
data->resize(kMaxLength);
data->replace(kMaxLength - 3, 3, "...");
}
}
Turning off logging in Selenium (from Python)
Here's what helped me to overcome the problem:
import logging
from selenium.webdriver.remote.remote_connection import LOGGER
LOGGER.setLevel(logging.WARNING)
Note: this code should be put before webdriver initialization.
Hope that helps.
Related Topics
Bidirectional Multi-Valued Map in Java
How to Remove Leading Zeros from Alphanumeric Text
Java Arraylist - How to Tell If Two Lists Are Equal, Order Not Mattering
Drawing a Simple Line Graph in Java
Spring Autowiring Using @Configurable
Java: Array of Primitive Data Types Does Not Autobox
Swingworker, Thread.Sleep(), or Javax.Swing.Timer? I Need to "Insert a Pause"
Webdriver: Check If an Element Exists
Using Jasperreports with a Relative Path
Should Private Helper Methods Be Static If They Can Be Static
Easy Way of Running the Same Junit Test Over and Over
Getting Java.Lang.Classnotfoundexception: Org.Apache.Commons.Logging.Logfactory Exception
Is It Safe to Construct Swing/Awt Widgets Not on the Event Dispatch Thread
How to Flatten 2D Array to 1D Array
What Goes into the "Controller" in "Mvc"
How to Intentionally Cause a Custom Java Compiler Warning Message