Logging Without a Static Logger

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

你是如何在应用程序中组织日志记录的呢?我指的是Web应用程序、命令行应用程序,甚至是移动应用程序。我敢打赌,你有一个名为Logger的全局变量或者单例对象,它有一些方法,比如info()error()debug()。你在应用程序启动时进行配置,或者通过类似于log4j.properties的方式自动配置,将所有日志记录到控制台、文件甚至数据库中。我多年来一直都是这样做的,或者说非常类似,直到我最终意识到这种方法是多么错误。在我最近的一个Ruby应用程序中,我完全以不同的方式做了,从那以后,我比以前更快乐了。

嗯,如果你的应用程序很简单,几乎没有单元测试或集成测试,使用静态日志记录器是没有问题的,本质上它就是一个全局变量。然而,正如我们之前讨论过的,全局变量是有害的。如果我们使用静态日志记录器会有什么问题呢?换句话说,正如我的一个朋友过去常说的那样,我们要解决的问题到底是什么?基本上,有两个问题:

  • 其次,当您决定向最终用户显示日志的特定部分时,您将不得不进行大量编码,以便将属于用户的内容与不属于用户的内容分离开来,特别是在多线程环境中。如果使用Java且具有线程组,则幸运的是,但是在Ruby中,例如,没有这样的东西,您将不得不找到一些解决方法。

为了克服这两个问题,我在Zold中,一个使用Ruby命令行应用程序,决定将log作为一个变量传递给所有需要日志记录的类。在Ruby中比在Java中更容易,因为它们有可选参数。例如,看看这个类(当然,这是简化版本):

这个类的作用是列出当前目录中的所有钱包,并将它们的余额打印到日志中,在某些情况下会打印到控制台。然而,当这个类从一个网络应用程序中调用时,打印的目标是一个临时文件,然后在网页上呈现。在单元测试中,它可以是其他东西,它必须捕获发送到日志的所有内容,然后传递给单元测试。

正如你看到的,默认值为logLog::NULL,这是我自己定义的常量,作为默认的记录器,它不会在任何地方记录任何内容。默认情况下,这个类不会记录任何内容。它会静静地检查所有钱包的余额并且不会打印任何内容。嗯,它会打印,但没有人会看到。

在一个单元测试中,我创建了一个带有一些方法(如debug()info()等)的对象,并将其传递给我正在测试的Zold::List类的实例。换句话说,它是一个用于捕获Zold::List发送的所有内容的假/模拟日志记录器。然后我可以检查其中的内容。

我在这里说的是显而易见的事情吗?如果是这样,为什么我们在Java、Ruby、PHP、C#等地方仍然处处都有静态记录器呢?无论如何,我建议你使用可注入的日志记录依赖项。

顺便说一下,是的,你肯定注意到了名称的变化。它不再是logger,而是log。我相信你知道为什么。

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-05 at 22:15

sixnines availability badge   GitHub stars