伐木门面有什么意义?

Bri*_*ian 45 logging design-patterns

有许多不同的日志库可供选择,每个都有自己的一套怪癖和优点.(.Net示例:log4net,System.Diagnostics.TraceSource,nLog等)

自然的倾向是抽象出那些怪癖并使用伐木立面.(示例:Castle.Services.Logging,Common.Logging,Simple Logging Facade)这样,如果您使用的给定日志框架变得陈旧,或者另一个日常框架变得流行,您可以换掉实现并离开代码没有动过.

但是有多个伐木外墙可供选择.鉴于许多不同的日志记录实现的答案是抽象,为什么不使用日志门面?如果这听起来很荒谬,是什么让它比原始的伐木门面更荒谬?是什么让一个额外的抽象层在日志框架之上成为神奇的数字?

wag*_*ghe 65

我将主要从使用抽象来隔离特定日志框架中的应用程序代码的角度来讲.还有其他因素可能影响一个人选择日志框架或一个人对抽象的选择(和要求).

我最近花了很多时间评估各种日志框架以及第三方日志记录抽象.

有些人认为将应用程序代码与特定的日志记录框架隔离开来是有价值的.在这里你会在于是找到很多帖子像这个这个这个(有更多),其中记录了讨论,许多人把它当作理所当然的日志框架应包/抽象.

显然,这允许您不依赖于特定的框架.这很重要吗?你真的会切换你的日志框架吗?嗯,还有很多人要么不提包装,要么推荐反对包装.如果你看一下这里发布的日志框架包装代码的一些例子,你也可以看到很多例子,说明为什么至少有些人不应该包装他们的日志框架!

如果您最近启动了一个项目,那么您可能已经检查了日志框架,并且可能将其缩小为两个最终版本:log4net和NLog.每个人都有自己的观点.log4net显然是最受欢迎的,可能是那些发表意见的人的最爱.NLog提供非常相似的功能.受到人气的影响,log4net可能是明智的选择.基于功能,它们看起来非常相似.基于"最近的活动"(通过博客活动或缺少其源代码存档的签到表示),NLog是明确的选择.如果你必须在一年前选择,你可能会使用log4net,因为它将是"安全"的选择.NLog什么时候发布还不清楚.在那一年,NLog经历了一个非常重要的开发周期,几天前发布了测试版.

一年前选哪个?现在选择哪个?那么一个明显更好的选择吗?现在是一个更好的选择吗?

抽象有一件事就是能够推迟决定选择哪一个(你甚至不一定要选择EVER,尽管如果你计划用你的产品提供日志框架,你可能会想要).您可以测试一个驱动器,然后测试另一个驱动器,并了解它们如何与您的应用程序一起在您的环境中与您的团队一起工作.使用Common.LoggingSLF之类的东西允许您现在开始编写代码,编写一些日志记录接口/ API,并获取日志代码.如果您认为抽象提供的接口/ API足以满足您的工作需求(并且,为什么它不会因为它与log4net和NLog提供的接口/ API基本相同),那么就没有多少使用抽象的危险.在进行开发周期时,您可能会发现一个框架或另一个框架更适合您的需求.编码到抽象后,您可以随时做出选择,直到您的产品出门为止.

您可能会在脑海中想到,您可以从头开始编写日志库.同样,如果您认为log4net和/或NLog的接口/ API已足够,您可以使用类似的API实现日志库.如果您相信这可能是使用抽象的另一个原因.同样,您现在可以开始编写代码(针对您的产品,而不是您的日志库),使用其他日志记录框架进行日志记录,直到您的"从头开始"日志记录库准备就绪为止.也许你真的想使用System.Diagnostics.TraceSource和Ukadc.Diagnostics(以获得类似于log4net或NLog的输出格式化功能),以便您可以与Microsoft使用TraceSources在其某些平台中实现的日志记录进行"更好"的集成.根据TraceSources编写"记录器"然后编写抽象以便将其插入Common.Logging或SLF可能非常容易.(如果接口/ API足够,您可以根据抽象库的接口编写"logger",而不必编写额外的抽象层).

有了这些有说服力的论据,为什么有人不会使用抽象?哈哈,开玩笑吧!

如果抽象是好的,你应该自己编写还是使用现有抽象?如果你自己写一个,那么你显然必须写它.怎么做到这一点?好吧,你可能只是定义一个接口并包装一个框架(小心并正确包装它!).稍后,如果您决定要切换,请包装该框架.如果您小心,则不必更改任何应用程序代码,除非您实际创建基础框架的对象.也许这很好.您已经避免了对某个第三方抽象的依赖,因为在单个框架上实现单个包装器的"小"价格.但是,有一个成本.在编写抽象之前,您无法编写大量已登录的应用程序代码,除非你有一个好的策略来改变它到你的抽象.测试驱动两个或更多框架以决定哪个框架更适合您的工作也变得更加困难.您想要"尝试"的每个框架都需要另一个包装作业.如果您想在框架之间轻松切换(至少在开发周期中),您可以轻松完成工作.第三方框架提供了开箱即用的功能.

哇!现在我卖了!给我记录抽象,或给我死!

伐木抽象都是肉汁吗?有缺点吗?他们不可能那么棒,他们可以吗?

好吧,和往常一样,当"购买"某些东西或获得免费的东西时,你会获得可用的东西.记录抽象也不例外.Common.Logging和SLF都没有公开至少一个非常重要的log4net/NLog功能集 - 日志记录上下文功能(GDC,MDC,NDC).这些对于获取足够的信息进行记录和格式化是关键,这样您就可以从中获得最大价值.SLF不提供TraceSource抽象.它也不提供IsXXXEnabled功能.Common.Logging提供了TraceSource抽象.Castle.Logging DOES为log4net和NLog公开GDC/MDC/NDC.它还提供了TraceSource抽象.Castle的TraceSource抽象还通过提供"分层"命名功能来增强TraceSource日志记录,类似于log4net和NLog提供的功能.

此外,这些项目都是一种形式的开源.因此,根据抽象,开发人员可能或多或少地拥有了保持最新并增加新功能的既得利益.Common.Logging已经过几个版本,在Spring.Net中使用了AFAIK.看似合情合理,至少在历史上如此.Castle.Logging用于Castle框架.因此,他们显然拥有"真正的"客户并且正在使用"真实世界",这有望推动更多功能实施.据我所知,SLF并没有被用作"真正的"开发平台的一部分,所以很难说它运用了多少.

目前尚不清楚这些平台的路线图是什么.Common.Logging在他们的网站上列出了一些即将推出的功能,但不清楚它们何时可用.网站上写着"六月",但是哪一年?邮件列表的监控频率是多少?对于SLF,他们的codeplex多久被监控一次?与开发商的薪酬工作相比,这些"免费"项目的优先级在哪里?您能否承担一些第三方抽象以实现您需要的功能?如果您实施某些内容然后将其提交以考虑包含在产品中,它们是否会接受?

从好的方面来说,所有这些抽象的所有源代码都是可用的,因此您可以承担起所有这些抽象的责任并进行任何修复或添加任何增强功能,而无需花费时间和精力创建抽象.刮.你喜欢Common.Logging但是真的想要log4net/NLog GDC/MDC/NDC吗?获取Castle的实现并将其添加到Common.Logging.瞧!一种日志记录抽象,包含几乎100%的log4net/NLog日志记录API.你喜欢SLF但希望它有IsXXXEnabled吗?没有太多工作来实现它.当你在GDC/MDC/NDC时,继续前进.你喜欢Castle吗?(我不熟悉它,不知道在城堡外面使用是多么容易,如果这很重要的话)小心,我没有用它,但是看看git上的来源,可能不会保留呼叫网站信息.

采用多个开源项目的一部分并将它们组合成一个"超级"项目(供您自己或公司使用)是否合乎道德?采用Common.Logging并使用Castle的GDC/MDC/NDC实现来增强它是不是很糟糕?我不知道.我会让别人回答这个问题.

我快要完蛋了......

某些第三方日志记录抽象提供了其他功能.您可以使用按照log4net实现的库.您可能不想使用log4net,或者至少可能不希望与它绑定.Common.Logging(也许是SLF)使您可以相对轻松地捕获log4net日志记录消息并通过抽象重新路由它们,以便在抽象的底层日志记录框架的日志记录流中捕获它们.SLF可能提供类似的东西.当然,您可以使用现有的日志框架执行类似的操作,既可以开箱即用,也可以编写自定义的log4net Appender,NLog Target或System.Diagnostics TraceListener.

那么,我站在哪里?我认为保持应用程序代码与特定日志框架隔离是有价值的.对我来说,Common.Logging看起来是一个可靠的抽象选择,虽然缺少一些重要的功能(GDC/MDC/NDC)并且它不兼容Silverlight.这些功能很快就会推出.如果必须的话,我很乐意实施GDC/MDC/NDC.使Silverlight兼容可能需要更多的努力,主要是因为我对C#/ .NET/Silverlight不是特别有经验.在解决这些问题之前,我们可以使用Common.Logging编写大量应用程序代码.我们可以花时间开发应用程序,而不是开发另一个日志库或抽象库.如果我们最终不得不自己添加这些缺失的功能,

  • 如此庞大的帖子!我同意一切,肯定是+1,但也许它可以简化/格式化一点?例如,我可以多次看到很多事情.此外,由于这是非常古老的,你对此有任何新见解吗?在此期间有什么变化值得再次讨论吗? (3认同)

azh*_*lov 9

我认为是什么使One(抽象级别)成为神奇的数字是Zero太少而Two太多了.

在记录器外观后面交换记录器(级别数:1)可能会带来一些用户利益,例如新记录器可以执行旧记录器无法执行的操作.我可以想象它可能是性能,支持某些类型的appender等.

很难想象用户从交换记录器外观中获益(级别数量:2).

(如果级别数为0,则可能只是面向对象的设计错误:您的代码中将有数千个位置引用记录器,如果下一版本的记录器发生了重大变化,那该怎么办? )

与记录器外观的交易似乎是你必须选择一个第三方选项或创建自己的选项并准备好长时间坚持使用它.


chr*_*eml 5

日志外观的一个重要用途是在您编写库时。在库中嵌入依赖项总是需要一些小心,记录更是如此。

简而言之,您不希望将您的日志记录实施强加给您的库用户。使用精心挑选的外观意味着他们将能够使用自己选择的框架处理您库的日志,而不必通过一些奇怪的依赖排除和漏洞来使您的日志记录框架和它们的共存。