JBaba
JBaba

Reputation: 610

Programmatically log into multiple files using log4j

I want to write logs in separate files Programmatically,

public class ProgLoggerMultipaleFiles {

    HashMap<LogCategory, Logger> myLogHashMap = new HashMap<LogCategory, Logger>();

    public ProgLoggerMultipaleFiles() {

        JLogger jlog = new JLogger();
        jlog.startFileLog("mylog");
        jlog.startFileLog("HC");
        jlog.startFileLog("MC");
        jlog.startFileLog("DC");

        myLogHashMap.put(LogCategory.mylog, Logger.getLogger("mylog"));
        myLogHashMap.put(LogCategory.HC, Logger.getLogger("HC"));
        myLogHashMap.put(LogCategory.MC, Logger.getLogger("MC"));
        myLogHashMap.put(LogCategory.DC, Logger.getLogger("DC"));

        String parameter = "Hello";

        log(LogCategory.mylog,Priority.DEBUG,"This is debug : " + parameter);
        log(LogCategory.mylog,Priority.INFO,"This is info : " + parameter);
        log(LogCategory.mylog,Priority.WARN,"This is warn : " + parameter);
        log(LogCategory.mylog,Priority.ERROR,"This is error : " + parameter);
        log(LogCategory.mylog,Priority.FATAL,"This is fatal : " + parameter);

        log(LogCategory.HC,Priority.FATAL,"HC");
        log(LogCategory.MC,Priority.FATAL,"MC");
        log(LogCategory.DC,Priority.FATAL,"DC");

    }

    public void log(LogCategory category,Priority priority,String msg){
        myLogHashMap.get(category).log(priority, msg);
    }

    public enum LogCategory{
        mylog,HC,MC,DC
    }

    public static void main(String[] args) {

        ProgLoggerMultipaleFiles plog = new ProgLoggerMultipaleFiles();

    }

}

And I initialize loggers and Appenders in this class,

public class JLogger {

    public JLogger() {
        startConsolLog();
    }

    public void startConsolLog(){
        ConsoleAppender console = new ConsoleAppender(); //create appender
          //configure the appender
        String PATTERN = "%d [%p|%c|%C{1}] %m%n";
        console.setLayout(new PatternLayout(PATTERN)); 
        console.setThreshold(Level.FATAL);
        console.activateOptions();

        //add appender to any Logger (here is root)
        Logger.getRootLogger().addAppender(console);
    }

    public void startFileLog(String fileName){
        FileAppender fa = new FileAppender();
        fa.setName(fileName);
        fa.setFile(fileName+".log");
        fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
        fa.setThreshold(Level.DEBUG);
        fa.setAppend(true);
        fa.activateOptions();
        //add appender to any Logger (here is root)

        Logger.getRootLogger().setAdditivity(false);
        Logger.getRootLogger().addAppender(fa);
        //repeat with all other desired appenders
    }

}

When I run this code creates 4 diff files but all messages are logged into all files.

Thanks in advance.

Upvotes: 1

Views: 867

Answers (1)

Fildor
Fildor

Reputation: 16059

Log4j Loggers work like a tree. When you get Loggers like LogManager.getLogger(MyClass.class) and MyClass is in org.my.company namespace, log4j will traverse the configuration and look for "org.my.company.MyClass" then "org.my.company" and so on until it finds one. If not it uses the rootlogger.

So you can "tap" that tree with appenders. For example you want all classes in "org.my.company.api" to log into a special file: Configure a logger named "org.my.company.api" , add that fileappender to it and get the Loggers with *.class.

In your case it's a bit different. You get Loggers with a specific name that is probably not in the namespace tree. So if there is no logger with that special name, the root logger is used. Thus all messages go everywhere.

So what you have to do is configure not only appenders, but also Loggers with those specific names - "mylog" for example and add the respective appender to only that logger.

Your tree:
root ← Appender Console, mylog, HC, MC, ...

but you need actually:
root ← Appender Console
  |- mylog ← Appender for mylog.log
  |- MC    ← Appender for MC.log
  |- ...

Try:

public void startFileLog(String fileName){
        FileAppender fa = new FileAppender();
        fa.setName(fileName);
        fa.setFile(fileName+".log");
        fa.setLayout(new PatternLayout("%d %-5p [%c{1}] %m%n"));
        fa.setThreshold(Level.DEBUG);
        fa.setAppend(true);
        fa.activateOptions();
        //add appender to any Logger (here is NOT root)

        Logger.getLogger(fileName).setAdditivity(false); // messages will not go to root logger anymore!
        Logger.getLogger(fileName).addAppender(fa);
        //repeat with all other desired appenders
    }

Upvotes: 2

Related Questions