Excluding only one level of Log4j Logger - java

I'm using Log4j in a application in which I also use Axis2 and Jetty web server.
I configured the Log4J property file to exclude these classes from logging when in debug priority. But when I did this, the other priority messages also began to be excluded from the main logger.
Is there a way that I can tell Log4j that I just want to log INFO logs from these classes while logging debug logs from my classes?
Here's what I have done:
#Jetty Server and Axis2
log4j.category.org.apache.axiom=DEBUG
log4j.additivity.org.apache.axiom=false
log4j.category.org.apache.axis2=DEBUG
log4j.additivity.org.apache.axis2=false
################# MAIN LOGGER #################
log4j.rootCategory=DEBUG, mainLogger
#File configuration
But as I said this configuration also exclude INFO messages from the main logger.

No, set the Root level to DEBUG, and
log4j.category.org.apache.axiom=INFO
log4j.category.org.apache.axis2=INFO
Also, do not set the additivity to false.
When you're starting from scratch, you might want to use the more modern XML config format right away. There, it would look like this:
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
...
</appender>
<category name="com.apache.axiom">
<priority value="INFO" />
</category>
<root>
<priority value ="DEBUG" />
<appender-ref ref="FILE" />
</root>
</log4j:configuration>

Set the rootCategory to INFO, set an apropriate Logger of your classes (e.g. org.myemployer.myapp) to DEBUG

Using this you can set your log level:
import org.apache.log4j.Level;
public static Logger logger = null;
logger.setLevel(Level.DEBUG);
and
Logger.getRootLogger().setLevel(Level.INFO);

Related

Stop log4j debug printing from third party Jars

I'm using classes from other Jars which use classes from other Jars that use log4j. I cannot change any of these Jars.
A lot of these classes are printing debug to the console at startup when debugging in IntelliJ.
I'm looking for ways to stop this as it's irritating.
I've tried creating a log4j.properties file with "error" log level and had it load in the main() of my application as well as setting the default logger to "error" level. I also checked and all the Jars have a properties inside but non are specfying what log level (they just say what version the Jar is). I've tried creating my own properties files for the classes to use which works but they've already printed their debug before they load the file.
Here's some of the debug chatter being produced:
12:54:17.660 [main] DEBUG org.apache.commons.configuration.PropertiesConfiguration - FileName set to xxx.properties
12:54:17.665 [main] DEBUG org.apache.commons.configuration.ConfigurationUtils - ConfigurationUtils.locate(): base is null, name is xxx.properties
12:54:17.665 [main] DEBUG org.apache.commons.configuration.DefaultFileSystem - Could not locate file xxx.properties at null: no protocol: xxx.properties
12:54:17.668 [main] DEBUG org.apache.commons.configuration.ConfigurationUtils - Loading configuration from the path xxx.properties
12:54:17.668 [main] DEBUG org.apache.commons.configuration.PropertiesConfiguration - Base path set to file:///C:/myProgram/xxx.properties
12:54:17.680 [main] DEBUG org.apache.commons.configuration.PropertiesConfiguration - FileName set to yyy.properties
12:54:17.680 [main] DEBUG org.apache.commons.configuration.ConfigurationUtils - ConfigurationUtils.locate(): base is null, name is yyy.properties
12:54:17.681 [main] DEBUG org.apache.commons.configuration.DefaultFileSystem - Could not locate file yyy.properties at null: no protocol: yyy.properties
12:54:17.681 [main] DEBUG org.apache.commons.configuration.ConfigurationUtils - Loading configuration from the path yyy.properties
12:54:17.681 [main] DEBUG org.apache.commons.configuration.PropertiesConfiguration - Base path set to file:///C:/myProgram/yyy.properties
Here are my .properties files:
---log4j.properties---
log4j.rootLogger=error
---xxx.properties---
log4j.rootLogger=error
---yyy.properties---
log4j.rootLogger=error
my main method starts like this:
public static void main(String[] args) {
PropertyConfigurator.configure("log4j.properties");
Logger.getRootLogger().setLevel(Level.ERROR);
The log4j.properties file is being loaded fine with no issue, and is happy with "log4j.rootLogger=error". (if I add ', R' or ', stdout' like I've seen in other SO questions it complains but I suspect that is due to me being on Windows ).
If this isn't possible, let me know and I'll just accept it, live with it and stop looking.
This project is run by a large audience using windows, mac and linux. (the project is a test harness for developers who need to run the collection of Jars do develop new ones for the collection)
--- edit ----
I've investigated the suggestion of putting a log4j.xml in my project's src/main/resource folder but can't get it to work.
Everything I read indicates the log4j.xml should work but I'm running out of things to try. As a last ditch attempt I tried to google:
"org.apache.commons.configuration" debug stop
and google sent me to my own question haha
Here's my log4j.xml which doesn't seem to be stopping the org.apache.commons.configuration from each jar debug printing every time those classes are initilised (which happens a few hundred times a second).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
<appender name="CA" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n"/>
</layout>
</appender>
<logger name="org.apache.commons.configuration">
<level value="error"/>
</logger>
<root>
<priority value="off"/>
<appender-ref ref="CA"/>
</root>
</log4j:configuration>
I've rebuilt my project and repackaged my jar. I'm hoping I don't have to put the log4j.xml into each Jar's resources folder? :/
Is there a way to see if it's loading the log4j.xml file?
Is there something I need to do to make all the Jars which are presumably instantiting their own instances of log4j use this log4j.xml?
I tried this now for my main method:
public static void main(String[] args) {
PropertyConfigurator.configure("log4j.xml");
Logger.getRootLogger().setLevel(Level.ERROR);
but I am still seeing the console spammed with DEBUG messages from org.apache.commons.configuration
-- edit 2 --
Still stuck. I tried simplying to a really basic example and DEBUG output is still appearing in the console.
Here is my simple main method:
public static void main(String[] args) throws ConfigurationException {
PropertyConfigurator.configure("log4j.xml");
Logger.getRootLogger().setLevel(Level.ERROR);
PropertiesConfiguration config = new PropertiesConfiguration("log4j.xml");
}
Here are the imports:
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
3rd line causes this output to appear:
10:04:08.526 [main] DEBUG org.apache.commons.configuration.PropertiesConfiguration - FileName set to log4j.xml
10:04:08.536 [main] DEBUG org.apache.commons.configuration.ConfigurationUtils - ConfigurationUtils.locate(): base is null, name is log4j.xml
10:04:08.536 [main] DEBUG org.apache.commons.configuration.DefaultFileSystem - Could not locate file log4j.xml at null: no protocol: log4j.xml
10:04:08.546 [main] DEBUG org.apache.commons.configuration.ConfigurationUtils - Loading configuration from the path log4j.xml
Here is the log4j.xml which I confirmed is being loaded by renaming it and seeing a load file error.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
<root>
<level value="error"/>
<priority value="off"/>
</root>
<logger name="org.springframework">
<level value="error"/>
<priority value="off"/>
</logger>
<logger name="org.apache.commons.configuration">
<level value="error"/>
<priority value="off"/>
</logger>
<logger name="org.apache.commons.configuration.PropertiesConfiguration">
<level value="error"/>
<priority value="off"/>
</logger>
<logger name="org.apache.commons">
<level value="error"/>
<priority value="off"/>
</logger>
<logger name="org.apache">
<level value="error"/>
<priority value="off"/>
</logger>
</log4j:configuration>
I created a file called "logback-test.xml" and tried placing it in every possible folder I could think of, finally found if I put it into here "Log4JTest\out\production\Log4JTest" (where Log4JTest is the name of my test IntelliJ project) then it is found.
The loopback-test.xml has the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.apache" level="OFF"/>
</configuration>
and it seems to have done the job!
Here's my Main.java
package com.company;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
public class Main {
public static void main(String[] args) throws ConfigurationException {
PropertiesConfiguration config = new PropertiesConfiguration("log4j.xml");
}
}
and here's the output console:
Connected to the target VM, address: '127.0.0.1:50725', transport: 'socket'
Disconnected from the target VM, address: '127.0.0.1:50725', transport: 'socket'
Process finished with exit code 0
Now to test on the full project... will mark this as 'solved' if it solves the original problem.

Logback shows DEBUG output with root at level INFO when org.hibernate.SQL logger configured

Why would logback allow DEBUG output thru a root logger set to level INFO?
The context is a spring-boot-starter project using Hibernate. The POM names logback-classic and logback-core at version 1.2.0. The following config file is on its classpath (src/main/resources), sets the root logger to INFO level.
logback-test.xml:
<configuration scan="true" debug="false">
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/test.log</file>
<encoder>
<pattern>%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC} [%thread] %-5level %logger{5} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
<logger name="org.hibernate.SQL" level="DEBUG" />
</configuration>
Plenty of INFO/WARN/ERROR messages come thru in the file during a JUnit test. But I'm surprised to see the following DEBUG output from org.hibernate.SQL, which is the ONLY package that contributes debug-level output. I thought I would have to set the root logger to level DEBUG to allow this; I figured level INFO would block it:
2018-09-18T13:31:02.596Z [http-nio-auto-1-exec-4] DEBUG o.h.SQL - delete from C_NOTIF_XYZ where ID=?
Under the covers it appears that Hibernate uses org.jboss.logging.Logger via annotations, see https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/internal/CoreLogging.java
Due to use of annotations, I'm not confident I found the exact class that creates the Delete output shown above. I see from googling that some people suggest an interaction of logging shim classes; but I'm not sure.
Very similar SO question (so I'm not alone :) but no answer: Using logback, debug messages are still being logged though root level is set to "Error"
Thanks in advance for any hints.
From the docs:
The effective level for a given logger L, is equal to the first non-null level in its hierarchy, starting at L itself and proceeding upwards in the hierarchy towards the root logger.
So, you can define an effective level for a logger which overrides the root level. The behaviour you are seeing is default Logback behaviour.
If you want to disable the DEBUG logging from org.hibernate.SQL logger then either:
Remove the org.hibernate.SQL logger configuration since this will cause the org.hibernate.SQL logger to assume the root logger level
Assign the org.hibernate.SQL logger a log level other than DEBUG
Remove this line:
<logger name="org.hibernate.SQL" level="DEBUG" />
At the moment I don't find the reference to the documentation, but I confirm this mode of operation: behavior for ancestor loggers reached through additivity, which by default is set to true, skips log level checks.
Then the log message is sent to the root logger regardless of his log level.

Can i run my log asynchronously using log4j 1.x with log4j.properties file?

I am currently working on performance of "log4j 1.x" vs "logback" i.e. (slf4j).
I can append async to my logback, but i am not able to find any link which can async my log4j.
Async is only introduced in log4j 2.x? or is there any way to make my log4j 1.x work async.
Please assist me.
Thank you.
Asynchronous logging is one of Log4j 2's strong points. Instead of the AsyncAppender, use Async Loggers: the performance is much better.
The Log4j 2 performance page compares Log4j-1.x, Logback and Log4j 2. Take a look and then decide what logging framework to use.
By the way, Log4j 2 has an adapter called log4j-1.2-api-2.6.jar which lets your application use the old log4j-1.2 API, but uses the new log4j 2 implementation.
(Log4j-1.x also has an AsyncAppender. Just like the Log4j 2 AsyncAppender and the Logback AsyncAppender, it uses a BlockingQueue. Log4j 2's Async Loggers use a non-blocking data structure which is much faster.)
log4j.properties does not handle the advanced configuration features
supported by the DOMConfigurator such as support custom ErrorHandlers,
nested appenders such as the AsyncAppender, etc.
Refer log4j API Documentation
There are two ways to configure AsyncAppender in log4j 1.x
Using log4j.xml
Configure AsyncAppender as below
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console1" class="org.apache.log4j.ConsoleAppender">
<param name="target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n" />
</layout>
</appender>
<!--wrap ASYNC around other appender if you want -->
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="500" />
<!-- LocationInfo is Optional, use only if location info is required. (Default value : false)-->
<!-- <param name="LocationInfo" value="true" /> -->
<appender-ref ref="console1" />
<root>
<priority value="debug" />
<appender-ref ref="ASYNC" />
</root>
</log4j:configuration>
Programmatically
You can configure AsyncAppender programmatically as below
static {
enableAsyncAuditLog(Logger.getRootLogger());
}
private static void enableAsyncAuditLog(Logger targetLogger) {
Enumeration<Appender> appenders = targetLogger.getAllAppenders();
AsyncAppender asyncAppender = new AsyncAppender();
asyncAppender.setBufferSize(500);
asyncAppender.setLocationInfo(true); // Otherwise Class and Line info will not be available to logger
while (appenders.hasMoreElements()) {
Appender appender = appenders.nextElement();
if (!(appender instanceof AsyncAppender)) {
targetLogger.removeAppender(appender);
asyncAppender.addAppender(appender);
}
}
appenders = asyncAppender.getAllAppenders();
if (appenders != null && appenders.hasMoreElements()) {
targetLogger.addAppender(asyncAppender);
}
}
You can refer this project for reference

Weblogic12 + Log4j logging not writing to server logs

I know there are lots of Q's regarding this, but I did go through all of them, and kinda confused myself more, I am listing the steps I followed, please let me know where I messed it up.
1) I just want to use Log4j on application level, so need to copy WL_HOME/server/lib/wllog4j.jar, and the log4j.jar in Domail_Home/Lib?
2) I am using Maven, I added the Log4j dependency in my pom.xml [war].I have my WAR wrapped in EAR.
3) Since I want to write the logs in weblogic managed server logs file, I created a custom appender, to use weblogic, NonCatalogAppender as mention in the link - https://blog.desgrange.net/2010/02/15/logging-in-weblogic-console-with-log4j.html
4) I copied the log file in my war/src/main/resources and i see maven added them to classpath i.e war/target/classes, see below for my lo4j xml
http://jakarta.apache.org/log4j/'>
<!-- stdout appender settings -->
<appender name="STDOUT" class="com.xyz.logging.util.WeblogicAppender">
<param name="Threshold" value="DEBUG"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- notes on patterns:
%p - priority (i.e. level) of message
%c - class that threw error
%m - message in logger's method, e.g. "Exiting application HERE..."
%n - carriage return
%d - date information
-->
<param name="ConversionPattern" value="%c{1} %m"/>
</layout>
</appender>
<!-- settings for root debugger -->
<root>
<level value="DEBUG"/>
<appender-ref ref="STDOUT"/>
</root>
5) Now I didn't change anything on the config level, but I don't see anything appending to server logs. When I initialize NonCatlogLogger manually and call the logger it works fine:
NonCatalogLogger logger =new NonCatalogLogger("XYZ");
logger.debug("This is the debug message")
6) When I debug the application in eclipse, it looks like my custom appender is never called.
Got it, just need to put below into arguments under "server start".
-Dweblogic.log.Log4jLoggingEnabled=true

java logging nightmare and log4j not behaving as expected with spring + tomcat6

I have a spring application that has configured log4j (via xml) and that runs on Tomcat6 that was working fine until we add a bunch of dependencies via Maven. At some point the whole application just started logging part of what it was supposed to be declared into the log4.xml
"a small rant here" Why logging has to be that hard in java world? why suddenly an application that was just fine start behaving so weird and why it's so freaking hard to debug?
I've been reading and trying to solve this issue for days but so far no luck, hopefully some expert here can give me some insights on this
I've added log4j debug option to check whether log4j is taking reading the config file and its values and this is what part of it shows
log4j: Level value for org.springframework.web is [debug].
log4j: org.springframework.web level set to DEBUG
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.compass] additivity to [true].
log4j: Level value for org.compass is [debug].
log4j: org.compass level set to DEBUG
As you can see debug is enabled for compass and spring.web but it only shows "INFO" level for both packages. My log4j config file has nothing out of extraordinary just a plain ConsoleAppender
<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="%-5p: %c - %m%n" />
</layout>
</appender>
What's the trick to make this work? What it's my misunderstanding here?
Can someone point me in the right direction and explain how can I make this logging mess more bullet proof?
It might not be log4j that is doing the logging, and hence your log4j config would be ignored. Spring logs using Commons Logging, which is an api that can delegate to various logging frameworks, including log4j. To decide which implementation to use, commons logging looks into the classpath.
If you have added a dependency that dragged its own logging implementation into the classpath, commons logging might now use the other implementation.
I recommend to set a breakpoint at a call to the logging facility, and trace the execution to see which logging implementation is used.
As it was working until you loaded a number of dependencies via Maven, perhaps there's a Log4j configuration loaded inadvertently via these dependencies ?
Run mvn dependency:tree to see what's being loaded, and then see if any of these dependencies has a Log4j configuration.
I think your problem is that you're not setting the threshold param on your appenders, and (maybe) because you're not assigning those appenders to your loggers.
Try adding param name="threshold" value="debug" to your appenders and then explicitly adding them to the specific (or root) loggers like so:
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="threshold" value="debug" />
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<logger name="org.springframework.web">
<level value="debug" />
<appender-ref ref="console" />
</logger>
Also, this page says "This appender will not log any messages with priority lower than the one specified here even if the category's priority is set lower" which is probably the source of your problem.
This seems like a good thread for you to read:
http://forum.springsource.org/showthread.php?t=88250
Cutting to the chase, it seem that the poster had a problem with a Tomcat security setting. An updated Tomcat policy file fixed the issue.
Probably has something do with reading outside of the webapp for your log4j.xml file.

Categories

Resources