有许多不同的日志记录库可供选择,每个都有自己的一套怪癖和优势。 (.Net示例:log4net,System.Diagnostics.TraceSource,nLog等)
自然倾向于抽象出那些怪癖并使用伐木立面。 (示例:Castle.Services.Logging,Common.Logging,Simple Logging Facade)这样,如果您使用的给定日志框架过时,或者另一个日常框架变得流行,您只需换出实现并保持代码不变。
但是有多个伐木外墙可供选择。鉴于许多不同的日志记录实现的答案是抽象,为什么不使用日志门面?如果这听起来很荒谬,是什么让它比原始的伐木门面更荒谬?是什么让日志框架之上的一个额外的抽象层成为神奇数字?
答案 0 :(得分:62)
答案 1 :(得分:9)
我认为这使得One(抽象级别)成为神奇数字的原因是Zero太少而且Two太多了。
将记录器交换到记录器外观(级别数:1)可能会带来一些用户利益,例如新的记录器可以执行旧记录器无法执行的操作。我可以想象它可能是性能,支持某些类型的appender等。
很难想象用户从交换记录器外观中获益(级别数:2)。
(如果级别数为0,则可能只是面向对象的设计错误:您的代码中将有数千个位置引用记录器,如果下一个版本中存在重大更改,那该怎么办?记录器。)
与记录器外观的交易似乎是您必须选择其中一个第三方选项或创建自己的选项并准备好长时间坚持使用。
答案 2 :(得分:3)
直到NLog和log4net提供了一个可以用来代替具体类的接口,我总是将它们抽象在我自己的接口和包装类之后。
为什么?
获得所有用户要求的最大测试覆盖率,尤其是当这些要求包括日志记录时。
当您通过接口而不是具体类进行所有日志记录时,使用日志记录界面(选择如何执行此操作,依赖注入等)来提供模拟对象变得非常容易。记录在特定测试场景中进行的所有日志记录调用。
然后可以断言这些,如果代码更改中断了单元测试将覆盖它的日志记录。
如果NLog或log4Net要为他们的记录器提供接口,那么我就不需要去提供接口和包装器类,因为我可以模拟他们的接口进行测试。
答案 3 :(得分:3)
在我的项目中,我使用System.Diagnostics.Trace.TraceError(...)
,System.Diagnostics.Debug.Print(...)
作为记录的外观。为了组织(写入)日志,我使用NLog,即在app.config中我有NLog配置和.net跟踪到NLog的重定向。
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="file" xsi:type="File"
layout="${longdate:universalTime=true}Z [${threadid}] ${pad:padding=5:inner=${level:uppercase=true}} ${logger} ${message}"
fileName="${basedir}/App_Data/logfile.txt"...
</targets>
</nlog>
<system.diagnostics>
<trace>
<listeners>
<add name="nlog" type="NLog.NLogTraceListener, NLog" />
</listeners>
</trace>
</system.diagnostics>
这不会将我捆绑到任何记录器。当我将组件发送给客户时,他们可以使用他们喜欢的任何记录器。在应用程序中使用特定的记录器可能会导致问题,即您可以使用nlog,但您的客户使用log4net。
答案 4 :(得分:1)
这不是神奇的数字,它取决于你想要的灵活性。 如果你想有一天改变日志立面,你应该写一个立面门面。 如果您考虑仅更改日志,则需要一个外观。 如果你没有想到什么都不使用门面。
你说的缺点是特殊能力。如果您正在使用它们,请仅编写自己的外观。
答案 5 :(得分:1)
日志门面的一个重要用途是当您编写图书馆时。在库中嵌入依赖项总是需要一些小心,并且记录更多。
简而言之,您不想强制将您的日志记录实施强加给您的图书馆用户。使用精心挑选的外观意味着他们能够使用自己的选择框架处理您的图书馆日志,并且不必经历一些奇怪的依赖项排除和漏洞,以使您的日志记录成为可能框架和他们共存。
答案 6 :(得分:0)
在此示例中,您只需要一个抽象级别就可以换出记录器。
能够换出日志门面的另外一个优势是什么?
答案 7 :(得分:0)
可用于插件系统的协议。而不是说use Some3rdParty.dll and MyPlugingApi.dll
我只会记录MyPlugingApi.dll
。日志外观界面将建议并记录一些可能会导致可读日志和足够好的日志记录性能的用法。当然,进行更改不会导致插件API的更改。
为什么需要改变实施?如果当前电流似乎从配置开始变慢或写入条目变慢,可能会发生这种情况,希望扩展以减少不需要第三方的.NET版本,与使用其他日志编写器的其他代码库集成。
在这个答案中,我还写了另一个facade,这是思想的孩子。
答案 8 :(得分:0)
我自己并不是专家,但在我们的小组中,外观的价值并不在于让我们能够改变日志框架。没错,这是我们得到的,但我们属于不太可能改变我们框架的类别。
在我们的例子中,我们使用Facade来定制记录接口以满足我们应用程序的需求。我们发现,在我们所看到的所有语义框架中,他们仍然过于关注我们所说的&#34;取证&#34;记录模型 - 有人挖掘日志,寻找一些输出线,试图分析一些事件。
虽然这也是我们的用例,但它实际上不是我们的主要用例。我们需要更多的 instrumentation 框架而不是日志记录框架,这将允许我们报告感兴趣的事物 - 甚至是我们在实施时没有想到的事情。
例如,我们的应用程序不需要&#34;消息&#34;陪同活动;相反,我们的记录器&#34;将接受定义事件类型的枚举和表示特定的状态对象(例如时间戳或其他值),并将序列化这些以便于报告,性能分析,业务价值度量等,除了支持传统的取证之外。 (事实上,我们认识到,对于简单易用且易于理解的日志记录界面来说,传统的取证有点困难,这增加了我们实际使用它并更频繁地使用它的可能性。
因此,为了简明扼要地给您一个总结答案,这是我们使用日志门面所获得的好处的大致排序。
最后,0个外墙将失去这些好处,2个外墙不会增加任何这些好处,所以这就是为什么1门面对我们来说是正确的数字。
很棒的问题,@ brian! :)