Conditional log4j.xml pattern - java

Because %C and %M are resource intensive, for the pattern
%d{yyyy-MM-dd HH:mm:ss} [%C][%M][%t]
I would like that %C and %M to be effective only if log level is set to debug (or more detailed levels).
Does log4j have any provisions for such conditional output formats?

Similar to what Matt suggested before, you can also attach filters to log Appenders and attach multiple Appenders to a single logger. For example:
<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="%d{yyyy-MM-dd HH:mm:ss} [%C][%M][%t] - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMax" value="DEBUG" />
</filter>
</appender>
<appender name="console2" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
</filter>
</appender>
<root>
<priority value="debug" />
<appender-ref ref="console" />
<appender-ref ref="console2" />
</root>
</log4j:configuration>
This should output the patterns you require. The max level filter on the first appender should prevent high log levels and the min level on the second appender prevents debug level statements from appearing twice.
Hope this helps.

You could use another logger that sets additivity="false" for the debug level combined with a ThresholdFilter that only accepts DEBUG or below. It would be a bit of work, though. If that doesn't work, file an issue.

Related

Write specific logs to a log file spring-boot/slf4j

I am able to write console logs to rotating log files using this method here:
https://www.codejava.net/frameworks/spring-boot/logback-rolling-files-example
But my requirement is to write only specific logs to the log files instead of whole console log. For example, i need to write only the json messages(i can print them on console using log.info(message) which is supported by slf4j) being received by Kafka listener to the log files and nothing more. How can i achieve this in my spring-boot app? Is this not possible with slf4j logback?
Specify the appender-ref in your logger element.
So something like this in your logger XML configuration file:
<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>
<appender name="bdfile" class="org.apache.log4j.RollingFileAppender">
<param name="append" value="false"/>
<param name="maxFileSize" value="1GB"/>
<param name="maxBackupIndex" value="2"/>
<param name="file" value="/tmp/bd.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
</layout>
</appender>
Then in the same config file, add a appender reference to the log file that you are interested in
<logger name="com.example.ClassWithJsonMessage" additivity="false">
<level value="debug"/>
<appender-ref ref="bdfile"/>
</logger>

How to solve Log4J No Such Property warning/error?

I have a Log4J xml config file with appenders in it.
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<param name="File" value="/tomcat/website/webapps/app/logs/appInfo.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{MMM dd HH:mm:ss} %F: %m%n" />
</layout>
</appender>
<appender name="rolling" class="org.apache.log4j.RollingFileAppender">
<param nawebsite/webapps/app/logs/app.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="2" />
<param name="DatePattern" value="'.'yyyy-MM-dd'" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{MMM dd HH:mm:ss} %F: %m%n" />
</layout>
</appender>
When I build my project, I get the following warnings/errors in the console which I am trying to get rid of:
log4j:WARN No such property [datePattern] in org.apache.log4j.RollingFileAppender.
log4j:WARN No such property [file] in org.apache.log4j.ConsoleAppender.
I did not make these log4j config xml files; they were already part of the project.
I've seen the DatePattern documentation online, and it seems to suggest exactly what is in the DatePattern value, so I have no idea why it's still showing me that warning. Same with file.
Did the person who made this before me just stick properties in these appenders that do not belong? I'm having a difficult time verifying this.
Every Appender has it's own configuration properties. file make sense for RollingFileAppender but doesn't make sense for ConsoleAppender.
If you switch one appender to another and do not update configuration properties, then you will get such warnings.
To fix them, you need to remove unused (or inapplicable) properties from your configuration:
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{MMM dd HH:mm:ss} %F: %m%n" />
</layout>
</appender>
<appender name="rolling" class="org.apache.log4j.RollingFileAppender">
<param name="FileName" value="/tomcat/website/webapps/app/logs/app.log" />
<param name="MaxFileSize" value="1000KB" />
<param name="MaxBackupIndex" value="2" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{MMM dd HH:mm:ss} %F: %m%n" />
</layout>
</appender>
Complete list of appenders and their parameters is available on the Apache Commons Log4j webpage:
https://logging.apache.org/log4j/2.x/manual/appenders.html

How to create different files for logger hierarchy in tomcat?

In my Tomcat application, I want to use two loggers to log general event informations and errors to two different files.
Logger eventLogger = Logger.getLogger("event");
Logger errorLogger = Logger.getLogger("error");
Now I want to do the following: the logs of the eventLogger should be written to a "events.log" file, and the errorLogger logs should be written in a "errors.log" file. All logs from any other logger (e.g. Tomcat logs) should be written to catalina.out (or any other default file).
How can I achive this with JULI? Or do I need a third party lib?
This can't be achieved with Juli. You might use log4j.
Basically you need appenders. They will manage the logs to go to separate files. Example configuration in xml:
<?xml version="1.0"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.EnhancedPatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%t][%c{1}:%L] %m%n" />
</layout>
</appender>
<appender name="eventFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="#tomcat.home#/logs/event.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<appender name="errorFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="#tomcat.home#/logs/error.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<logger name="event" additivity="false">
<level value="INFO" />
<appender-ref ref="eventFILE" />
</logger>
<logger name="error" additivity="false">
<level value="INFO" />
<appender-ref ref="errorFILE" />
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="FILE" />
</root>
</log4j:configuration>
you have to define an appender for each file in your log4j.xml and connect them to your loggers:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %5p [%c.%M:%L] - %m%n" />
</layout>
</appender>
<appender name="FILE-error" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/error.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="ImmediateFlush" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} %5p [%c.%M:%L] - %m%n" />
</layout>
</appender>
<appender name="FILE-event" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/event.log" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="ImmediateFlush" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss};%m%n" />
</layout>
</appender>
<!-- Loggers -->
<logger name="error" additivity="false">
<level value="warn" />
<appender-ref ref="FILE-error" />
</logger>
<logger name="event" additivity="false">
<level value="info" />
<appender-ref ref="FILE-event" />
</logger>
<!-- Root Logger -->
<root>
<priority value="warn" />
<appender-ref ref="FILE-error" />
</root>
</log4j:configuration>
Tomcat documentation does not provide any way to define more than one file per application when using JULI. Actually it provides the steps to use log4j instead of it because JULI configuration can be too basic.
But again this configuration is at container level:
Note: The steps described in this section are needed when you want to
reconfigure Tomcat to use Apache log4j for its own logging. These
steps are not needed if you just want to use log4j in your own web
application. — In that case, just put log4j.jar and log4j.properties
into WEB-INF/lib and WEB-INF/classes of your web application.
So using a third party library is the logical choice and you can find how to configure it in this SO post
Tomcat JULI logging supports this only via the logging.properties located in the ${catalina.base}/config folder.
#Declares the handlers allowed for use.
handlers = 100catalina.org.apache.juli.FileHandler, 200catalina.org.apache.juli.FileHandler, 300catalina.org.apache.juli.FileHandler
#Install the 'all' hander on the root logger.
.handlers=300catalina.org.apache.juli.FileHandler
#Install the 'event' handler on the 'event' logger and don't report to root.
event.handlers=100catalina.org.apache.juli.FileHandler
event.useParentHandlers=false
#Install the 'error' handler on the 'error' logger and don't report to root.
error.handlers=200catalina.org.apache.juli.FileHandler
error.useParentHandlers=false
#Event handler settings.
100catalina.org.apache.juli.FileHandler.level = ALL
100catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
100catalina.org.apache.juli.FileHandler.prefix = event.
#Error handler settings.
200catalina.org.apache.juli.FileHandler.level = ALL
200catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
200catalina.org.apache.juli.FileHandler.prefix = error.
#Root handler settings.
300catalina.org.apache.juli.FileHandler.level = ALL
300catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
300catalina.org.apache.juli.FileHandler.prefix = all.
This config will not work if you try to install this file in the WEB-INF/classes/logging.properties. This is because the ClassLoaderLogManager doesn't allow you to install handlers on named loggers.

how to stop quartz warn loggers

Console is getting filled with Quartz WARN loggers all the time and it's really annoying to developers who work in the project to find other logger messages in console.
[2013-09-14 11:18:35,142] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'system-id'
[2013-09-14 11:18:35,142] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'end-at'
[2013-09-14 11:18:35,143] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'cron-expression'
[2013-09-14 11:18:35,144] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'start-at'
[2013-09-14 11:18:35,144] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'scheduled-job-id'
[2013-09-14 11:18:35,144] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'size'
[2013-09-14 11:18:40,086] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'GNS'
[2013-09-14 11:18:40,087] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'limit'
[2013-09-14 11:18:40,087] WARN {org.quartz.simpl.PropertySettingJobFactory} - No setter on Job class lk.gov.elg.admin.action.detain.DetainJob for property 'tenantId'
I Google and find a way to do but it didn't give the solution.
<logger name="org.quartz">
<level value="info" />
</logger>
We are using log4j.xml instead of log4j.properties.
Here is the snapshot of log4j.xml file
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true" xmlns:log4j="http://jakarta.apache.org/log4j/">
<!--
Read http://logging.apache.org/log4j/docs/api/org/apache/log4j/DailyRollingFileAppender.html
for more information on DaliyRollingFileAppender configuration options.
-->
<appender name="error" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/elg/logs/scandium-error.log"/>
<param name="Threshold" value="error"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{DATE} %-5p - [%t] [%x] %m%n"/>
</layout>
</appender>
<appender name="debug" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/elg/logs/scandium-debug.log"/>
<param name="Threshold" value="trace"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{DATE} %-5p [%t] - %c{1} [%x] - %m%n"/>
</layout>
</appender>
<appender name="info" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/elg/logs/scandium-info.log"/>
<param name="Threshold" value="info"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{DATE} %-5p %c{1} - [%t] [%x] %m%n"/>
</layout>
</appender>
<appender name="trace" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="/elg/logs/scandium-trace.log"/>
<param name="Threshold" value="info"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{DATE} %-5p %c{1} - [%t] [%x] %m%n"/>
</layout>
</appender>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="info"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p %c{1} - [%t] [%x] %m%n"/>
</layout>
</appender>
<category name="com.opensymphony.xwork2.ognl.OgnlValueStack">
<priority value="error"/>
<appender-ref ref="error"/>
<appender-ref ref="console"/>
</category>
<root>
<priority value="trace"/>
<appender-ref ref="info"/>
<appender-ref ref="trace"/>
<appender-ref ref="debug"/>
<appender-ref ref="error"/>
<appender-ref ref="console"/>
</root>
<logger name="org.quartz">
<level value="info" />
</logger>
</log4j:configuration>
Please help to sort out the issue. Thanks in advance.
WARN is a more severe log level than INFO, and so setting your log level to INFO will still get warnings. The best solution is to figure out why you're getting all those warnings; they're pointing to something Quartz thinks is a real problem (you apparently have a bunch of properties set in a configuration somewhere that the target job type doesn't understand). If you absolutely can't fix the real problem, then you can set the log level to ERROR.

Why is log4j logging to the console?

This is a standalone java application.
I am using the configuration file below and having two problems.
1) I'm getting logs to stdout and I don't know why.
2) I'm getting ALL log messages in my error log even though I have tried to direct only error and higher to the error log.
I am using the BasicConfigurator without specifying an explicit path to the log4j.xml file. The xml file is in the same jar as my classes. It is creating and writing to the appropriate logs in addition to these problems so the configuration is being applied.
3) In addition, I have had no luck having the log4j.xml file outside of the jar so I can change it at runtime. How do I do that?
<!--appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="DEBUG"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%F:%L] - %m%n"/>
</layout>
</appender-->
<!-- working dir is $CATALINA_TMPDIR. send logs to log dir. -->
<appender name="ROLL" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="/var/log/company/application.log"/>
<param name="MaxFileSize" value="5MB"/>
<param name="MaxBackupIndex" value="9"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %x - %m%n"/>
</layout>
</appender>
<appender name="ERRORLOG" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="/var/log/rocketvox/company/error.log"/>
<param name="MaxFileSize" value="5MB"/>
<param name="MaxBackupIndex" value="9"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %x - %m%n"/>
</layout>
</appender>
<category name="com.company">
<priority value="ALL"/>
<appender-ref ref="ROLL"/>
</category>
<category name="com.mattx">
<priority value="ALL"/>
<appender-ref ref="ROLL"/>
</category>
<root>
<priority value="error"/>
<appender-ref ref="ERRORLOG"/>
</root>
Add -Dlog4j.debug to the application's JVM args to see exactly what log4j is doing and which configuration file it uses.
Your problem is using BasicConfigurer - for configuring using a file named log4j.xml, you don't need to use any explicit log4j Configurer in your application code, as the default log4j initialization logic will kick in to pick log4j.xml (or log4j.properties, if no xml is found) from the classpath.
See Default Initialization Procedure from the log4j manual.

Categories

Resources