记录和配置系统:循环依赖

时间:2016-03-01 14:12:31

标签: design-patterns language-agnostic

假设在启动时从配置文件加载应用程序的初始设置的典型方案。该应用程序还有一个记录器。记录器的参数(例如,详细程度,日志文件路径等)理想地也存储在配置文件中。但是,还希望配置加载器记录有关参数加载的信息,例如

  

尝试加载参数LogVerbosity。参数不存在。使用默认值:4。

因此,我们看到两个组件之间存在循环依赖关系。配置加载程序需要一个即用型记录器,记录器需要配置参数来初始化自身。在我看来这是一个典型的问题,足以让它有规范的解决方案,但我无法找到任何东西。

当然,人们可以推出一些临时解决方案,但我对最佳行业实践感兴趣。

希望这个问题有道理。

2 个答案:

答案 0 :(得分:3)

我假设您要记录参数,以便稍后能够对其进行调查,例如在出现错误的情况下。显而易见的是,只有将它们保存在文件或其他存储中才有可能。这意味着必须正确配置记录器 才能执行此操作。所以基本问题是:

我们可以假设记录器至少能够记录启动参数吗?

这个案子很简单。我只是:

  1. 读取记录器的配置参数。
  2. 初始化记录器。
  3. 记录记录器的参数。
  4. 阅读其他参数。
  5. 记录其他参数。
  6. 这种情况比较复杂。我认为一个好的解决方案是为记录器使用默认的硬编码参数集。它将保证可以安全地记录启动参数:

    1. 使用默认(硬编码)参数初始化记录器。
    2. 阅读配置参数。
    3. 记录参数。
    4. 根据配置文件中的参数初始化记录器。
    5. 尝试再次记录参数。
    6. 如果记录器的配置正确,您将能够在标准日志位置找到所有参数。如果配置错误,您仍然可以在默认(硬编码)位置找到它们。

      或者,您可以使用fstream等标准机制将启动参数简单地写入文件(在应用程序的工作目录中),而不是在步骤1中使用记录器。

      其他评论

      可以配置某些日志库(如 nlog )( throwExceptions = true ),以便在配置错误时引发错误。然后,操作系统应记录未处理的异常。

      如果您使用此类日志库,则可以启用此选项并使用上面的解决方案1。如果应用程序已启动,那么您将在日志中找到启动参数。如果它没有启动,您应该检查系统日志。

答案 1 :(得分:2)

我认为规范的解决方案是:不要混合日志记录和配置!

想象一下,配置文件解析会触发一个错误(但你还不知道!)。您更改配置文件以启用日志记录。现在解析没有触发错误,一切看起来都正确,直到你再次禁用日志...

所以:更一般地说,原则上,人们希望最大限度地减少调试基础设施(包括日志记录)引入程序的中断;在理想情况下,调试功能将与应用程序执行的任何操作正交,以避免导致 heisenbugs。将正常配置与日志配置混合已经违反了这一原则。

但是根据经验,您可以看到众所周知的日志库如何工作:它们都有自己的配置文件,独立于应用程序中的任何配置,因此您可以更改日志记录行为,而不会弄乱应用程序本身。所以你可以重复一个有问题的应用程序运行,只改变它的日志记录行为,希望没有别的。这就是Log4j及其系列端口或已经提到过的nlog的工作原理。