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

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

Related

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

How to log different loggers into different files

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

log4j: how to set more packages logging into two file appenders, one with INFO threshold, the other with DEBUG threshold

I have two java app working together.
I'm trying to configure my log4j.properties file to have two RollingFileAppender catching same packages but with different log levels.
I want it.pack.subpack1, it.pack.subpack2, it.pack.subpack3 log to two different file appenders, one catching all at DEBUG and above, one catching all at INFO and above.
I did the trick for appB but it doesn't work for appA. Why?
My properties file looks like:
log4j.rootLogger=INFO
#appA INFO file appender
log4j.appender.bocfe=org.apache.log4j.RollingFileAppender
log4j.appender.bocfe.File=${server.log.dir}/bocfe.log
log4j.appender.bocfe.Append=true
log4j.appender.bocfe.Threshold=INFO
log4j.appender.bocfe.MaxFileSize=15MB
log4j.appender.bocfe.MaxBackupIndex=5
log4j.appender.bocfe.layout=org.apache.log4j.PatternLayout
log4j.appender.bocfe.layout.ConversionPattern=%d [%c{1}] %p - %m%n
#appA DEBUG file appender
log4j.appender.bocfe-debug=org.apache.log4j.RollingFileAppender
log4j.appender.bocfe-debug.File=${server.log.dir}/bocfe-debug.log
log4j.appender.bocfe-debug.Append=true
log4j.appender.bocfe-debug.Threshold=DEBUG
log4j.appender.bocfe-debug.MaxFileSize=15MB
log4j.appender.bocfe-debug.MaxBackupIndex=5
log4j.appender.bocfe-debug.layout=org.apache.log4j.PatternLayout
log4j.appender.bocfe-debug.layout.ConversionPattern=%d [%c{1}] %p - %m%n
#appB INFO file appender
log4j.appender.bocws=org.apache.log4j.RollingFileAppender
log4j.appender.bocws.File=${server.log.dir}/bocws.log
log4j.appender.bocws.Append=true
log4j.appender.bocws.Threshold=INFO
log4j.appender.bocws.MaxFileSize=15MB
log4j.appender.bocws.MaxBackupIndex=5
log4j.appender.bocws.layout=org.apache.log4j.PatternLayout
log4j.appender.bocws.layout.ConversionPattern=%d [%c{1}] %p - %m%n
#appB DEBUG file appender
log4j.appender.bocws-debug=org.apache.log4j.RollingFileAppender
log4j.appender.bocws-debug.File=${server.log.dir}/bocws-debug.log
log4j.appender.bocws-debug.Append=true
log4j.appender.bocws-debug.Threshold=DEBUG
log4j.appender.bocws-debug.MaxFileSize=15MB
log4j.appender.bocws-debug.MaxBackupIndex=5
log4j.appender.bocws-debug.layout=org.apache.log4j.PatternLayout
log4j.appender.bocws-debug.layout.ConversionPattern=%d [%c{1}] %p - %m%n
#loggers
log4j.logger.com.eclipsesource.json=DEBUG, bocfe, bocfe-debug
log4j.logger.it.secservizi.boc=DEBUG, bocfe, bocfe-debug
log4j.logger.it.secservizi.abgmf.communication=DEBUG, bocfe, bocfe-debug
log4j.logger.it.sec.ws.boc=DEBUG, bocws, bocws-debug
#additivity
log4j.additivity.com.eclipsesource.json=false
log4j.additivity.it.secservizi.boc=false
log4j.additivity.it.sec.ws.boc=false
log4j.logger.it.secservizi.abgmf.communication=false
Could you please try adding the appender to log4j.rootLogger?
log4j.rootLogger = INFO, bocfe, bocfe-debug

log4j in a JRuby on Rails app - redirecting logs to a separate file

I want to get more granular logging in my JRuby on Rails app. I introduced log4j. I currently have a properties file that looks like the following:
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
#
log4j.logger.Rails=INFO, A
log4j.appender.A=org.apache.log4j.RollingFileAppender
log4j.appender.A.File=/usr/share/tomcat6/logs/production.log
log4j.appender.A.MaxFileSize=10000KB
log4j.appender.A.MaxBackupIndex=5
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
To get Rails.logger to use this, I pop in the following initializer:
org.apache.log4j.PropertyConfigurator.configure("#{::Rails.root.to_s}/config/log4j.properties")
Now, I want to be able to also do something like:
Rails.logger.feature_1("Log to feature_1.log")
Rails.logger.feature_N("Log to feature_N.log")
What's the best way of accomplishing this so not everything goes to one log file?
Also just to note, I am using the adapter that was blogged about here: http://squaremasher.blogspot.com/2009/08/jruby-rails-and-log4j.html
First, you should define an appender/logger configuration for each "feature" you need in your log4j.properties file :
...
log4j.logger.Rails=INFO, A
log4j.appender.A=org.apache.log4j.RollingFileAppender
log4j.appender.A.File=/usr/share/tomcat6/logs/production.log
...
log4j.logger.feature_1=INFO, feature_1
log4j.appender.feature_1=org.apache.log4j.RollingFileAppender
log4j.appender.feature_1.File=/path/to/your/feature_1.log
...
log4j.logger.feature_N=INFO, feature_N
log4j.appender.feature_N=org.apache.log4j.RollingFileAppender
log4j.appender.feature_N.File=/path/to/your/feature_N.log
This way each logger will have it own severity filter and destination file.
Then instead of always using the same logger you may select it depending on the method you called on the Ruby side of the moon (from the example adapter you provided) :
class Log4jAdapter
def method_missing(meth, *args)
# Checking the method name matches feature_N
if /\Afeature_(\d+)\z/ =~ method.to_s
# Retrieve the appropriate logger => getLogger('feature_N')
logger = org.apache.log4j.Logger.getLogger(method.to_s)
# Log !
logger.log *args
else
puts "UNSUPPORTED METHOD CALLED: #{meth}"
end
end
end
Untested but I think you'll get the idea.

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