log4j change CONSOLE threshold during java execution - java

I've in my log4j.properties file :
log4j.rootLogger=WARN, CONSOLE, FILEWARN
...
log4j.appender.CONSOLE.threshold=ERROR
...
During Java execution, I would like to put it to WARM.
I did not found anything like Logger.getRootLogger().getAppender("CONSOLE")....setThreshold("WARN")
Is it a solution with some method, or have I to reaload some dedicated properties File with
log4j.appender.CONSOLE.threshold=WARN inside?

The setThreshold method is defined on AppenderSkeleton (the abstract base class of all the standard appenders), not on the Appender interface directly.
((AppenderSkeleton)Logger.getRootLogger().getAppender("CONSOLE"))
.setThreshold(Level.WARN);

Related

log4j ConsoleAppender printing to console twice even after setting Additivity to false

I have log4j appenders that print outputs to the console once when running the program in intellIj
but twice when running the program via executable .jar.
The actual logs that get written to the log file only appear once which is correct.
I define my logger/appenders programmatically in this code block
and after everything is done I call
rootLogger.setAdditivity(false);
but for some reason my classes still output twice to cmdline console when running as a .jar. I call loggers in each class by defining a log variable at the top like so:
public class SomeClass {
static Logger log = Logger.getLogger(SomeClass .class);
and this log variable is used everywhere in the "SomeClass" class.
I've tried setting additivity to false for all the package loggers as well before and after I set their levels...
Logger.getLogger("com.company").setAdditivity(false);
Logger.getLogger("com.company.project.database.Admin").setAdditivity(false);
...
but when I run the code that way it complains it cannot find the appenders for the class that I'm defining all the log4j stuff in, and nothing gets written to output/log.
I think you are on the right track with additivity, however additivity is a property of a child, telling log4j not to use the parents:
https://logging.apache.org/log4net/release/sdk/html/P_log4net_Repository_Hierarchy_Logger_Additivity.htm
You have set additivity to false for the ultimate parent logger, that will never do anything as root will not be a child of anything.
Try setting the additivity to false of each package logger and hopefully that will solve the issue.

Two logs for one class

I'm working on jdk 1.6 and I have a class that needs to log to 2 different log files using log4j. I have read many other answers, but I can't get mine to work the way I want it. This is my log4j properties.
log4j.debug=false
log4j.rootLogger=ERROR, appLog
log4j.logger.com.my.apps.idm.transactionalemail=DEBUG, appLog, infoLog
log4j.appender.appLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.appLog.File=/opt/apps/logs/${ni.cluster}/TransactionalEmail/1.0/TransactionalEmail.log
log4j.appender.appLog.DatePattern='.'yyyy-MM-dd
log4j.appender.appLog.layout=org.apache.log4j.PatternLayout
log4j.appender.appLog.layout.ConversionPattern=DATE: %d{DATE}%nPRIORITY: %p%nCATEGORY: %c%nTHREAD: %t%nNDC: %x%nMESSAGE:%m%n%n
log4j.appender.infoLog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.infoLog.File=/opt/apps/logs/${ni.cluster}/TransactionalEmail/1.0/Info.log
log4j.appender.infoLog.DatePattern='.'yyyy-MM-dd
log4j.appender.infoLog.layout=org.apache.log4j.PatternLayout
log4j.appender.infoLog.layout.ConversionPattern=DATE: %d{DATE}%nPRIORITY: %p%nCATEGORY: %c%nTHREAD: %t%nNDC: %x%nMESSAGE:%m%n%n
And the way I want this to work is like this
public class MyClass{
private static final LOG = Logger.getLogger("appLog");
private static final INFO_LOG = Logger.getLogger("infoLog");
public void myMethod(){
INFO_LOG.debug("This is info");
LOG.debug("This is debug");
}
}
What happens when I run my app is that the Info.log has the same information as TransactionalEmail.log, and also, the line "This is a test" doesn't show up in either of the log files.
What am I doing wrong?
I would recommend against using multiple logger instances for classes. Utilize log4j's configuration to handle logging events as they are generated. You may want to look at the Routing File Appender to decide how log events are handled. From the link
The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed. The RoutingAppender should be configured after any Appenders it references to allow it to shut down properly.

Log4j For Each Class in Project

I have a project containing classes.
I would like to do logging per class instead of wrapping them up altogether in a single log file. I am using Java.
Like for example I have
foo.bar.class1
foo.bar.class2
How can I achieve log file per class?
So that I could have a log file named "class1.log" and "class2.log" containing their own respective log data. What should I do in log4j.properties or on classes?
Any help would be appreciated, thanks.
I'm not sure you can do this in log4j.xml or log4j.properties. So what you can actually do is this (untested, but should work in this fashion):
static {
Logger LOG = LoggerFactory.getLogger(MyClass.class);
try {
((FileAppender)LOG.getAppender()).setFile("class-" + MyClass.name());
} catch (...) {}
}

Change log level of project with single call?

I have configured the log level in properties to DEBUG and works fine, but i want to change the log level of whole project if some event occurs.Apparently my project has many classes and they use the logging like below
private static final Logger log = Logger.getLogger(CommandOperations.class);
I am able to change the log level individually for each class by calling log.setLevel(Level.INFO) but I rather want project wide change. How to do it?
Try Logger.getLogger("com.xx").setLevel(..); where com.xx is the package prefix to all your classes. Do not set levels for individual classes.
When you give com.xx it will be applicable to all subpackages also.
Have you tried using?
LogManager.getRootLogger().setLevel((Level)Level.DEBUG);

Calling log4j logger in a java "Generic Class"

When trying to add log4j logger to a Generic class, it does not generate logs.
This is the code used.
public class GenericClass<K extends Serializable, V extends Serializable> extends ... {
public static Logger log = Logger.getLogger(GenericClass.class.getName());
I am guessing the reason this code fails is because the class is not instantiated till runtime and the plain name that i have given no more resolves to the newly generated class.
Is there a way that generic classes can be logged at all?
Generics have nothing to do with this.
At runtime, a logger by the name of x.y.z.GenericClass (x.y.z being the package in which GenericClass is located). If nothing is logged, then it's either because your application isn't logging anything, or your Log4J configuration is faulty.
To decide which one is true, add -Dlog4j.debug=true to your server initialization parameters and give it a try.

Categories