How to create different log files for different packages using same log4j logger?

java, log4j, logging

Solution

If you create a static Logger within MyLogger class, then you have one Logger instance, with the name set to MyLogger. When you call that logger from other packages, Log4j is not able to determine the origin of those calls, as they all use the same Logger.

The best way to handle it, is to define a separate Logger within each class, but if you want to use one class as a point of contact with Log4j, then you can do this:

package com.daniel.logger;
import org.apache.log4j.Logger;

import com.daniel.package1.ClassA;
import com.daniel.package2.ClassB;

public class MyLogger{

    public static void write(String message, Class<?> clazz){
        Logger.getLogger(clazz).info(message);
    }

    public static void main(String[] args){
        ClassA.log();
        ClassB.log();
    }
}

Then, one of the class using it could look like:

package com.daniel.package1;

import com.daniel.logger.MyLogger;

public class ClassA {

    public static void log(){
        MyLogger.write("ClassA",ClassA.class);
    }
}

And the `log4j.properties` file would look like:

log4j.appender.package1=org.apache.log4j.FileAppender 
log4j.appender.package1.File=package1.log
log4j.appender.package1.layout=org.apache.log4j.PatternLayout

log4j.appender.package2=org.apache.log4j.FileAppender
log4j.appender.package2.File=package2.log
log4j.appender.package2.layout=org.apache.log4j.PatternLayout

log4j.logger.com.daniel.package1=DEBUG,package1
log4j.logger.com.daniel.package2=DEBUG,package2

If you don't want to pass the Class from ClassA, you could use a nasty trick with reflection, that gets the calling class' name, but I wouldn't recommend that due to a performance hit:

public class MyLogger
{

    public static void write(String message){
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        Logger.getLogger(stackTraceElements[2].getClassName()).info(message);
    }

    public static void main(String[] args){
        ClassA.log();
        ClassB.log();
    }
}

Problem

I'm trying to set up separate log files for different packages. I'm using a Wrapper class for a `log4j` logger. Every class in my application calls same wrapper class. My wrapper class: ``` public class MyLogger { private static Logger logger = Logger.getLogger(MyLogger.class.getName()); .... .... } ``` It is called like this: ``` MyLogger.write(, , ); ``` Is there a way to configure log4j so that it outputs logging of different packages to different files? Thanks! Edit: Here is my `log4j.properties` file: ``` log4j.rootLogger=DEBUG, infoout, aar log4j.logger.com.businessservice.datapopulation=DEBUG, aar log4j.additivity.com.businessservice.datapopulation=false log4j.appender.infoout = org.apache.log4j.RollingFileAppender log4j.appender.infoout.file=/app/aar_frontend.log log4j.appender.infoout.append=true log4j.appender.infoout.Threshold=DEBUG log4j.appender.infoout.MaxFileSize=2MB log4j.appender.infoout.MaxBackupIndex=10 log4j.appender.infoout.layout = org.apache.log4j.PatternLayout log4j.appender.infoout.layout.ConversionPattern = %m%n log4j.appender.aar = org.apache.log4j.RollingFileAppender log4j.appender.aar.file=/app/aar/aar_backend.log log4j.appender.aar.append=true log4j.appender.aar.Threshold=DEBUG log4j.appender.aar.MaxFileSize=2MB log4j.appender.aar.MaxBackupIndex=10 log4j.appender.aar.layout = org.apache.log4j.PatternLayout log4j.appender.aar.layout.ConversionPattern = %m%n ```

Original source