Log4j for per class, how is precedence determined? - java

I'm trying to permit debug logging per a particular class using Log4j, and I've got the following:
log4j.rootLogger=stdout, daily
log4j.logger.com.mycompany.myapplication.mymodule=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{h:mm:ssa} %5p (%F:%L) - %m%n
log4j.appender.stdout.threshold=warn
log4j.appender.daily=org.apache.log4j.DailyRollingFileAppender
log4j.appender.daily.layout=org.apache.log4j.PatternLayout
log4j.appender.daily.layout.ConversionPattern=%d{h:mm:ssa} %5p (%F:%L) - %m%n
log4j.appender.daily.File=/some/file/path/stuff
log4j.appender.daily.DatePattern=MMdd'.log'
log4j.appender.daily.threshold=info
If this is the WEB-INF/classes/log4j.properties file as part of tomcat should debug messages from mycompany.myapplication.mymodule be seen or do the entries later in the file override it? (or am I changing the logging level per class completely wrong?)
Secondly, if a log4j.properties file is included in a jar file, do my settings in Tomcat override those?

You tell your class to log at level DEBUG but tell the appenders to ignore anything below WARN and INFO, so you won't see the log messages.
As for the order in which the log4j.properties will be discovered:
WEB-INF/classes
Any JAR in WEB-INF/lib
common/classes (in the tomcat directory)
Any JAR that you put into common/endorsed
Any JAR that you put into common/lib
shared/classes
Any JAR that you put into shared/lib
The discovery will stop with the first file found.

For your first question, I would say that log4j.appender.daily.threshold=info is a problem. I might not pick any DEBUG message.
Normally, we don't give a threshold to an appender, levels are configured for loggers.
I suggest you use the log4j.xml instead of the log4j.properties.
In addition to the useful validation, it adds some interesting features or default values.
I don't recall exactly which though...

Yes, you seem to be configuring your individual loggers correctly.
No, they will not be seen because you are declaring thresholds on both of your appenders which are above DEBUG:
log4j.appender.stdout.threshold=warn
log4j.appender.daily.threshold=info
As for "Secondly, if a log4j.properties file is included in a jar file, do my settings in Tomcat override those?", I'm not sure what you mean by this. log4j attempts to load a log4j.xml or log4j.properties from the classpath, and will use whichever it finds first. IIRC, entries in the shared lib folder of Tomcat supercede the classpath of each application. If you have a log4j configuration in both a jar in WEB-INF/lib and in a plaintext file in WEB-INF/classes, then you are essentially flipping a coin at runtime as to which will be used.

I think you have to give mymodule an appender, as in
log4j.logger.com.mycompany.myapplication.mymodule=DEBUG, Daily
log4j.additivity.com.mycompany.myapplication.mymodule=false
Also, if you set the additivity to false, you make sure messages get logged only
by the appender you specify.
The 'root' of a jar is normally not included in the CLASSPATH, so a log4j.properties within a jar should be invisible to the JVM.

Related

How to know if logback configuration file has loaded?

I am new to SLF4j and I don't know if the logback.xml file has loaded properly or not. The logback.xml file is in PROJECTNAME/src/main/java where all my packages are found.
My questions are:
How can I know if the configuration file has properly loaded or not
?
How can restrict the logging only from an explicit set of class,
only to avoid logging from libraries
You can add the debug="true" attribute to the <configuration> element to enable debug of the logback configuration. It will print the configuration to the console. See https://logback.qos.ch/manual/configuration.html#dumpingStatusData.
Simple answer, if the configuration file is loaded properly, you will see results in log file or console, depending on your configuration.
By default, logback searches file in src/main/resources instead of src/main/java if I remember correctly.
In the configuration file, you can define log lever on a specific logger. Normally you'll still want to see logs of the libraries, but maybe only WARN or ERROR, so you could set the root level to WARN/ERROR, and add a logger of your root package with DEBUG/INFO level.
Also, use a logback-test file (under src/test/resources) for your own dev environment.

log4j logger overwriting into jxl.log file

I am using log4j for logger purpose. At the same time I am also using JXL to read/write Excel file.
But instead of writing log into log4j logger file, it is writing into jxl.log file.
What can be issue?
Looks like you have been using jxl-2.6.3.jar or similar version.
Log4j picks up the first configuration file with default file name ( i.e. log4j.xml or log4j.properties ) in your classpath if you haven't specified a specific name via JVM parameters. As jxl-2.6.3.jar contains a log4j.xml you ended up printing everything to jxl.log as defined in the log4j.xml
The best way to deal with these kind of problems is to run your application with -Dlog4j.debug JVM parameter. This would print a few line snippet when the log4j is initialized.
log4j: Using URL [jar:file:/C:/YourApp/WEB-INF/lib/jxl-2.6.3.jar!/log4j.xml] for automatic log4j configuration.
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator
...{Blah Blah Blah}
There are many ways in which you can solve this problem.
Use the newer versions of jxl which doesn't contain log4j.xml.
Make sure your log4j.properties file is on top of classpath.
Remove the log4j.xml from the jxl-2.6.3.jar (Dirty solution).
Pass the configuration file name in VM parameter as -Dlog4j.configuration=log4j.properties. This would atleast make sure log4j.xml inside jxl-2.6.3.jar will not be used. (But what if another jar with same name as log4j.properties?).
Rename your log4j.properties file to log4j-yourApp.properties and add VM parameter -Dlog4j.configuration=log4j-yourApp.properties This would definitely help and this is how it should be done to avoid these kind of situations.
More details on Log4j here

log4j doesn't see log4j.properties file

I'm trying to configure logging in my app where log4j.properties is put to /resources folder an has the following content:
#log level
log4j.rootLogger=ERROR, file
log4j
#
log4j.appender.file=org.apache.log4j.RollingFileAppender
#
log4j.appender.file.File=D:\agent\temp\panel log.log
#
log4j.appender.file.MaxFileSize=1MB
#
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
and on my app start I see the following in the console:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
what does this mean and how to fix it?
I had the same problem, I was using tomcat 7.
I solved the problem by adding conf path to the /bin/setenv.sh (if you are on linux, create the file if it does not exist) like this:
export JAVA_OPTS="$JAVA_OPTS -Dconfig.location=file -Dlog4j.configuration=file:///opt/apache-tomcat-7.0.61/lib/log4j.properties"
if you are on windows edit or create setenv.bat and write something like this (not sure about the path format):
set JAVA_OPTS=%JAVA_OPTS%-Dconfig.location=file -Dlog4j.configuration=file://c:/opt/apache-tomcat-7.0.61/lib/log4j.properties
Forgot to say: this will affect all the apps on the server
Try putting the log4j.properties in the root of your source folder. Or alternatively add resources to your classpath.
The root problem is log4j not seeing your config file, so you need to make it accessible.
Extract from log4j manual:
Default Initialization under Tomcat
The default log4j initialization is particularly useful in web-server
environments. Under Tomcat 3.x and 4.x, you should place the
log4j.properties under the WEB-INF/classes directory of your
web-applications. Log4j will find the properties file and initialize
itself. This is easy to do and it works.
You can also choose to set the system property log4j.configuration
before starting Tomcat. For Tomcat 3.x The TOMCAT_OPTS environment
variable is used to set command line options. For Tomcat 4.0, set the
CATALINA_OPTS environment variable instead of TOMCAT_OPTS.
i've changed log4j.properties to log4j.xml and put it to resources folder and now everything is correct. maybe my log4j version doesn't supprot .properties format

log4j.properties, where to put it

According to log4j manual, I should put log4j.properties to the src folder. I copied this file to all the possible places I think it will affect log4j. However, this does not work.
TestEM class contains many unit test functions (I use testng). I run one of these test functions which references a class in the feedback.strategy package.
Here is the content of the log4j.properties file:
#log for class1
log4j.category.Demo1=DEBUG, dest1
log4j.appender.dest1=org.apache.log4j.FileAppender
log4j.appender.dest1.File=C:/Users/Asus/workspace/FeedbackProcess/logs/class1.log
log4j.appender.dest1.layout = org.apache.log4j.PatternLayout
log4j.appender.dest1.layout.ConversionPattern= %d %p [%t] (%c) \u2013 %m%n
This is mostly a question of convention and/or personal preference. What I am accustomed to is to create another source directory (e.g. config or resources) in the project root (next to src and test), then place the log4j.properties there. This can by done by you right-clicking on the newly created folder and choosing Build Path -> Use as Source Folder. Optionally you can specify some inclusion/exclusion patterns too.
Log4j looks for the properties file on the root of the classpath by default. With the above setup the properties file gets copied to the output directory and it will be on the root of your classpath during development.
Later during the deployment the log4j.properties would get bundled in the jar/war file too. You might want to override the bundled properties by specifying an alternative config folder on the classpath during runtime. (see this other question and the docs about the order entries take precedence on the classpath)
You need to put the log4j.properties file on the application classpath.
maybe the file log4j.properties is being read correctly and the problem is with the configuration in log4j.properties file. Does adding this line to the begining of log4j.properties make any difference (assuming that you are have some logging statements in your class files)
log4j.rootLogger=DEBUG, dest1
Place log4j.properties in WEB-INF\classes of the project .
Put log4j-xx.jar under WEB-INF\lib see here for details

SLF4J-Log4j logger not logging

I am trying to use SLF4J-Log4j for the first time. In every Java class, I define a logger like so:
private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(<TheClass>.class);
(And of course, I make sure that the slf4-log4j12-1.6.4.jar JAR is on the classpath!)
But whenever I go to use the logger, like logger.debug("Something interesting happened"); or logger.error("An error occurred");, I don't see their output in my log files. However, no exceptions occur and the app (its actually a WAR deployed to Tomcat) runs fine.
Here is the log4j.properties file included in the project:
# Set the root logger to DEBUG.
log4j.rootLogger=DEBUG
# MonitorLog - used to log messages in the Monitor.log file.
log4j.appender.MonitorAppender=org.apache.log4j.FileAppender
log4j.appender.MonitorAppender.File=${catalina.base}/logs/MyAppMonitor.log
log4j.appender.MonitorAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.MonitorAppender.layout.ConversionPattern= %-4r [%t] %-5p %c %x - %m%n
# Use the MonitorAppender to log all messages.
log4j.logger.*=DEBUG,MonitorAppender
org.quartz.impl.StdSchedulerFactory=DEBUG,MonitorAppender
This WAR uses Quartz to cron a few jobs, which is why you see that last entry.
When I check Tomcat's logs/ directory, I see the MyAppMonitor.log get created, but it has nothing in it (0 bytes). I've scanned all the typical catalina.out, catalina-, and localhost- logs as well, and none of my log statements are seeing the light of day.
I am thinking:
I don't have log4j.properties configured right, or
I don't have slf4j-log4j configured right, or
This is a classpath issue and perhaps the WAR can't find log4j.properties (although I would imagine I would see errors or warnings for this), or
I'm not using (the API itself) SLF4J correctly, or
I never actually created something called MonitorAppender, so I'm wondering if this is the problem; I was just following an example I saw online
Can anybody spot where I'm going awrye, or help me troubleshoot this? Thanks in advance!
Your log4j.properties configuration file is has a number of errors in it. Try with something simple like the following.
log4j.debug=true
log4j.rootLogger=DEBUG, CON
log4j.appender.CON=org.apache.log4j.ConsoleAppender
log4j.appender.CON.layout=org.apache.log4j.PatternLayout
log4j.appender.CON.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
As for the configuration file in your question, the root logger does not have an appender attached. Moreover, the line
log4j.logger.*=DEBUG,MonitorAppender
is not valid as '*' is not supported.

Categories

Resources