How to log different loggers into different files - java

Here is what i have in my java code
private static final Logger SUCCESS = LogManager.getLogger("success");
private static final Logger ERROR = LogManager.getLogger("error");
And I need to create 2 log files for these logs. (i tried to follow Creating multiple log files of different content with log4j) but I think its not exactly the same. But here goes what i created in log4j.properties.
log4j.rootLogger=TRACE, SuccessAppender, ErrorAppender
# setup SuccessAppender
log4j.appender.SuccessAppender=org.apache.log4j.RollingFileAppender
log4j.appender.SuccessAppender.Threshold=INFO
log4j.appender.SuccessAppender.File=success.log
log4j.appender.SuccessAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.SuccessAppender.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
# setup ErrorAppender
log4j.appender.ErrorAppender=org.apache.log4j.RollingFileAppender
log4j.appender.ErrorAppender.Threshold=INFO
log4j.appender.ErrorAppender.File=error.log
log4j.appender.ErrorAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.ErrorAppender.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
I was wondering how to map this "success" log into the "SuccessAppender".

First of all you have to make sure that the RootLogger is not logging anything. This can be achieved in different ways but my first solution is to let it append to the NullAppender.
log4j.rootLogger=OFF, NullAppender
# setup NullAppender
log4j.appender.NullAppender=org.apache.log4j.varia.NullAppender
Then you'll have to set the log level and the appender for your loggers (success and error):
log4j.logger.success = TRACE, SuccessAppender
log4j.logger.error = TRACE, ErrorAppender
And the rest of your log4j.properties is left as is.
An alternate solution if you don't want to use the NullAppender would be to set the additivity flag on the loggers:
log4j.rootLogger=OFF, SuccessAppender, ErrorAppender
log4j.logger.success = TRACE, SuccessAppender
log4j.additivity.success = false
log4j.logger.error = TRACE, ErrorAppender
log4j.additivity.error = false
Some more information about the additivity can be found in the Log4J manual.
Appender Additivity
The output of a log statement of logger C will go to all the appenders in C and its ancestors. This is the meaning of the term "appender additivity".
However, if an ancestor of logger C, say P, has the additivity flag set to false, then C's output will be directed to all the appenders in C and its ancestors upto and including P but not the appenders in any of the ancestors of P.
Loggers have their additivity flag set to true by default.

try
log4j.logger.success=TRACE, SuccessAppender

Related

logging using log4j into a separate files along with on to console

Here is my log4j.properties file
# Define the root logger
log4j.rootLogger = DEBUG, toConsole
# Define the console appender
log4j.appender.toConsole=org.apache.log4j.ConsoleAppender
log4j.appender.toConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.toConsoleAppender.layout.ConversionPattern=%d{HH:mm:ss} %5p [%t] - %c.%M - %m%n
# Define the file appender
log4j.appender.success=org.apache.log4j.FileAppender
log4j.appender.success.File=logs/success.log
log4j.appender.success.Append=false
log4j.appender.success.layout=org.apache.log4j.PatternLayout
log4j.appender.success.layout.conversionPattern=%d{HH:mm:ss} %5p [%t] - %c.%M - %m%n
# Define the file appender
log4j.appender.failure=org.apache.log4j.FileAppender
log4j.appender.failure.File=logs/failure.log
log4j.appender.failure.Append=false
log4j.appender.failure.layout=org.apache.log4j.PatternLayout
log4j.appender.failure.layout.conversionPattern=%d{HH:mm:ss} %5p [%t] - %c.%M - %m%n
log4j.category.successLogger=DEBUG, success
log4j.additivity.successLogger=false
log4j.category.failureLogger=WARN, failure
log4j.additivity.failureLogger=false
and in java class I'm using it as:
static final Logger successLog = Logger.getLogger("successLogger");
static final Logger failureLog = Logger.getLogger("failureLogger");
and using it as:
successLog.warn("Connection is not established");
failureLog.error("Exception",e);
I'm able to get success.log and failure.log file but I was not able to print it on console. Right now, I need to print it on console as well (as just as the flow of our program i.e., need to print parallelly on console while writing to respective logs) and in future I may require only to print the statements only which are eligible to write into success.log
How can I achieve it ???? Thanks in advance
By default Log4j uses the appenders explicitly configured for a logger and the appenders of the parent logger. This behavior is called "additivity" by Log4j. You disabled it with the lines:
log4j.additivity.successLogger=false
log4j.additivity.failureLogger=false
You just need to restore additivity by deleting these lines or setting the value to true.
Alternatively, you can list multiple appenders for a given logger:
log4j.category.successLogger=DEBUG, success, toConsole

Can I set log level for appender wider than respective logger ?

I have the following log4j configuration:
log4j.rootLogger=WARN, myappender, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=com.nasdaq.fbms.logging.custom.EscapedEnhancedPatternLayout
log4j.appender.console.layout.ConversionPattern=%d{EEE, dd MMM yyyy HH:mm:ss,SSS z} %-5p [%t] %c{1.}#%M:%L - %m%n
log4j.appender.myappender=org.apache.log4j.RollingFileAppender
log4j.appender.myappender.File=D:/folder/myLog.log
log4j.appender.myappender.MaxFileSize=10MB
log4j.appender.myappender.MaxBackupIndex=10
log4j.appender.myappender.layout=org.apache.log4j.PatternLayout
log4j.appender.myappender.layout.ConversionPattern=%m%n
log4j.appender.myappender.Threshold=ERROR
at this case I see only errors in myLog.log
but if I set log4j.appender.myappender.Threshold=TRACE - I see errors and warns, but don't see debug info and traces
Can I set log level for appender wider than respective logger ?
Short answer no.
You need to set the appender's threshold to TRACE and the level of the logger to TRACE too.
Here, you don't have any logger defined, so it uses the rootLogger parameter value which is WARN.
If you change it to TRACE you should see more logs.
If you want to keep your rootLogger this way you can limit the level to a specific logger like this:
log4j.category.my.custom.logger=TRACE

Selecting file logging level on package level

I have several log files logfile and debugLogFile. One - more debug info, second less, but still need to have some. In future I expect to have third file with info quantity something between of these two.
I'm asking log4j to log package MyPck in INFO level. This I need for logfile. But I need to have DEBUG level for MyPck for debugLogFile. This is a problem.
Both, logFile and debugLogFile have Threshold=ALL. I need to have possibility in each log file to write all level information. For example logfile will contain DEBUG level for MyPck and INFO for MyPck1 and debugLogFile will contain INFO level for MyPck and DEBUG for MyPck1. How to solve this problem?
log4j.rootLogger=ALL, logfile, debugLogFile
log4j.logger.MyPck=INFO
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=logFile.log
log4j.appender.logfile.Threshold=ALL
log4j.appender.debugLogFile=org.apache.log4j.RollingFileAppender
log4j.appender.debugLogFile.File=debugLogFile.log
log4j.appender.debugLogFile.Threshold=ALL
This should get you going in the right direction:
log4j.rootLogger=TRACE, defaultFile
log4j.appender.defaultFile=org.apache.log4j.RollingFileAppender
log4j.appender.defaultFile.File=defaultFile.log
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=logFile.log
log4j.appender.debugLogFile=org.apache.log4j.RollingFileAppender
log4j.appender.debugLogFile.File=debugLogFile.log
log4j.logger.MyPck=DEBUG,logFile
log4j.logger.MyPck1=INFO,logFile
log4j.logger.MyPck=INFO,debugLogFile
log4j.logger.MyPck1=DEBUG,debugLogFile
log4j.additivity.MyPck=false
log4j.additivity.MyPck1=false
The log4j.additivity.MyPck=false setting ensures that the output of MyPck does not appear in the rootLogger appender.
When you set the log level for MyPck to INFO, you actually set the threshold for this package to INFO, i.e. no message below that level will ever be emitted.
So you need to set the threshold of the package to the lowest common level you want to log.
The next step is then to configure the thresholds of the loggers to filter out any messages you don't want:
log4j.rootLogger=ALL, logfile, debugLogFile
log4j.logger.MyPck=DEBUG
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=logFile.log
log4j.appender.logfile.Threshold=INFO
log4j.appender.debugLogFile=org.apache.log4j.RollingFileAppender
log4j.appender.debugLogFile.File=debugLogFile.log
log4j.appender.debugLogFile.Threshold=DEBUG
Note that the second appender gets a copy of all messages of the first one.

log4j - Why doesn't my appender show message?

At my work, I have inherited of the maintenance of a satandalone application.
The following code configures Log4J but no messages can be seen on the console.
LogManager.resetConfiguration();
PatternLayout layout = new PatternLayout();
layout.setConversionPattern("RECORD-BACKEND / (%-5p) %m (%F:%L)%n");
ConsoleAppender stderr = new ConsoleAppender();
stderr.setTarget(ConsoleAppender.SYSTEM_ERR);
stderr.setLayout(layout);
stderr.addFilter(new CurrentThreadLogFilter());
stderr.setThreshold(Level.INFO);
stderr.activateOptions();
Logger loggerRECORD = getLoggerRECORD();
loggerRECORD.setAdditivity(false);
loggerRECORD.addAppender(stderr);
Logger root = Logger.getRootLogger();
root.setLevel(Level.WARN);
root.addAppender(stderr);
// some lines forward ...
loggerRECORD.info("Process starting...");
What am I missing ?
Unfortunately you have not sent the code that actually prints the message. However I can assume that you try to do something like this:
logger.info("my message");
In this case your message will not be printed because it is filtered out by root logger defined to print warnings.
Loggers in Log4J are stored as hierarchical structure. The root logger is the entry point to this tree. Each logger filters log messages according to configured level. Therefore if upper level logger (root in your case) filters log message it even does not arrive to lower level logger and definitely does not arrive to appender.
The solution for you is to define root logger to allow ALL messages.
And the last note: do you have any special reasons to configure logger programmatically? Log4J can be configured using properties or (better) xml file. Take a look on this document.
And yet another note. Log4J has been deprecated by its creator. If you are starting now go forward to Logback as a logger and SLF4J as a light weight log interface.
Thanks to AlexR, here how I solved my problem:
LogManager.resetConfiguration();
PatternLayout layout = new PatternLayout();
layout.setConversionPattern("RECORD-BACKEND / (%-5p) %m (%F:%L)%n");
ConsoleAppender stderr = new ConsoleAppender();
stderr.setTarget(ConsoleAppender.SYSTEM_ERR);
stderr.setLayout(layout);
stderr.addFilter(new CurrentThreadLogFilter());
stderr.setThreshold(Level.INFO);
stderr.activateOptions();
Logger loggerRECORD = getLoggerRECORD();
loggerRECORD.setLevel( /* get Log Level from env. */ );
loggerRECORD.setAdditivity(false);
loggerRECORD.addAppender(stderr);
Logger root = Logger.getRootLogger();
root.setLevel(Level.WARN);
root.addAppender(stderr);
// some lines forward ...
loggerRECORD.info("Process starting...");
Since additivity is set to false for loggerRECORD, the appender sucessfully print any message from INFO to ERROR.

read .properties file using slf4j

I want to read data from .properties file using slf4j,T i am able to output the data on console but what i want is to output the data on some file so i need file Appender for this which is declared in .properties file and i am not able to read the .properties file using slf4j.Can anyone help.
PS:I need an example that explains how to use.properties file in slf4j and how to initialize logger factory for that.
See http://slf4j.org/faq.html.
SLF4J is only a facade, meaning that it does not provide a complete
logging solution. Operations such as configuring appenders or setting
logging levels cannot be performed with SLF4J.
slf4j-simple doesn't provide extra configuration features at all.
For other implementations you should use the way to configure they provide.
For example, log4j.properties for slf4j-log4j. See http://logging.apache.org/log4j/1.2/manual.html#Configuration.
If using log4j, alternatively it can be used "Log4jLoggerAdapter", defining the configuration on a .properties file.
Code below.
The required jars:
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
If desired the source code (useful when debugging):
slf4j-api-1.7.5-sources.jar
slf4j-log4j12-1.7.5-sources.jar
The testing java class:
import org.apache.log4j.PropertyConfigurator;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.Log4jLoggerAdapter;
public class Slf4j_log4j_main {
private static Log4jLoggerAdapter log = (Log4jLoggerAdapter) LoggerFactory.getLogger(Slf4j_log4j_main.class);
public static void main(String[] args) {
PropertyConfigurator.configure(Slf4j_log4j_main.class.getClassLoader().getResource("basic/log4j.properties"));
log.debug( "a debug" );
log.info( "an info" );
log.warn("a warn");
log.error("an error");
//log.fatal("a fatal"); // slf4j misses fatal log.
log.trace("a fatal");
System.out.println("");
System.out.println("[INFO]: done");
}
}
The basic/log4j.properties
##FROM: log4j_slf4j.basic
##BASED: [BIN319P17]/[BIN319P42]
#using your own named logger.
# defining appender file
log=/home/alsdias/work/dev/java/lab/slf4j/log4j/log4j_slf4j/src/basic
# root logger setup
log4j.rootLogger = DEBUG, A1, FILE
#setting your own named logger. If more loggers, set additivity false (below)
log4j.logger.log4j.level=INFO,A1
log4j.additivity.log4j.level=false
# console appender config
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
# Print the date in ISO 8601 format
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
# file appender config
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out
#setting the immediate flush to true (default)
log4j.appender.FILE.ImmediateFlush=true
#setting the threshold
log4j.appender.FILE.Threshold=debug
#setting the append to false, overwrite
log4j.appender.FILE.Append=false
#set a layout for the appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%d [%t] %-5p %c - %m%n
The generated output:
2013-06-14 11:47:00,473 [main] DEBUG basic.Slf4j_log4j_main - a debug
2013-06-14 11:47:00,474 [main] INFO basic.Slf4j_log4j_main - an info
2013-06-14 11:47:00,474 [main] WARN basic.Slf4j_log4j_main - a warn
2013-06-14 11:47:00,475 [main] ERROR basic.Slf4j_log4j_main - an error
[INFO]: done
slf4j is an API - if you consider it to consist only of interfaces and no classes, you are not far off.
The behavior you need is in the implementation of the interfaces, which for slf4j may be logback, AVSL, JDK14 (java.util.logging), log4j or Simple. Some can read properties, some cannot.
For logback you can use
<property file="src/main/java/chapters/configuration/variables1.properties" />
See http://logback.qos.ch/manual/configuration.html#definingProps for details.

Categories

Resources