Как создать разные файлы журнала для разных пакетов, используя один и тот же log4j logger?

Я пытаюсь настроить отдельные файлы журналов для разных пакетов. Я использую класс Wrapper дляlog4j регистратор. Каждый класс в моем приложении вызывает один и тот же класс-обертку. Мой класс обертки:

public class MyLogger
{
    private static Logger logger = Logger.getLogger(MyLogger.class.getName());
    ....
    ....
}

Это называется так:

MyLogger.write(, , );

Is there a way to configure log4j so that it outputs logging of different packages to different files?

Спасибо!

Edit:

Вот мойlog4j.properties файл:

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

Ответы на вопрос(4)

для каждого пакета. Затем вы можете использовать приведенный ниже метод для обновления местоположения файла log4j, установленного в проп-файле log4j:

private void updateLog4jConfiguration(String logFile) { 
    java.util.Properties properties = new Properties(); 
    try { 
        InputStream configStream = getClass().getResourceAsStream( "/log4j.properties");
        properties.load(configStream); 
        configStream.close();
        } 
    catch (IOException e) {
        System.out.println("Error: Cannot laod configuration file "); 
        } 
    properties.setProperty("log4j.appender.FILE.file", logFile); 
    org.apache.log4j.LogManager.resetConfiguration(); 
    org.apache.log4j.PropertyConfigurator.configure(properties); 
}
 daniel17 мая 2012 г., 09:26
Это будет не очень хорошо. Log4j нужно будет постоянно переключаться между двумя файлами, закрывая поток для одного и открывая для другого.
Решение Вопроса

то у вас есть один экземпляр Logger с именем, установленным в MyLogger. Когда вы вызываете этот регистратор из других пакетов, Log4j не может определить источник этих вызовов, поскольку все они используют один и тот же регистратор.

Лучший способ справиться с этим - определить отдельный Logger в каждом классе, но если вы хотите использовать один класс в качестве точки соприкосновения с Log4j, то вы можете сделать это:

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

Тогда один из классов, использующий его, может выглядеть так:

package com.daniel.package1;

import com.daniel.logger.MyLogger;

public class ClassA {

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

Иlog4j.properties файл будет выглядеть так:

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

Если вы не хотите передавать класс из ClassA, вы можете использовать неприятный трюк с отражением, который получает имя вызывающего класса, но я бы не рекомендовал это из-за снижения производительности:

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();
    }
}
 HashimR17 мая 2012 г., 09:54
Благодарность!. Еще один вопрос, пожалуйста: Могу ли я проверить (в java), определен ли appender для определенного класса в файле конфигурации log4j?

и два разных пакета):

log4j.logger.com.myco.a=DEBUG, infoout 
log4j.logger.com.myco.b=DEBUG, aar 

Приветствие.

 HashimR17 мая 2012 г., 09:14
Я использую один и тот же класс logger-обертки во всех своих приложениях. Также упоминается в вопросе.
 Philippe17 мая 2012 г., 09:17
Если вы должны использовать класс-оболочку, используйте либо SLF4j, либо используйте класс-оболочку, предоставляемый log4j, посмотрите в их API, это просто использовать
 HashimR17 мая 2012 г., 09:05
Пытался. Не повезло
 Philippe17 мая 2012 г., 09:13
Вы используете тот же логгер в своем коде? Вы должны создать регистратор в каждом классе

что вы хотите.

 HashimR17 мая 2012 г., 09:05
Не может быть достигнуто с помощью одногоLogger?

Ваш ответ на вопрос