【问题标题】:How to create different log files for different packages using same log4j logger?如何使用相同的 log4j 记录器为不同的包创建不同的日志文件?
【发布时间】:2012-05-17 05:50:39
【问题描述】:

我正在尝试为不同的包设置单独的日志文件。我正在为 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

【问题讨论】:

    标签: java logging log4j


    【解决方案1】:

    如果您在 MyLogger 类中创建一个静态 Logger,那么您将拥有一个 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 传递 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个问题:我可以检查(在java中)是否在log4j的配置文件中定义了特定类的appender?
    【解决方案2】:

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

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

    干杯。

    【讨论】:

    • 您是否在代码中使用相同的记录器?您应该在每个类中创建一个记录器
    • 我在所有应用程序中都使用相同的包装记录器类。问题中也提到了。
    • 如果你必须使用封装类,使用 SLF4j 或者使用 log4j 提供的封装类,看看他们的 api 使用起来很简单
    【解决方案3】:

    创建 2 个附加程序和 2 个记录器可以满足您的要求。

    【讨论】:

    • 无法使用单个Logger实现?
    【解决方案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); 
    }
    

    【讨论】:

    • 这样的表现不会太好。 Log4j 需要一直在两个文件之间切换,方法是关闭一个流并打开另一个。
    猜你喜欢
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多