记录门面的要点是什么? [英] What's the point of a logging facade?

查看:117
本文介绍了记录门面的要点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



自然倾向是抽象出这些怪癖,并使用日志门面。 (例如: Castle.Services.Logging Common.Logging 简单日志门面)这样,如果您使用的给定的日志记录框架陈旧,或者其他日志框架变得流行,那么您只需将实现并保留代码不变。



但是有多个登录界面可供选择。鉴于许多不同的日志记录实现的答案是抽象的,为什么不使用日志记录外观立面?如果这听起来很可笑,究竟是什么让它比原来的录音门面更可笑?什么使一个额外的抽象层在采伐框架之上的魔术数字?

解决方案

我将主要从使用抽象将应用程序代码与特定的日志框架隔离开来。还有其他一些因素可能会影响到日志框架的选择,或者是对抽象的选择(和要求)。



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



有些人认为在将应用程序代码与特定日志记录框架隔离开来方面有价值。你会在这里找到很多帖子,如这个这个这个(还有更多)讨论了日志记录,许多人把它当成是应该包装/抽象的日志框架。



显然,这样可以让您不受特定框架的限制。这很重要吗你真的会切换你的日志框架吗?那么,还有很多人不要提包,还是那些反对的人。如果你看一下这里发布的一些日志框架包装代码的例子,你还可以看到很多例子,至少有些人不应该包装他们的日志框架!



如果您最近开始了一个项目,您可能已经检查了日志记录框架,也许将其缩小为两个入围:log4net和NLog。每个人都有争议。 log4net显然是最受欢迎的,也许是那些表达意见的人的最爱。 NLog提供非常相似的功能。以受欢迎程度判断,log4net可能是明确的选择。基于能力,他们似乎非常相似。根据最近的活动(如通过博客活动或缺少访问者对其源代码重新签名所示),NLog成为明确的选择。如果你一年前不得不选择,你可能会跟log4net一起去,因为它将是安全的选择。 NLog会释放不清楚。在这一年以来,NLog已经经历了一个非常重要的开发周期,几天前发布了一个测试版。



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



抽象获得你的一件事是放弃决定哪一个选择的能力(你不一定甚至没有选择EVER,虽然您可能想要,如果您计划提供与您的产品的日志框架)。您可以测试一个驱动器,然后测试其他驱动器,并了解如何与您的应用程序一起工作,与您的团队在您的环境中。使用类似 Common.Logging SLF 允许您开始编写代码,编码到某些日志记录接口/ 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,他们的代码监控的频率是多少?这些免费项目的优先次序与开发商的付费工作相比有何优点?你能负担一些第三方抽象来实现你需要的功能吗?如果您实施某些内容,然后将其提交回来考虑纳入产品,他们会接受吗?



在这方面,所有这些抽象可用,所以您可以承担责任,并进行任何修复或添加任何增强功能,而无需经历时间和精力从头开始创建抽象。你喜欢Common.Logging,但真的想要log4net / NLog GDC / MDC / NDC?获取Castle的实现并将其添加到Common.Logging中。瞧!一个日志记录抽象,包含近100%的log4net / NLog日志记录API。你喜欢SLF,但希望它有IsXXXEnabled?没有多少工作要实施。在您参加GDC / MDC / NDC的时候,继续努力。你喜欢城堡吗(我不熟悉它,不知道在城堡之外使用它是多么容易,如果重要)请小心,我没有使用它,但看git的源代码,它看起来像NLog记录器抽象可能不会保留呼叫站点信息。



是否遵守多个开放源码项目的部分内容,并将其组合成一个超级项目(为您自己或贵公司使用)?使用Castle的GDC / MDC / NDC实现来扩展Common.Logging是不是很糟糕?我不知道。我会让别人回答。



我已经完成了...



有些第三方记录抽象提供其他功能。您可以使用按照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编写大量的应用程序代码。我们可以花时间开发我们的应用程序,而不是开发另一个日志库或抽象库。如果我们最终不得不自己添加这些缺少的功能,那么如果我们自己实现了一个日志库或抽象库,那么我们不得不做很多。


There are a bunch of different logging libraries to choose from, each with their own set of quirks and advantages. (.Net examples: log4net, System.Diagnostics.TraceSource, nLog, etc.)

The natural inclination is to abstract away those quirks and use a logging facade. (examples: Castle.Services.Logging, Common.Logging, Simple Logging Facade) That way, if a given logging framework that you're using goes stale, or a different one comes into vogue, you can just swap out the implementation and leave the code untouched.

But there are multiple logging facades to choose from. Given that the answer to many disparate logging implementations was abstraction, why not use a logging facade facade? If that sounds ridiculous, what makes it more ridiculous than the original logging facade? What makes one extra layer of abstraction on top of the logging framework the magic number?

解决方案

I will speak mainly from the perspective of using the abstraction to insulate application code from a particular logging framework. There are other factors that can affect one's choice of logging framework or one's choice of (and requirements for) an abstraction.

I have spent a lot of time recently evaluating various logging frameworks as well as third party logging abstractions.

Some people feel there is value in insulating their application code from a specific logging framework. You will find many posts here on SO like this and this and this(and there are more) where logging is discussed and many people take it as a matter of course that the logging framework should be wrapped/abstracted.

Obviously, this allows you to not be tied to a specific framework. Is this important? Will you ever really switch out your logging framework? Well, there are also plenty of people who either don't mention wrapping or those who recommend against it. If you look at some of the examples of logging framework wrapping code that has been posted here, you can also see many examples of why at least some people should not wrap their logging framework!

If you had started a project recently, you might have examined logging frameworks and, perhaps, narrowed it down to two finalists: log4net and NLog. Each has arguments in its favor. log4net is clearly a favorite, probably THE favorite of those who have expressed an opinion. NLog provides very similar capabilities. Judged by popularity, log4net might be the clear choice. Based on capabilities, they seem very similar. Based on "recent activity" (as indicated by checkins to their source code repostories by blog activity or lack thereor), NLog be the clear choice. If you had to pick a year ago, you might go with log4net since it would be the "safe" choice. It was not clear when NLog would release. In the year since, NLog has gone through a pretty signifcant development cycle, releasing a beta version just a few days ago.

Which to choose a year ago? Which to choose now? Was one a clearly better choice then? Is one the better choice now?

One thing an abstraction gets you is the ability to put off the decision of which one to choose (you don't necessarily even HAVE to choose EVER, although you probably want to if you plan to deliver the logging framework with your product). You can test drive one and then the other and get a feel for how they work with your application, with your team, in your environment. Using something like Common.Logging or SLF allows you start writing code now, coding to some logging interface/API, and getting your logging code in place. If you believe that the interface/API is provided by the abstraction is sufficient for your work (and, why wouldn't it be since it is essentially the same as the interface/API provided by log4net and NLog), then there is not much danger in using the abstraction. As you go through the development cycle, you might find that one framework or the other better suits your needs. Having coded to the abstraction, you are free to make that choice at any point, up until the time your product goes out the door.

You might even be thinking, in the back of your mind, that you could possibly write a logging library from scratch. Again, if you believe that the interface/API of log4net and/or NLog is sufficient, you might implement your logging library with a similar API. If you believe that, that might be another reason to use an abstraction. Again, you can start writing code (for your product, not your logging library) today, logging with some other logging framework until such time that your "from scratch" logging library is ready. Maybe you really want to use System.Diagnostics.TraceSource and Ukadc.Diagnostics (to get output formatting capabilities similar to log4net or NLog) so that you can get "better" integration with the logging that Microsoft has implemented in some of their platforms using TraceSources. It could be pretty easy to write a "logger" in terms of TraceSources and then write the abstraction so that you could plug it into Common.Logging or SLF. (If the interface/API is sufficient, you could just write your "logger" in terms of the abstraction library's interface and not have to write an additional abstraction layer).

With such persuasive arguments as these, why would anyone ever NOT use an abstraction? Ha ha, just kidding!

If an abstraction is good, should you write your own or use an existing one? If you write one on your own, then you obviously have to write it. How does one do this? Well, you might just define an interface and wrap one framework (be careful and wrap it correctly!). Later, if you decide you want to switch, wrap that framework. If you are careful, you don't have to change any application code, except for maybe the place where you actually create the underlying framework's objects. Maybe this is good. You have avoided a dependency on some third party abstraction for the "small" price of implementing a single wrapper over a single framework. However, there is a cost. Until you have written your abstraction you cannot really write a lot of application code that has logging in it, unless you have a good strategy for changing it over to your abstraction. It also becomes more difficult to test drive two or more frameworks to decide which works better for your. Each framework that you want to "try" requires another wrap job. If you want to switch among frameworks easily (at least during development cycle), you have work to do to make it easy. The third party frameworks provide this out of the box.

Wow! Now I'm sold! Give me logging abstraction, or give me death!

Are logging abstractions all gravy? Is there a downside? They can't THAT great, can they?

Well, as always, when "buying" something or when getting something free, you get what is available. Logging abstractions are no different. Neither Common.Logging nor SLF expose at least one very important set of capabilities of log4net/NLog - the logging context capabilities (GDC, MDC, NDC). These can be key to getting adequate information logged and formatted to enable you to get the most value from your. SLF does not provide a TraceSource abstraction. It also does not provide IsXXXEnabled functions. Common.Logging provides a TraceSource abstraction. Castle.Logging DOES expose GDC/MDC/NDC for log4net and NLog. It also provides a TraceSource abstraction. Castle's TraceSource abstraction also enhances TraceSource logging by providing a "hierarchical" naming capability, similar to that provided by log4net and NLog. It looks pretty cool!

Also, these projects are all opensource of one form or another. So, depending on the abstraction, the developers might have more or less of a vested interest in keeping it up to date and adding new features. Common.Logging has been through a few versions and is used, AFAIK, in Spring.Net. Seems reasonbly active, at least historically. Castle.Logging is used in the Castle framework. So, they apparently have "real" customers and are getting "real world" usage, which will hopefully drive more feature implementation. SLF, as far as I can tell, is not used as part of a "real" development platform, so it is hard to tell how much it is exercised.

It is not clear what the roadmap is for these platforms. Common.Logging has some upcoming features listed on their website, but not clear indication when they will be available. The website says "June", but of what year? How often is the mailing list monitored? For SLF, how often is their codeplex monitored? Where does the priority of these "free" projects rate compared to the developers' paying jobs? Can you afford for some third party abstraction to implement a feature that you need? Will they be receptive if you implement something and then submit it back for consideration to be included in the product?

On the plus side, all of the source for all of these abstractions is available, so you could just assume responsibility for it and make any fixes or add any enhancements that you which, without having to go through time and energy of creating an abstraction from scratch. Do you like Common.Logging but really want log4net/NLog GDC/MDC/NDC? Get Castle's implementation and add it to Common.Logging. Voila! A logging abstraction that contains nearly 100% of the log4net/NLog logging API. Do you prefer SLF but wish it had IsXXXEnabled? Not much work to implement that. Go ahead and tack on the GDC/MDC/NDC while you are at it. Do you like Castle? (I'm not that familiar with it, not sure how easy it is to use outside of Castle, if that matters) Be careful, I haven't used it, but looking at the source on git, it looks like the NLog logger abstraction might not retain call site info.

Is it ethical to take parts of multiple open source projects and combining them to make one "super" project (for your own or your company's use)? Is it bad to take Common.Logging and augment it with Castle's GDC/MDC/NDC implementation? I don't know. I'll let someone else answer that.

I'm nearly finished...

Some third party logging abstractions provide other capabilities. You might use a library that is implemented in terms of, say log4net. You might not want to use log4net, or at least might not want to be tied to it. Common.Logging (and maybe SLF) makes it relatively easy for you to capture the log4net logging messages and reroute them through the abstraction so they are captured in the abstraction's underlying logging framework's logging stream. SLF might provide something similar. Of course, you might be able to do something similar with existing logging frameworks, either out of the box or by writing a custom log4net Appender, NLog Target, or System.Diagnostics TraceListener. These features have not bubbled up very high in my particular evaluation of whether or not to use a third party logging abstraction on my project because I am mainly interested simply in the abstraction aspect.

So, where do I stand? I think that there is value in keeping your application code insulated from a specific logging framework. To me, Common.Logging looks like a solid choice of abstraction, although some important features are missing (GDC/MDC/NDC) and it is not Silverlight compatible. It would great of those features became available soon. I am comfortable with implementing GDC/MDC/NDC if I have to. Making it Silverlight compatible would probably take more effort, primarily because I am not particularly experienced with C#/.NET/Silverlight. Until those issues are ironed out, we would be able to write plenty of application code with Common.Logging in place. We can spend our time developing our application rather than developing yet another logging library or abstraction library. If we end up having to add those missing features ourselves, well, we would have had to do a lot of that if we had implementing a logging library or abstraction library ourselves.

这篇关于记录门面的要点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆