I want to log WebView console events. They sometimes pick up quirks in the underlying browser used and can help with troubleshooting.
It is possible to use an Sun implementation class to interact with the WebView console:
import
//...
WebConsoleListener.setDefaultListener((webView, message, lineNumber, sourceId) ->
LOGGER.info(() -> "WebConsoleListener: " + message + "[" + webEngine.getLocation() + ":" + lineNumber + "]")
);
However, com.sun.javafx.webkit.WebConsoleListener, is an implementation class and not part of the JavaFX public API.
What is the public API for getting JavaFX WebView console events?
Alternatively, what is the correct way to get these events for troubleshooting?
You can enable browser console logging via Java™ 2 platform's core logging facilities by adding this to logging.properties:
com.sun.webkit.WebPage.level = FINE
Make sure that a log handler with FINE or lower level is present in the logging configuration or the logs will be filtered before they are logged. Example:
handlers = java.util.logging.ConsoleHandler
.level = INFO
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.XMLFormatter
com.sun.webkit.WebPage.level = FINE
Here's a more in-depth explanation of how I figured that out:
WebConsoleListener#setDefaultListener(WebConsoleListener) calls WebPageClientImpl#setConsoleListener(WebConsoleListener).
WebPageClientImpl#setConsoleListener(WebConsoleListener) stores the listener in its static field consoleListener.
consoleListener is only interacted with by WebPageClientImpl#addMessageToConsole(String,int,String).
WebPageClientImpl#addMessageToConsole(String,int,String) overrides WebPageClient#addMessageToConsole(String,int,String).
WebPageClient#addMessageToConsole(String,int,String) is called by WebPage#fwkAddMessageToConsole(String,int,String). There are no other call sites in the code base at the time of this writing.
That same method logs the console information:
log.log(Level.FINE, "fwkAddMessageToConsole(): message = " + message
+ ", lineNumber = " + lineNumber + ", sourceId = " + sourceId);
That means you can get the logging you need by enabling FINE logging on com.sun.webkit.WebPage limiting the implementation-level dependency to logging configuration:
com.sun.webkit.WebPage.level = FINE
I could not find a public API for this.
Based on my review of the OpenJDK JFX repo source, there isn't a public API for this.
This solution is still not ideal as it depends on a private implementation classname, but that dependency is in a configuration file where if the implementation class changes or disappears, the impact is a loss of logging rather than a likely fatal NoClassDefFoundError or NoSuchMethodError.
Related
I have set my logging.properties with the following and restarted tomcat:
com.example.handler.level = FINEST
And I have a method of:
public SearchHistoryItem getSearchHistoryItem(Api1 api1, String stringId, String resultId) {
SearchHistoryItem item = api1.getSearchHistoryDetails(stringId, resultId);
Level level = logger.getLevel();
logger.log(Level.INFO, "Log level is: " + level);
logger.log(Level.FINEST, "item is: " + item);
return item;
}
And a return of the following:
13-Dec-2016 18:32:53.093 INFO [ajp-nio-127.0.0.1-8009-exec-4] com.example.handler.SomeHandler.getSearchHistoryItem Log level is: FINEST
If you note. The first log message prints what I am looking for. So I see that logging is indeed FINEST, and I see that log messages are being written. But I don't see the second log message ever print. Is there something other than setting the level in the properties file that I need to worry about?
UPDATE
I am using java.util.logging.Logger with default configurations as far as I can see.
UPDATE
I have been playing with this more and it seems that if I change to Level.FINE they will log. Perhaps there is something somewhere filtering out logs that are to high?
I suppose your problem is with logs in the console.
The used default level for that Handler is Level.INFO.
http://docs.oracle.com/javase/6/docs/api/java/util/logging/ConsoleHandler.html
With FileHandler which the used default level is Level.ALL, you would have not had the problem.
Either you set the level for ConsoleHandler programatically, either you set the it in the configuration file (https://docs.oracle.com/cd/E19717-01/819-7753/gcblo/)
This post gives more details about the question :
Why are the Level.FINE logging messages not showing?
I am running into logging issues after upgrading my Java EE app from Weblogic/JDeveloper to 12.1.2 to 12.1.3.
System.out.println is printing to the server log fine but log.info("test") is not. The logging works if I set the log level e.g. log.setLevel(Level.INFO). Here are my test results.
// This works
System.out.println("test1");
// Output when run: test1
// This does not work. Nothing prints to the server log
log.info("test2");
// The above works if I set the log level
log.setLevel(Level.INFO);
log.info("test3");
// Output when run: test3
// This prints null. It appears that logging level is set to null on server startup
System.out.println(" what is my current logging level: " + log.getLevel());
As per Oracle documentation if no logging configuration is provided then the default logging.properties in JDK/JRE/Lib is used. The default log level is INFO.
I have also tried to load up logging.properties and switch log4j but nothing works.
I don't want to set log level to something in every class. Is there a way to set this on server startup or debug what is causing/setting the logging level to null.
From the logger documentation:
The result may be null, which means that this logger's effective level will be inherited from its parent.
So you only have to set the level of the root logger. You should check that a ConsoleHandler is installed and that the level is set to INFO or lower. You should also check that writing to System.err shows up in the log file as that is the stream that is used for the ConsoleHandler.
I use this code for mine "Logg class" so every class is connected with it, so every exception from every class use this. if you have many classes you want to get logged from this is kind a smart and easy way. I just have one problem too, this code creates a txt file every time you run a program and it's connected with the Logg class. I will fix it soon, so i will edit this answer then. heres my code:
Top of class
private final static Logger logger = Logger.getLogger(Logg.class.getName());
private static FileHandler fh = null;
and in the method you can have this;
Properties prop = new Properties();
InputStream in = Logg.class.getResourceAsStream("loggconfig");
if (in != null) {
prop.load(in);
} else {
throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
}
Some exemple, this txt file will be named the current year, date and time.
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm");
fh = new FileHandler((dateFormat.format(date) + ".log"), false);
Logger l = Logger.getLogger("");
fh.setFormatter(new SimpleFormatter());
l.addHandler(fh);
l.setLevel(Level.INFO);
have this under argument you want to logg:
logger.log(Level.WARNING, "Bla bla");
you can also have a file, like a config so you can choose what level you want to get logged. Then you need to create a property file, my is named loggconfig.
in the config file i have this code:
Level=WARNING
so it just every exception i have as a WARNING, i can change it to INFO to so i get everything logged. Smart to only use two levels in the code.
So if you want to use config file u need to change l.setLevel too this:
l.setLevel(Level.parse(prop.getProperty("Level")));
so it takes the level from config file.
I have a Tomcat server running a large application. It has two classes similar to this example:
public abstract class ClassA {
private static final Logger LOGGER = Logger.getLogger(ClassA.class);
// ...
public File methodA(ICancellable cancel) {
URL request = new URL("an URL");
LOGGER.debug("Calling ClassB.methodB(type)");
File f = classB.methodB(request, "type", cancel);
LOGGER.debug("The call to ClassB.methodB(type)"
+ " returned the File==" + f);
// ...
}
}
public class ClassB {
private static final Logger LOGGER = Logger.getLogger(ClassB.class);
// ...
public static synchronized File methodB(URL url, String type,
ICancellable cancel)
{
final String thisMethodsName = "ClassB.methodB(url: " + url
+ ", type:" + type + ", cancel: " + cancel + ")";
LOGGER.debug("Entering method: " + thisMethodsName);
// ...
return f;
}
}
The application works properly, and ClassA.methodA() initially calls succesfully to ClassB.methodB(), as I can see in the log files:
[...]
14/02/2013 12:34:56 DEBUG ClassA:123 - Calling ClassB.methodB(type)
14/02/2013 12:34:56 DEBUG ClassB:456 - Entering method: ClassB.methodB(url: anURL, type: type, cancel: #1234);
[...]
14/02/2013 12:34:56 DEBUG ClassA:125 - The call to ClassB.methodB(type) returned the File=="aFile".
[...]
My problem is after the server is working for some time, it stops calling ClassB.methodB(). the application gets hung and it simply writes this to the log:
[...]
14/02/2013 12:34:56 DEBUG ClassA:123 - Calling ClassB.methodB(type)
That's the last line of the log file. ClassB.methodB() isn't actually called.
I suspected it could be due to opened resources that werent closed, but I'm trying to locate all the code that did that, and after fixsing so, it still happens.
What can be causing this? How can I continue searching for the cause?
JVM version: 1.6.0_13
Tomcat version: 6.0.18
Is it possible that there is a thread deadlock bug involving some code that you didn't paste? Your ClassB.methodB method is synchronized. You probably have some other thread that is holding and not releasing the synchronized lock on ClassB.class, preventing the thread that is doing the logging from ever acquiring that lock and entering the method.
Enable the debug mode and assign breakpoints in your code. Use IDE ( preferrably eclipse) to go step by step.
Eclipse has plugins like findbugs or PMD to scan the code and find out possible bugs.
Manually go through every conditions, method calls, loops to see flaws.
If you have written the complete app, then you would know where to look at. If not, it would still be good to check all that is written
hi i'm working with a netbeans project, that they gave me to work on, and i need to check if the connection to the database (postgres) are working well, and i notice that there are lines in the code like
static Logger log = Logger.getLogger(getNivel.class);
then
if (user != null) {
log.debug("Usuario identificado: " + user.getIdUsuario() + "obteniendo su cuadro de mandos");
but i don't know how to see if the connection is actually working, because i can't find the log file. so i searched the internet and i found this page
link
but i don't really understand what i should do to see those messages. Can anybody help me?
Not sure which logging library you use, but I presume you use the standard java logging api (java.util.logging package) ...
You dont probably see it because you are using DEBUG level of logging and your project is set to print WARNING and above I believe. So if you what to quickly see whats going on, either change temporarily the code to:
if (user != null) {
log.severe("Usuario identificado: " + user.getIdUsuario() + "obteniendo su cuadro de mandos");
OR create logging.properties file in the root of you project, where you will enable logging on DEBUG level for the class or package for which you want to see the logs:
com.mycompany.mypackgepath.myclass.level=DEBUG
Note, that there might be already such a file in your project. Also you can add more handlers in order to print the log output to a file as well as to netbeans console
handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.FileHandler.pattern = %h/Library/Logs/xd%g-%u.log
java.util.logging.FileHandler.limit = 10485760
java.util.logging.FileHandler.count = 2
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.encoding = UTF8
You might want to check this tutorial for example: http://www.javapractices.com/topic/TopicAction.do?Id=143
Btw. the logger should be private and final ;)
I'm using java logging to write log messages of my application to a log file and other destinations. Having set the log level to FINE, I also get (unwanted) messages from AWT/Swing, such as:
{0}, when grabbed {1}, contains {2}
and others. Looking at the JDK source code (see e.g. here), one sees that the name of the corresponding logger is sun.awt.X11.grab.XWindowPeer.
What I understood from the Java logging framework is that this logging handler should inherit its loglevel from its parents like sun.awt.
I tried the following:
Logger.getLogger("sun.awt").setLevel(Level.OFF);
but the AWT/Swing debug messages still appear in the log output.
What's the recommended way of programmatically disabling these log messages (while still allowing FINE messages from other sources) ?
If you just want to log the messages of your own application, you can disable all messages and then explicitly enable messages for your application:
Logger.getRootLogger().setLevel(Level.OFF);
Logger.getLogger("package.of.your.application").setLevel(Level.ALL);
Inside the properties-file for logging (e.g. logging.properties) this would be:
.level = OFF
package.of.your.application.level = ALL
I had the same problem today. Searching on google this is the top url and I don't find a good source to a answer, so I will post mine :)
Assuming that Andre use the java.util.logging API, it's possible to add a Handler that will control the format of your log, using setFormatter(Formatter newFormatter).
So I extended Formatter and checked if the class of the log contains java.awt, javax.swing or sun.awt.
class MyFormatLog extends Formatter {
#Override
public String format(LogRecord record) {
if( !record.getSourceClassName().contains("java.awt") &&
!record.getSourceClassName().contains("javax.swing.") &&
!record.getSourceClassName().contains("sun.awt.") ) {
//format my output...
} else {
return "";
}
}
}
I could not find the getRootLogger() method in the Logger class any more. This is what works for me:
logger = Logger.getLogger("my.package");
Logger l = logger;
while (l != null) {
l.setLevel(Level.OFF);
l = l.getParent();
}
logger.setLevel(Level.FINER);
Logger.getLogger("java.awt").setLevel(Level.OFF);
Logger.getLogger("sun.awt").setLevel(Level.OFF);
Logger.getLogger("javax.swing").setLevel(Level.OFF);
Try
Logger.getRootLogger().setLevel(Level.OFF);