Log4j单例包装器的好处



我最近继承了一些Java代码,需要将其集成到我正在进行的一个项目中。我的项目是一个处理和转换XML消息的服务代理。在查看新代码时,我发现了以下日志类:

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
public class MyLogger {
    private static MyLogger instance = null;
    protected final static Logger log = Logger.getLogger(MyLogger.class);
    private MyLogger() {
        super();
    }
    public static MyLogger getInstance(){
        if(instance  == null){
            instance  = new MyLogger();
            BasicConfigurator.configure();
            log.setLevel(Level.ALL);
        }
        return instance;
    }
    public void info(String myclass, String msg) {
        log.info("[" + myclass + "] " + msg);
    }
    public void error(String myclass, String msg, Exception ce) {               
        log.error("[" + myclass + "] " + msg, ce);      
    }
    public void warning(String myclass, String msg) {
        log.warn("[" + myclass + "] " + msg);
    }    
}

这个类基本上是用(另一个)单例封装log4j。我需要集成的类中的所有日志看起来像这样:

public class MyClass {
   private final static MyLogger log = MyLogger.getInstance();
   private final static String myclass = MyClass.class.getName();
   ...
   log.info(myclass, "Information message...");   
}

我没有看到使用额外的类进行日志记录有任何明显的好处,因此我正在考虑重构这段代码,以删除MyLogger类并以以下方式进行日志记录:

import org.apache.log4j.Logger;
public class MyClass {
   private static Logger log = Logger.getLogger(MyClass.class);
   ...
   log.info("Information Message...");     
}

这将使日志机制在整个项目中保持一致。在我这样做之前,我想知道用单例类包装Log4j是否有任何好处,我可能会错过。谢谢!

编辑:感谢每个人的有用答案-我从每个人那里获得了一些新的见解。接受Nathan Hughes的回答,他指出保持类的完整性会导致功能的丢失——我一直认为保持单例最大的缺点就是代码膨胀。我要把这门课搞得一团糟。

去掉它。使用这个怪物意味着通过它的所有日志记录都将使用相同的记录器(MyLogger)和方法列出(这就是为什么它的方法的参数包括被记录的事物的类)。这不仅意味着您必须向每个日志记录器调用添加任何类、方法和行号信息,而且您不能像使用类作为日志记录器的典型log4j方法那样,在日志级别上对不同的包进行任何过滤。

这个东西就是一堆垃圾,你最好不要它。

我能看到的唯一好处是,可以很容易地用另一个日志记录实现替换log4j实现,或者让日志记录做一些更自定义的事情,例如记录到您自己的数据库之一。

也就是说,我仍然会重构代码以直接使用log4j。或者,在我的情况下,更有可能使用SLF4J。

您的继承代码所做的一件事,log4j所做的是使事情非线程安全。因为在getInstance()中没有锁定,你可能会分发多个实例,从而破坏代码的单例意图。

您还失去了根据您正在做的事情为每个类设置日志级别的能力。

我能看出的唯一缺陷是,由于这个声明:

protected final static Logger log = Logger.getLogger(MyLogger.class);

本质上,记录器被连接到对象MyLogger,所有日志信息/错误/警告等将被"链接"到MyLogger。您不知道是哪个对象添加了日志信息,什么也不知道。

我看到的唯一优点是:

  • 单实例化:您永远不必担心声明static final Logger实现。
  • 你不必担心你正在使用什么类型的记录器。只能在这个Singleton类中更改Logger的类型。任何对日志的进一步更改都只能在单例中完成。

我在我的公司也见过这种情况,但我不建议采用这种设置。不如使用SLF4J或Java Logging Framework。

最新更新