I have a servlet. But it is not working as desired. Hence for debugging purposes, I want to print statements to the java console(the one that can be opened using the java icon in taskbar). However, if I use System.out.println("message"), it doesnt display in java console.
Is there any alternative way where I can display messages to the console from the servlet?
Or can anyone suggest me an alternative way to display messages to any other console?
In which console do you expect it to appear?
Depending on the servlet container (I assume Tomcat), the logs are stored in a logs folder. For Tomcat this is tomcat/logs (or more often referred to as CATALINA_HOME/logs). If you are running it from within an IDE - they should be in the IDE console.
As a sidenote, using System.out isn't advisable for a real product - use a logging framework (like log4j).
Servlet (HttpServlet) has a method log(String s) inherited from GenericServlet class.
So you can just include
log("output text")
in the servlet's code and see output.
If you use Eclipse log goes right into console.
If you use IntellijIdea log goes into Run --> "Tomcat Localhost Log" tab.
I want to print statements to the java console(the one that can be opened using the java icon in taskbar)
You need to realize that servlets actually runs at the server side, not at the client side. Those are in fact two physically different environments which communicates with each other through the network using the HTTP protocol. That Java console will only work for Java programs which runs at the client side, such as applets and JNLP.
In your case, you just need to read the server logs. That's where the stdout will by default print to, or use a better configureable logging framework such as logback. The server logs are usually found in a straightforward folder/file in the server installation directory, such as /logs in case of Tomcat.
Look for the log file in the log-folder of your servlet container (i.e. Tomcat).
As suggested use log4j to generate debug messages. This logging framework provides a configuration file where you can set things like where the logs should be written into or how the log messages should be formatted. As soon it's in place you can replace
System.out.println("message");
with
log.debug("your debug message");
or
log.info("in case of a message with info character");
log.error("routine foo has experienced an exception", e);
Now your code is much cleaner and there is even another benefit - when being placed correctly these logs act as documentation for your code segments.
You should use logging, e.g. java.util.logging or log4j
Example of relevant log4j configuration:
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
</root>
Related
How can I use Logback to capture System.out messages in a Java program?
For example, I would like to use this code:
System.out.println("test: console out to file instead");
... and capture it's output to a file.
Can this be done using the logback.xml config file?
There's a little jar that does this for you: http://projects.lidalia.org.uk/sysout-over-slf4j/index.html
Please do read the FAQ: http://projects.lidalia.org.uk/sysout-over-slf4j/faq.html - If you use this module and configure logback to output to stdout, you'll get a stream of StackOverFlowErrors :D
If you want to do this yourself, you need to replace System.out and System.err with a custom PrintWriter (?I cannot fully remember the class name). This custom PrintWriter needs to forward the calls to logback in a semi intelligent manner, as print writters can also print character by character rather than by line.
The sysout-over-slf4j solutions answers the question 100%.
Just take note: If you setup the Java Util Logger -> SLF4j bridge (jul-to-slf4j), all the System.out.println messages will also be in you logback log file, along with all the messages printed to the Java util logger.
Here is how to set it up:
https://stackoverflow.com/a/43242620/2359435
Yes you can do it with some configuration similar to..
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<filter class="com.foo.StdOutFilter" />
...
</appender>
<logger name="mylogger" level="debug">
<appender-ref ref="stdout" />
</logger>
In a production environnement (for example) we often use INFO log level because with DEBUG log the size become quickly huge.
I know that's it's possible with SLJ4J or LOG4J to configure log rotation to split files etc.
But most of the time, we only need DEBUG logs when an exception appear, so we can have more information (HTTP Request logs for example).
I'm wondering if it's possible to keep only (for example) 1 minute of DEBUG log and save it if an exception appear. (Main log file is always on level INFO)
For example, when a HttpRequestException occurs, we have a file saved with 1 Minute of DEBUG log HttpRequestException-10-02-2015-10:28:50.log in a specific folder
So we can easily see all exceptions in this folder
/Exceptions/
- HttpRequestException-10-02-2015-10:28:50.log
- NullPointerException-10-02-2015-10:29:51.log
- IOException-10-02-2015-11:29:51.log
So... is it possible to do it with a tool like slf4j ?
And is DEBUG logging a huge performance problem on a production server?
Thanks
I found a solution.
I use cyclicBufferTracker to tell appender to use the last x lines once trigerred
And I can use the evaluator attribute to configure the trigger (default trigger is when an ERROR occurs)
Email is ok for me, but if someone want to put it in files instead of email I think you can create a custom Appender instead of SMTPAppender
Like on this page : http://jira.qos.ch/browse/LOGBACK-207
Here is the actual code : (You will need javax.activation and javax.mail if you use email implementation) and if you use gmail like me you will need to allow low security app in gmail settings : Gmail less secure apps
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<smtpHost>smtp.gmail.com</smtpHost>
<smtpPort>587</smtpPort>
<asynchronousSending>false</asynchronousSending>
<STARTTLS>true</STARTTLS>
<username>GoogleUsername</username>
<password>mypassword</password>
<to>GoogleUsername#gmail.com</to>
<from>GoogleUsername#gmail.com</from>
<subject>Exception Alert</subject>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date - %message%n</pattern>
</layout>
<cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
<bufferSize>50</bufferSize>
</cyclicBufferTracker>
</appender>
Hope it will help
How do I clear JBoss' server.log file when JBoss is running? When I try to do
echo 1 > server.log
I get error msg that the file is being used by another program (JBoss). Is it possible to use a command-line tool (windows or linux(I do have CygWin)) or an application that I can write myself to clear that file?
P.S. I don't need that file to have 0kb, but I want it to have less than 100MB.
By default JBoss keeps the file locked, since it is writing log messages into it. It is locked as long as JBoss is running and I don't know of other way to release it than stopping JBoss itself.
To keep its size under control, you can modify your log configuration, which is by default in <server>/conf˛jboss-log4j.xml. You can specify the maximum size of a log file, and define what to do when that size is reached: roll over to a new file, truncate the existing one and start writing over it again, etc.
A basic example (not tested, so no guarantee that it works straight as it is):
<appender name="ROLL" class="org.apache.log4j.rolling.RollingFileAppender">
...
<param name="maxFileSize" value="100MB" />
...
</appender>
Moreover, with the maxBackupIndex parameter you may define the number of backup files (default is 1).
JBoss locks the file as long as the logging process is running.
If you enabled the JMX console you can stop the logging, delete / modify the log, and start the logging service again.
The url should look something like this (for log4j):
http://jboss.example.com:8080/jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss.system%3Atype%3DLog4jService%2Cservice%3DLogging
I tested this with JBoss 5.
This solution should be scriptable as well.
Regarding your log file size problem: You should use a configuration approach instead of editing the log file manually.
I have small application that is uploading pictures to another website via webservice.
My current problem is, that Axis is logging the whole xml message (including the binary data of the picture!) via STDOUT and I can't seem to figure out, how to disable it.
My log4j settings for jboss (jboss-log4j.xml) includes an appender for normal STDOUT Info loggings, and I tried to disable axis with different category settings:
<appender name="STDLOG" class="org.jboss.logging.appender.RollingFileAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="File" value="${jboss.server.log.dir}/myapplication.log"/>
<param name="Append" value="true"/>
<param name="MaxFileSize" value="5MB"/>
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
</layout>
</appender>
using this setting for STDOUT:
<category name="STDOUT">
<priority value="DEBUG"/>
<appender-ref ref="STDLOG"/>
</category>
I tried these category settings without any change in the result:
<category name="log4j.logger.org.apache.axis" additivity="false">
<priority value="ERROR"/>
</category>
<category name="org.apache.axis">
<priority value="ERROR"/>
</category>
Some sample log output looks like this:
2009-08-07 10:29:43,911 INFO [STDOUT] (http-127.0.0.1-8080-1) =======================================================
= Elapsed: 2190 milliseconds
= In message: <?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<addVehicleImage xmlns="urn:VMgrWebService">
<id xmlns="">APP-T4QKR3U</id>
<idType xmlns="">chiffre</idType>
<data xmlns="">9j4AAQSkZJRgABAQAAAQABAAD2wBDAAUDBAQEAwUEBAQFB
QUGBww0TDMnrXAfKlLjnNJZcciiAOtqk9NG99qhZJKuyYq5k3G
8P2bVSOpT7rVddRP2Z/yqidRuMMKaO2CXRQNWP2jfOo4S4Bo3W
removed rest of image data...
IBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGe1UqaZJJy0jSHPGQ
2009-08-07 10:29:43,927 INFO [STDOUT] (http-127.0.0.1-8080-1) Upload result: true for image mypicture.JPG
Update
I checked the axis-1.4.jar and there is a file called simplelog.properties:
# Logging detail level,
# Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
org.apache.commons.logging.simplelog.defaultlog=info
Setting this to error within the jar, or as a category in jboss-log4j.xml didn't help at all.
Anyone any idea how I can turn off the Axis logging or at least set it to ERROR level?
Cheers
Frank
This might be a bit late in the day, but the problem does not seem to be that logging itself is done in Axis (via System.out and Commons Logging), but rather that the LogHandler is present in the handler chain. That is how the elapsed time is getting logged.
You can disable this handler from the Axis configuration file(s) - server-config.wsdd and/or client-config.wsdd, depending on whether you are using Axis as a server or a client.
The reason why you are seeing messages in your console is probably due to the LogHandler.writeToConsole property being set to true. If you set LogHandler.writeToConsole to false, it should write into a file as defined by the LogHandler.fileName property. By default, the file name is axis.log.
Ok, after trying to find a better solution, the only real way was to check the old legacy code and turn all System.out calls into real logging statements (much better anyway), and then simply filter the remaining STDOUT messages into a different log file.
One of the main reasons seems to be Jboss itself. This discussion from the axis2 mailing list explains why:
Ahh, but you didn't mention you are using jboss! It pretty much forces
you to use their parent log4 config . Ignore the axis2 logging in this
case, and see:
~/jboss/server/default/conf/log4j.xml
There you have to limit the categories. For example, you have:
<category name="org.apache">
<priority value="INFO"/>
</category>
You could leave that as is and just get your logs out of server.log .
I tried setting the category, without success. I assume this is because of differences between axis and axis2. So the only solution left was to go the good coding way and just don't use STDOUT in your own code ;-)
First off, you'll want to check that your log4j configuration is actually the one being read - I recall that in the past, at least one axis jar (I think it may have been axis-ant.jar) was guilty of bundling their own log4j.properties. It may be that log4j is reading a different configuration file than yours, making your efforts at tweaking the configuration pointless!
You can enable the system properties -Dlog4j.debug to have log4j print to standard out which configuration file is being read. If necessary, you can use -Dlog4j.configuration=<file> to point to your own file.
Also, I don't think this is causing your issues, but why are you setting additivity to false?
The problem is that Axis is not using Log4j to log that message, so attempting to change the log4j logging level on that class isn't relevant. Axis is using a System.out.println.
The only thing I can think of (which is really not nice given the side effects) is to turn the STDOUT logging off altogether. Probably setting the priority to off will do.
The only real solution is to fix Axis and patch the code to not pump the xml to System.out but rather use the logging mechanism instead - then you could control it.
It is very important to know which log4j.properties file or log4j.xml is being read. and as Matt pointed out, this is crucial in knowing why your tweaking efforts are not working.
I have a several webapps which use java.util.logging. Tomcat 5.5 is configured to use the Juli logger so that each webapp has its own log file. The problem is that Juli does not have properties for maximum file size and file count. Using Juli the files will grow unbounded and only roll at the end of the day. Also, an unlimited number of log files are retained.
You can see the FileHandler properties on this page - Apache Tomcat 5.5 Documentation
There is no limit or count property (the following lines do nothing)
org.apache.juli.FileHandler.limit=102400
org.apache.juli.FileHandler.count=5
Without changing the webapps is there a way to get unique log files for each application with some type of bounds on the log file sizes?
UPDATE:
The solution I found was not use the Juli logger at all!
java.util.logging.FileHandler.limit=102400
java.util.logging.FileHandler.count=5
Thanks,
Greg
Update: I see your point now after reading more. "Tomcat's JULI implementation is not intended to be a fully-featured logging libary, only a simple bridge to those libraries. However, JULI does provide several properties for configuring the its handlers. These are listed below." Funny that they say that the default java.util.Logging implementation is too limited then they work around it by providing an even more limiting implementation.
FileHandler javadocs
java.util.logging.FileHandler.limit specifies an approximate maximum amount to write (in bytes) to any one file. If this is zero, then there is no limit. (Defaults to no limit).
java.util.logging.FileHandler.count specifies how many output files to cycle through (defaults to 1).
for the one file per web app, you probably want to separate it by the name of the logger and it depends on how the loggers are created for each app. If they're based off the package or class name then you can filter the logs based on that. It looks like the sample on the link you provided tells how to do this
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = \
2localhost.org.apache.juli.FileHandler
EDIT: Just realized you wanted per webapp logging which might not be possible with this setup...
My suggestion, assuming your are using Tomcat 6.0, is to compile the extra component for full commons-logging and use Log4j to configure rolling logs.
Building instructions here
http://tomcat.apache.org/tomcat-6.0-doc/building.html
Then replace the tomcat-juli.jar in the /bin directory of Tomcat and place the tomcat-juli-adapters.jar in the /lib directory along with log4j.jar and log4j.properties.
Then using something like:
<appender name="file" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="logfile.log"/>
<param name="Threshold" value="INFO"/>
<param name="MaxFileSize" value="10MB"/>
<param name="MaxBackupIndex" value="3"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %p %m%n"/>
</layout>
</appender>