如何使用相同的log4j记录器为不同的包创建不同的日志文件?

时间:2012-05-17 05:50:39

标签: java logging log4j

我正在尝试为不同的包设置单独的日志文件。我正在为log4j记录器使用Wrapper类。我的应用程序中的每个类都调用相同的包装类。我的包装类:

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

它被称为:

MyLogger.write(, , );

有没有办法配置log4j,以便将不同包的日志记录输出到不同的文件?

谢谢!

修改

这是我的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 个答案:

答案 0 :(得分:6)

如果在MyLogger类中创建静态Logger,则会有一个Logger实例,其名称设置为MyLogger。当您从其他软件包调用该记录器时,Log4j无法确定这些调用的来源,因为它们都使用相同的Logger。

处理它的最好方法是在每个类中定义一个单独的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传递Class,您可以使用反射的讨厌技巧,获取调用类的名称,但由于性能损失,我不建议这样做:

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

答案 1 :(得分:0)

你可以这样做(com.myco.a和com.myco.b是你的两个不同的包):

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

干杯。

答案 2 :(得分:0)

创建2个appender和2个logger可以做你想要的。

答案 3 :(得分:0)

从每个包的属性文件中读取所需的自定义文件位置。然后,您可以使用以下给定的方法更新log4j prop文件中设置的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); 
}