Java自定义日志记录器:日志记录标准和最佳实践。

6

我正在开发一个框架,希望jar包尽可能轻量和独立。

因此,我编写了一个日志类:

import java.util.Date;
import java.util.Properties;

public class Logger {

    private static final Logger me = new Logger();
    private static boolean info = false;
    private static boolean debug = false;
    private static boolean error = false;
    private static String className = null;

    public static Logger getInstance(Class<?> clazz) {  
        className = clazz.getCanonicalName();
        try {
            Properties props = new CustProps().load(clazz);
            if(props.get(CustProps.NAME_LOG_MODE) != null) {
                String devMode = props.getProperty(CustProps.NAME_LOG_MODE)
                                   .toLowerCase();
                if("info".equals(devMode)) {
                    info = true;
                    debug = true;
                } else if("debug".equals(devMode)) {
                    debug = true;
                } 
            }
        } catch (Exception e) {
            // debug is error by default
        }

        error = true;
        return me;
    }

    public void logError(Object msg) {
        if(isError()) {
            System.out.println(new Date().toString()
              + " ERROR ["+Logger.className+"] - " + msg);
        }
    }

    public void logDebug(Object msg) {
        if(isDebug()) {
            System.out.println(new Date().toString()
              + " DEBUG ["+Logger.className+"] - " + msg);
        }
    }

    public void logInfo(Object msg) {
        if(isInfo()) {
            System.out.println(new Date().toString()
              + " INFO ["+Logger.className+"] - " + msg);
        }
    }

    public boolean isInfo() { return Logger.info; }

    public boolean isDebug() { return Logger.debug; }

    public boolean isError() { return Logger.error; }

}
  • 如何做到更好的日志记录?
  • 自己开发一个日志记录器是否值得?
  • 使用这个日志记录器会不会比选择现有的(例如log4j)使我的框架变得更糟?
7个回答

25
我强烈建议您使用slf4j作为日志API,因为它被设计成能够在部署时切换后端。换句话说,如果您的日志框架不再适用或需要与其他使用其他框架的人进行接口,更改主意就很简单了。

http://slf4j.org/

它还允许您使用{}语法在日志字符串中轻松插入对象,而不会产生额外开销(这真的很好)。
我建议您考虑根据自己的需求调整“简单”后端,因为它可能提供了您需要的90%功能。

http://www.slf4j.org/apidocs/org/slf4j/impl/SimpleLogger.html

注意:不要直接使用任何后端(例如log4j或java.util.logging),因为它将使您的代码与该后端绑定。使用门面模式。

1
考虑到像java.util.log*或log4j这样的日志框架非常可扩展和可配置,是否真的值得通过门面(尽管是非常好的门面)来实现?您是否曾经遇到过log4j无法满足的需求? - djna
slf4j 提供了 {}-构造。仅凭这一点就足以在任何地方使用。 - Thorbjørn Ravn Andersen
谢谢您的建议,但对于java.util.logging.Logger,我不需要额外的导入。 - Trick
现在回顾10年前,我认为slf4j(作为logback的API)背后的设计是有问题的,因为日志记录不应该是应用程序中不可见的一部分,而应该是一个一等公民组件。对于一个新项目,我建议研究log4j 2.x版本并使用其本地API。https://logging.apache.org/log4j/2.x/ - Thorbjørn Ravn Andersen
你是否曾经遇到过log4j无法满足的需求?嗯,比如安全的供应链? - Andrew Henle

13

您不喜欢java.util.logging.Logger吗?它已包含在JDK中,您无需其他任何东西。


5
话虽如此(Curb Your Enthusiasm),Java日志记录实现了曾经被认为在物理上不可能的事情,即它同时吸和吹。 - cletus
@Trick,你有没有尝试过重新配置j.u.l日志记录的乐趣? - Thorbjørn Ravn Andersen
@cletus 话虽如此(《宋飞正传》) - Anurag Awasthi

7

您有三个问题:

  • 如何提高日志记录的最佳实践?

正如其他人所指出的那样,最佳实践是完全替换它,使用类似于log4j或slf4j之类的东西,或者为了达到您的“独立性”目标,仅使用java.util.Logger。

  • 自己制作日志记录器是否值得?

不值得,除非在某些特殊情况下,由于某种原因,现有框架不能满足您的需求。您没有提供任何表明可能存在这种情况的迹象。

  • 使用此日志记录器会使我的框架比选择现有的框架(例如log4j)更差吗?

是的,即使只是因为这将使其他维护人员花费几分钟阅读您的日志记录类,当他们进入您的代码库时。使用现有框架意味着他们已经知道它的功能。


明智的建议。我已经数不清有多少次看到人们编写自己的框架(通常很好),但是在撰写文档时失去了兴趣。 - Fortyrunner
很好的回答。但我有一个后续问题。我们有一个包含5个不同微服务的产品。我们正在开发一个通用库来处理横切关注点。它可以处理哪些常见的日志记录功能?我想到了一些,比如:1- 日志记录模式,2- 日志记录库活动,3- 公共日志记录配置。但是我还在尝试找到更多的价值。提前致谢。 - Mustafa Mohammadi
1
@MustafaMohammadi 把它作为一个单独的问题提出来,这样会得到更多的关注。此外,您需要在问题上指定更多的信息。我仍然不明白为什么您想要开发一个通用的日志记录库。现有的工具已经很好了。 - CPerkins

3

使用log4j。它不是一个沉重的日志框架,"尽可能独立"是什么意思?只需将log4j jar添加到您的框架中,您就可以开始使用了。


3

2

为什么要重复造轮子?

如果您使用Java util logging库,则已经包含在JDK中,因此无需提供额外的代码。

否则,log4j肯定很不错。


0
我会同意其他评论 - 使用COTS工具(Logger、Log4j或其他)。编写和维护自己的工具(通常)不值得。
还有一点要考虑:如果您的框架包含其他第三方软件,您希望将其集成到一个日志文件中,您必须使用某些共享工具(例如,由该第三方软件支持的工具)。将系统的所有部分汇总到一个地方的日志通常非常有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接