Need to Set Minimum and Maximum Level of Logging in Log4j - java

My requirement is little weird.
I want different formatting pattern for different Logging levels that's why I have used this code. But I am unable to set the min and max limit. Because when I am setting logging level to Debug, it is also printing the ERROR and FATAL log messages in that format but I have defined a different format for ERROR and FATAL and because of this ERROR messages are printing two times for this code. I do not want to print ERROR and FATAL log messages in DEBUG pattern format.
log4j.rootLogger=DEBUG, infoLog, errorLog
log4j.appender.infoLog=org.apache.log4j.ConsoleAppender
log4j.appender.infoLog.Target=System.out
log4j.appender.infoLog.layout=org.apache.log4j.PatternLayout
log4j.appender.infoLog.layout.ConversionPattern=%m%n
#log4j.appender.infoLog.Threshold=DEBUG
log4j.appender.infoLog.filter.a=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.infoLog.filter.a.LevelToMatch=INFO
log4j.appender.infoLog.filter.a.AcceptOnMatch=true
log4j.appender.infoLog.filter.a.LevelMin=DEBUG
log4j.appender.infoLog.filter.a.LevelMax=INFO
#log4j.appender.infoLog.filter.b=org.apache.log4j.varia.LevelMatchFilter
#log4j.appender.infoLog.filter.b.LevelToMatch=DEBUG
#log4j.appender.infoLog.filter.b.AcceptOnMatch=true
log4j.appender.errorLog.Threshold=ERROR
log4j.appender.errorLog=org.apache.log4j.ConsoleAppender
log4j.appender.errorLog.Target=System.out
log4j.appender.errorLog.layout=org.apache.log4j.PatternLayout
log4j.appender.errorLog.layout.ConversionPattern=\u001b[31;1m%d{yyyy-MM-dd HH:mm:ss} [%-5p] %c{1}:%M():%L - %m%n

This xml Configuration will resolve this problem.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="debugLog" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="DEBUG"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="INFO"/>
</filter>
</appender>
<appender name="errorLog" class="org.apache.log4j.ConsoleAppender">
<param name="Threshold" value="WARN"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%-5p] %c{1}:%M():%L - %m%n"/>
</layout>
</appender>
<root>
<level value="DEBUG"></level>
<appender-ref ref="debugLog"/>
<appender-ref ref="errorLog"/>
</root>
</log4j:configuration>

Related

In java, how to write logs to a specific file appender of log4j?

If a log4j properties have multiple file appenders, then in Java how can I make sure that logs are written in a specific file.
log4j.rootLogger=INFO,out
log4j.appender.SUCCESS_FILE=org.apache.log4j.FileAppender
log4j.appender.SUCCESS_FILE.File=${dd.log.dir}/success.log
log4j.appender.VALID_FILE=org.apache.log4j.FileAppender
log4j.appender.VALID_FILE.File=${dd.log.dir}/valid_error.log
log4j.appender.TEMP_FILE=org.apache.log4j.FileAppender
log4j.appender.TEMP_FILE.File=${dd.log.dir}/Temp_error.tmp_log
In Java class, what can I do to write some messages to, lets say, SUCCESS_FILE and some messages to TEMP_FILE
Logger log = Logger.getLogger(Test.class);
log.debug("This message should go to SUCCESS_FILE");
log.debug("This message should go to TEMP_FILE");
This might help:-
log4j.appender.successLog=org.apache.log4j.FileAppender
log4j.appender.successLog.File=${dd.log.dir}/success.log
log4j.appender.tempLog=org.apache.log4j.FileAppender
log4j.appender.tempLog.File=${dd.log.dir}/Temp_error.tmp_log
log4j.category.successLogger=INFO, successLog
log4j.additivity.successLogger=false
log4j.category.tempLogger=INFO, tempLog
log4j.additivity.tempLogger=false
Access them like:-
static final Logger successLog = Logger.getLogger("successLogger");
static final Logger tempLog = Logger.getLogger("tempLogger");
Using XML configuration like #Nio answered is:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="successLog" class="org.apache.log4j.FileAppender">
<param name="file" value="${dd.log.dir}/success.log" />
<param name="append" value="false" />
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%p] %d %c %M - %m%n" />
</layout>
</appender>
<appender name="tempLog" class="org.apache.log4j.FileAppender">
<param name="file" value="${dd.log.dir}/Temp_error.tmp_log" />
<param name="append" value="false" />
<param name="append" value="false" />
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%p] %d %c %M - %m%n" />
</layout>
</appender>
<logger name="successLogger" additivity="false">
<level value="INFO"/>
<appender-ref ref="successLog"/>
</logger>
<logger name="tempLogger" additivity="false">
<level value="INFO"/>
<appender-ref ref="tempLog"/>
</logger>
</log4j:configuration>
This is what I use to write to 2 log files based on 2 appenders. This also write to console.
The log4j.properties file and java code is available Here
# Root logger option
log4j.rootLogger=ALL,STDOUT,debugLog
log4j.logger.reportsLogger=INFO,reportsLog
log4j.additivity.reportsLogger=false
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %C:%L - %m%n
# Direct log messages to a log file
log4j.appender.debugLog=org.apache.log4j.RollingFileAppender
log4j.appender.debugLog.File="/Users/test/debuglog.log"
log4j.appender.debugLog.MaxFileSize=10MB
log4j.appender.debugLog.MaxBackupIndex=10
log4j.appender.debugLog.layout=org.apache.log4j.PatternLayout
log4j.appender.debugLog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %C:%L - %m%n
# Direct log messages to a log file
log4j.appender.reportsLog=org.apache.log4j.RollingFileAppender
log4j.appender.reportsLog.File="/Users/test/reportslog.log"
log4j.appender.reportsLog.MaxFileSize=10MB
log4j.appender.reportsLog.MaxBackupIndex=10
log4j.appender.reportsLog.layout=org.apache.log4j.PatternLayout
log4j.appender.reportsLog.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %C:%L - %m%n

Redirect log to specific log file by classname

I want to redirect log to specific log file, by classname. The intention is to have a group of classes log output to a specific log file.
Right now the all output comes to console, and on startup it throws and error saying log4j:ERROR Could not retrieve category [com.mycomp]. Reported error follows..
What am I doing wrong here?
In my java class :-
private static final Logger log = Logger.getLogger(SpringBootLog4jApplication.class.getName());
My log4j.xml :-
<?xml version="1.0" encoding="UTF-8" ?>
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' debug="false">
<appender name="LOGFILE" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="/git/services.log"/>
<param name="maxBackupIndex" value="10"/>
<param name="maxFileSize" value="20MB"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %x %p %c{1} :: %m\n"/>
</layout>
</appender>
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<param name="ConversionPattern" value="%5p [%t] (%F:%L) - %m%n"/>
</layout>
</appender>
<logger name="com.mycomp" class="com.mycomp.SpringBootLog4jApplication" additivity="false">
<level value="INFO"/>
<appender-ref ref="LOGFILE"/>
</logger>
<root>
<level value="INFO"/>
<appender-ref ref="stdout"/>
</root>
I believe that the name for the logger should look like
<logger name="com.mycomp.*"...
as that would resolve to any concrete classes in the package.

Is "xmlns:log4j" a required attribute of the <log4j:configuration> tag?

I see a bunch of sample log4j configurations that contain xmlns:log4j="http://jakarta.apache.org/log4j/" in the <log4j:configuration> tag, is this attribute required? What does having this attribute in my configuration do for me?
Example:
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="infoLogsFile" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="MyApplication.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
</layout>
</appender>
<root>
<priority value ="DEBUG" />
<appender-ref ref="infoLogsFile"/>
</root>
</log4j:configuration>
Could I do this instead?
<log4j:configuration>
<appender name="infoLogsFile" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="MyApplication.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
</layout>
</appender>
<root>
<priority value ="DEBUG" />
<appender-ref ref="infoLogsFile"/>
</root>
</log4j:configuration>
The xmlns attribute specifies that elements prepended with log4j are defined by the schema referenced by that URL. Log4J does not actually perform schema validation before attempting to parse the configuration file, so it is not actually required.

log4j console warnings

I am getting two console warnings:
log4j:WARN No appenders could be found for logger (org.roussev.selenium4j.MainTestCase).
log4j:WARN Please initialize the log4j system properly.
Following is my log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="appender" class="org.apache.log4j.FileAppender">
<param name="File" value="selenium4j.log"/>
<param name="Append" value="false"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>
</layout>
</appender>
<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 [%t] %p - %m%n"/>
</layout>
</appender>
<root>
<priority value ="DEBUG"/>
<appender-ref ref="appender"/>
<appender-ref ref="console"/>
</root>
</log4j:configuration>
I am not sure why am I getting this error. The xml seems to be fine to me.
Most common reason for this undescriptive message is ::
The log4j.xml is not properly added in your classpath.
See more here ::: https://stackoverflow.com/a/6616858/1085285

Different log4j layout for debug and error?

In log4j, is there a way to have logger.error("") and logger.debug("") include different output layouts?
I'd like errors to include method names and line numbers, both of which slow down application performance.
EDIT:
After adding apache-log4j-extras, the following config file works.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="WARNINGS" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="warnings.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MMM-dd HH:mm:ss} %-5p %c - %m%n%n"/>
</layout>
<filter class="org.apache.log4j.filter.LevelRangeFilter">
<param name="LevelMin" value="DEBUG"/>
<param name="LevelMax" value="WARN"/>
</filter>
</appender>
<appender name="ERRORS" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="errors.log"/>
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- %M for method name , %L for line number -->
<param name="ConversionPattern" value="%d{yyyy-MMM-dd HH:mm:ss} %-5p %c %M %L - %m%n%n"/>
</layout>
<filter class="org.apache.log4j.filter.LevelRangeFilter">
<param name="LevelMin" value="ERROR"/>
<param name="LevelMax" value="FATAL"/>
</filter>
</appender>
<logger name="com.foo.bar">
<appender-ref ref="WARNINGS"/>
<appender-ref ref="ERRORS"/>
</logger>
</log4j:configuration>
This code was used to test
// goes to errors.txt
log.error("error");
//goes to warnings.txt
log.warn("warn");
Within your log4j.xml configuration, you can create two appenders, each using a LevelMatchFilter and each with a separate pattern output.
I would just setup two different loggers. One called ERROR and one called DEBUG. Then you can easily setup different output layouts and only call ERROR.error or DEBUG.debug.

Categories