How to configure Tomcat JULI logging to roll log files? - java

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>

Related

Writing a log in to specific file for particular Class special log

In my application currently I am using the log4j for log. All the logs are getting written in to same log file. there is one common log file, where some others application also used write the log.
Lets assume i have aap.log and common.log. I want that all the log will get in app.log file but for some specific class log will get in common.log.
My log4j config is as below for app.log
<appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${home}/logs/app.log</File>
<encoder>
<pattern>%d{MM.dd HH:mm:ss.SSS} [%2.2t][%c{1}.%M] %-5p - %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<maxIndex>20</maxIndex>
<FileNamePattern>${home}/logs/app.log.%i</FileNamePattern>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>25MB</MaxFileSize>
</triggeringPolicy>
</appender>
I don't want to create a new appender here for the common.log or addadditivity="false for that class. I want to use one CustomUtility class to write the log in to common.log instead of configuring it from log4.xml.
How can i write the log in same common.log file so other applications data or mine will not get messed up.
So in a nutshell, you need to do the following:
Define an another File appender (basically duplicate the section that you've presented in the question, change the name pattern). I don't think you should use app.log and app1.log to avoid confusion related to log rotation policies. So just pick other name for this new log file and associate appender with it.
When you have an appender - associate the logger of the utility class with this appender. You don't show it in the question but the chances are that a special "root" logger is associated with the presented appender. So you should define a logger for the utility class (use fully qualified name of the class including the package) and associate the appender that you've created in "1" with it.
After this step, logs coming from this utility class will be written into 2 files.
Why? Because of additivity feature of logging libraries:
So you should define the log created in "2" with "additivity=false".
Basically additivity means that you should resolve the actual appenders not only from the logger itself but from its parents as well, setting additivity=false breaks this chain

log4j2 configuration using system properties

Hi I have recently migrated the logging from log4j to log4j2 in my spring project.
Everything is working fine as expected but I wish to know how I can set the properties
<SizedBasedTriggeringPolicy size="10MB" /> and <DefaultRolloverPolicy max="80" /> in my log4j2 config file by directly picking up the value from the given system argument for Rolling File Appender.
In log4j I used to use <param name="MaxFileSize" value="10MB" />
and <param name="MaxBackupIndex" value="80" /> in my RollingFileAppender default configuration and could override the parameter value by passing myAppenderLoggerName.MaxBackupIndex = my-value and myAppenderLoggerName.MaxFileSize = my-value as system properties args.
I'm aware I can use $(sys:my-parameter-name:-default-value) in log4j2 for substitution but is there a direct approach through which I can override the parameter by referencing it's property name directly in log4j2 like it was there is log4j like say myAppender.paramterNameForRolloverSizeInLog4j2 = my-value ?
No, Log4j2 doesn't automatically associate every attribute with a system property.
I'm not sure why you would want to either as that would be quite cumbersome. For example, to set the max file size you would need
-DmyAppender.policies.sizeBasedTriggeringPolicy.max=10MB
How is that better?
But if you really want that you are free to do
<property name="myAppenderMax">${sys:myAppender.policies.sizeBasedTriggeringPolicy.max:=10MB}</property>
and then specify ${myAppenderMax} as the value in the appender configuration.

Configure Tomcat Log rotation windows

I use tomcat 9.0,slf4j for logging.
The problem was that log files are too big(17GM - the max i saw). I created java-based deleting system for logs. Because tomcat creates new log file every day.
But here is one unexpected moment. Tomcat creates log files whenever it may, sometimes it may use old days file.
For example today is 16th. This file may be used till 18th.
And thats why the size becomes big.
Even if configure correct(for my case) log creation i may have logs for 2 days in one file.
For example from 16th 1:00 pm till 17th 12:00 am.
So, i want to configure rotation for somehow.
Can somebody help?
slf4j is just an interface, you must be using log4j, logback, common-logging, etc (implmentation of slf4j).
If you are using slf4j + logback, you can set your rollingPolicy in logback.xml file. It cab be TimeBasedRollingPolicy, Size or combination of both.
For example, to set Time based policy to create log file per day and move older files to archive folder and just keep last 30 days logs, you can add this in your logback.xml file
<appender name="app" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${catalina.home}/logs/appname/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${catalina.home}/logs/archive/appname/app.%d{yyyy-MM-dd}.old.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>[%X{key}]%date{"yyyy-MM-dd'T'HH:mm:ss,SSSXXX", UTC} %-5level %logger{35}.%M[%L]-[%t] - %msg %n</pattern>
</encoder>

How to ouput text to console from Servlet

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>

Disable Axis log4j logging in jboss

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.

Categories

Resources