I want to be able to do in my Java Netbeans application the same thing as in a normal application: writing print statements to the console or some file for debugging purposes.
I tested this with Netbeans creating a brand new web project running Tomcat 8 with new servlet. I modified the servlet to include:
Logger.getLogger("foo").info("This is a test message.");
And the result is printed to the Tomcat console by default with no changes to Tomcat, no changes to the project, and no logger.properties in the project.
In a web app, it is unfortunately not possible to have the logger output to the console.
You should have multiple tabs at the bottom of Netbeans. One is the console output from the Netbeans ANT task that runs the compiler and launches Tomcat. You should then have another tab that is the output from the Tomcat instance. Under that tab, you should see the logger messages. The logging in Tomcat points out that System.err/out
are remapped to files:
When running Tomcat on unixes, the console output is usually redirected to the file named catalina.out. When running as a service on Windows, the console output is also caught and redirected, but the file names are different.
Default locations are in the Tomcat or domain home under a folder called logs
. The default configuration should already be writing logger output to a file because of the installed console handler and System.err being remapped to a file. It just may not be the location you want.
Even though System.err/out
are remapped you can write to the JVM console by creating your own custom handler that writes to a java.io.FileDescriptor.
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;
public class FileDescriptorHandler extends StreamHandler {
public FileDescriptorHandler() {
super(new FileOutputStream(FileDescriptor.out), new SimpleFormatter());
}
@Override
public synchronized void publish(LogRecord record) {
super.publish(record);
super.flush();
}
@Override
public void close() {
flush();
}
}
By default Netbeans will capture and display this console output. Same is true if you just write code that prints to the console.
How can it be so difficult to direct output to a text file?
Does anybody know how to do direct output of the java default logger to a file?
This is also covered in the Tomcat documentation:
Example logging.properties for the servlet-examples web application to be placed in WEB-INF/classes inside the web application:
handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
.handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
org.apache.juli.FileHandler.level = FINE
org.apache.juli.FileHandler.directory = ${catalina.base}/logs
org.apache.juli.FileHandler.prefix = ${classloader.webappName}.
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
Be aware that for Tomcat you have to declare the handlers that can be used unlike the standard LogManager.
If you can't get the log configuration files working then add a servlet context listener to your project and manually install the file handler.
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
import javax.servlet.annotation.WebListener;
import javax.servlet.ServletContextListener;
@WebListener
public class HandlerInstaller implements ServletContextListener {
private static final Logger logger = Logger.getLogger("");
private Handler target;
@Override
public synchronized void contextInitialized(ServletContextEvent sce) {
try {
target = new FileHandler();
logger.addHandler(target);
} catch (IOException | RuntimeException ex) {
sce.getServletContext().log(sce.toString(), ex);
}
}
@Override
public synchronized void contextDestroyed(ServletContextEvent sce) {
logger.removeHandler(target);
target.close();
target = null;
}
}
already tried log4j ... didn't work either
I'm sure that you are using it in wrong way or missing some configure. You can refer to this tutorial – Idlemanlogger.log
was invoked? – Okechuku