3.1 事件级别列表

日志记录是记录程序运行时发生的任何事件的过程。你作为程序员的职责是record everything important,因为那样的话,当production出现奇怪和/或严重的错误时,除了这些日志之外你将一无所有。

如果您掌握了有关错误的所有信息以及所有调用历史记录,那么消除任何错误的速度将快很多倍。但是从这里可以得出一个简单的结论 - 记录一般的一切:所有方法的调用,所有参数的值。

这也不是一个选择——信息太多和太少一样糟糕。我们需要智能日志记录。人为人而造。在这里,我们谈到了关于日志记录的第一个事实 - 日志中的所有条目甚至在创建时就被分为几类。

事件级别列表

程序员在将事件写入日志时,必须自己决定该信息的重要性。事件的严重级别由消息的作者选择。log4j记录的信息重要性有 5 个级别:

  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL

下面我们将更详细地介绍它们。

3.2 调试

该级别DEBUG被认为是最不重要的。以这种重要性级别写入日志的信息仅在应用程序调试期间需要。为了记录调试过程中需要的信息,使用了该方法debug()

例子:

class Manager {
    private static final Logger logger = LoggerFactory.getLogger(Manager.class);

    public boolean processTask(Task task) {
        logger.debug("processTask id = " + task.getId());
        try {
            task.start();
            task.progress();
            task.complete();
            return true;
        } catch (Exception e) {
            logger.error("Unknown error", e);
            return false;
        }
    }
}

注意,方法debug在方法的最开始(方法还没有来得及做任何事情)并将传递给方法的变量值写入日志。这是该方法最常见的用例debug()

3.3 信息和警告

接下来的两个级别是INFOWARN。它们有两种方法 -info()warn().

该级别INFO仅用于信息性消息:发生这种情况。当您开始解析日志中的错误时,阅读其背景会非常有用。该方法非常适合这个info()

级别WARN用于编写警告(来自warning一词)。通常,在这种重要程度下,会写入出错信息,但程序知道在这种情况下该怎么做。

比如在写一个文件到磁盘的过程中,结果发现已经存在这样一个文件。这里的程序可以记录警告(warning),但会向用户显示一个对话框并提供选择不同的文件名。

例子:

class FileManager {
    private static final Logger logger = LoggerFactory.getLogger(FileManager.class);

    public boolean saveFile(FileData file) {
        logger.info(“save the file ” + file.getName());
        boolean resultOK = SaveUtils.save(file);
        if (resultOK) return true;

        logger.warn(“file writing problem ” + file.getName());
        String filename = Dialog.selectFile();
        boolean result = SaveUtils.save(file, filename);
        return result;
    }

3.4 错误和致命错误

最后,两个最重要的日志记录级别是ERRORFATAL。对于它们,还有一些同名的特殊方法:error()fatal()

他们还决定将错误分为两类——普通错误致命错误。致命错误通常会导致应用程序崩溃(对于桌面应用程序)或 Web 服务崩溃(对于 Web 应用程序)。

另一个很好的例子是 Windows 操作系统。如果你的程序刚刚崩溃,那么从操作系统的角度来看,这是Error. 而如果操作系统本身已经崩溃,你看到的是 Windows 蓝屏死机,那么这已经是Fatal error.

在 Java 应用程序中,事件Error通常Fatal与引发的异常相关联。例子:

class Manager {
    private static final Logger logger = LoggerFactory.getLogger(Manager.class);

    public boolean processTask(Task task) {
        logger.debug("processTask id = " + task.getId());
        try {
            task.start();
            task.progress();
            task.complete();
            return true;
        } catch (Exception e) {
            logger.error("Unknown error", e);
            return false;
        }
    }
}

3.5 记录什么

当然,连续记录所有内容是不值得的。在大多数情况下,这会急剧恶化日志的可读性,毕竟日志首先是为了被读取而写入的。

此外,您不能将各种个人和财务信息写入日志。现在,严格而轻松地执行此操作可能会导致罚款或诉讼。这样的日志迟早会漏到一边,到时候就没有问题了。

那么应该记录什么?

首先,您需要记录应用程序的启动。应用程序启动后,建议记录其运行模式和各种重要设置 - 这将使以后更容易阅读日志。

其次,您需要记录与您的应用程序一起工作的所有第三方服务的状态:邮件系统、任何外部服务。至少,您需要确保与它们的连接时刻安全,以确保它们正常工作。

第三,需要记录所有异常。如果它们是预期的,那么可以紧凑地编写有关它们的信息。在搜索错误时,关于异常的完整信息提供了 50%-80% 的重要信息。

您还需要记录应用程序关闭。应用程序必须正常终止,并且不会在日志中抛出大量错误。通常在这个地方你会发现卡住的任务,线程池的问题,或者删除临时文件的问题。

请务必记录与安全和用户授权相关的所有内容。如果用户连续 10 次尝试登录或重置密码,则此信息应反映在日志中。

尽可能多地记录有关异步任务的信息——异常通常会在此类线程中丢失。对于异步任务,一定要记录它的开始和结束。成功完成的记录方式应与有问题的完成记录方式相同。

还有什么?启动定时任务,启动存储任务SQL-procedures,同步数据,分布式事务相关的一切。我认为这足以作为一个开始。您将来会添加到此列表中。