Log4j For Each Class in Project - java

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 (...) {}
}

Related

How to use custom log4j.properties file for private logging?

I need to periodically append text messages to a text file and I'm wanting to piggyback on log4j to make life easy. So I've created a "mylog.properties" file with a DailyRollingFileAppender -- nothing unusual -- and I've put that file in my src/java/resources directory. So now I'm ready to create a logger from this file and start logging with it, something like this:
class MyClass {
private static final Logger myLog = getLoggerConfiguredFromPropertiesFile("mylog.properties");
public void logSomething(String message) {
myLog.info(message);
}
}
So what would be the logic for getLoggerConfiguredFromPropertiesFile?
Thanks,
Alvaro
Doing:
private static final Logger myLog = Logger.getLogger(MyClass.class)
should get the job done. log4j automatically looks for the closest log4j.properties to the class, and if you only have one in the project, it's that one. Also, call your file log4j.properties, not mylog.properties.
I came up with a workaround where I'm using the regular logger:
private static final Logger myLog = LoggerFactory.getLogger(MyClass.class);
And in the log4j.properties, I configure a custom DailyRollingFileAppender that works just for my class, as explained here.

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 change CONSOLE threshold during java execution

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);

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);

How to see the log information after writing up my own java main class

I am using a package with many java classes where a lot of org.apache.commons.logging.Log objects are defined. Now I write my own Java main class using these classes; how can I turn on the log information?
I do have log4j.properties file ready. But I am not sure what needs to be included in the java main class in order for this to be effective.
Thank you.
Edit
My log4j.properties file has the following content:
log4j.rootLogger = DEBUG,sysout
log4j.appender.sysout=org.apache.log4j.ConsoleAppender
log4j.appender.sysout.layout=org.apache.log4j.PatternLayout
The package classes use the logger like the following:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
...
public class AClass {
private static final Log log = LogFactory.getLog(AClass.class);
log.debug("Some info ");
...
I am asking what I need to do in my main class in order to get logging information printed out in stdout.
You don't do it in the Java main class, although it might be possible. You need to modify the log4j.properties.
There is a root appender that should already appear in the property file. Set the level to DEBUG and you should see every log message. I recommend defining a fileappender first though. That way you can use your favorite text editor to browse the log messages.
You should define the conversion pattern for the PatternLayout of your appender.
For example:
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Try adding the code below to your main class
import org.apache.log4j.BasicConfigurator;
In main():
BasicConfigurator.configure();
This will use a simple configuration which should output all log messages to the console. Accourding to the Apache logging manual, you can send in the name of a config file as a parmeter like so:
import com.foo.Bar;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class MyApp {
static Logger logger = Logger.getLogger(MyApp.class.getName());
public static void main(String[] args) {
// BasicConfigurator replaced with PropertyConfigurator.
PropertyConfigurator.configure(args[0]);
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
logger.info("Exiting application.");
}
}
I'm assuming the logger jar is in the classpath. I don't know about the apache logging framework but Log4J would send a message to the console (or stderr) about not finding the config file, and it could be easily overlooked depending on what else is sent to stdout. Also, (again for log4j) the directory the property file was in had to be in the CLASSPATH as well.
It occurs to me to double check the expected name of the logfile. Log4J uses log4j.properties but is that what the Apache framework expects? Either way, you can declare the name of the config file when the logger is instantiated. Not sure what the methodname is though.

Categories