Log4j 单例包装器的好处?

问题描述 投票:0回答:4

我最近继承了一些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 的回答,指出通过保持类完整而丢失的功能 - 我一直认为单独保留单例的最大缺点只是代码膨胀。我会把班级搞得一团糟。

java singleton log4j wrapper
4个回答
12
投票

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

这东西是垃圾,没有它你会过得更好。

如果您正在考虑包装记录器,请首先确保您熟悉记录器提供的功能,并了解记录器的可配置性。您也许可以通过替换记录器组件之一来获得所需的功能。例如,如果您需要以某种任意格式将日志发送为 json,您也许可以找到一个编码器来执行此操作。使用自定义组件扩展您的记录器可以提供您需要的功能,而不会像使用包装器那样限制您。


4
投票

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

也就是说,我仍然会重构代码以直接使用 log4j。或者,就我而言,更有可能使用SLF4J


3
投票

继承的代码所做的 log4j 所做的一件事就是使事情变得非线程安全。由于

getInstance()
中没有锁定,您可能会分发多个实例并破坏代码的单例意图。

您还无法根据您正在做的事情为每个类别设置日志记录级别。


2
投票

我能说的唯一缺陷是,因为这个声明:

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

记录器本质上是挂钩到对象

MyLogger
并且所有日志信息/错误/警告等都将“链接”到
MyLogger
。您不知道哪个对象添加了日志信息,根本不知道。

我认为这个 Singleton 的唯一优点是:

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

我在我的公司也看到过这种情况,但我不建议这种类型的设置。而是使用 SLF4J 或 Java 日志框架。

© www.soinside.com 2019 - 2024. All rights reserved.