包装第三方日志程序(如log4net)时要考虑的设计原则

本文关键字:原则 日志 第三方 程序 log4net 包装 | 更新日期: 2023-09-27 18:14:06

我正在为一家公司创建一个日志记录器,该公司有几种类型的。net项目(Windows服务,ASP。. NET等),我正在考虑使用log4net作为我的记录器,但我不想嫁给log4net,所以我想把它包装在我自己的程序集中。我意识到一些开发人员不建议包装log4net,因为这将是一个反模式,但假设我无论如何都要走这条路,我有一些问题:

我计划使用本文中提到的设计原则来设计我的包装器(使用工厂方法、接口和反射,我可以通过在配置文件中指定来简单地决定我想使用哪个记录器(无论是log4net、elmah还是其他东西):https://www.simple-talk.com/dotnet/.net-framework/designing-c-software-with-interfaces/

问题是:

  • 我应该在一个单独的Visual Studio解决方案中创建这个记录器项目,然后在我的客户端应用程序中使用dll吗?如果是这样,log4net的配置细节应该放在哪里?这是由客户端应用程序的配置文件提供吗?如果是这样,这是好的设计吗?例如,如果我决定从log4net切换到不同的日志框架,我不仅必须更改配置设置以指定新的具体日志记录器的程序集/类名,而且还必须删除log4net配置项(可能还需要添加新的日志记录器的配置项)。这是一种可接受的设计方法吗?

包装第三方日志程序(如log4net)时要考虑的设计原则

天哪,你的时机真是太棒了。那篇文章和我非常相关,谢谢!我现在也在做同样的事情。我意识到log4net是一个不错的日志记录器,但是对于制作日志记录器来说是一个糟糕的库。

我同意这篇文章,因为您不应该直接暴露给log4net。除非这是一个小的应用程序,否则以后很难切换。而log4net正在显示年龄,所以这可能会发生。总的来说,我喜欢界面方法。

但是,包装log4net是一个痛苦的屁股。所以在制作我的原型包装器时,我感觉我重写了50%的log4net,并丢弃了25%。我发现了一些问题:

  1. log4net将为您抓取"调用者信息"。通常这很好。但是如果包装log4net,调用者信息将指向您的记录器。所以你必须自己明确地获取它。但是log4net不提供覆盖调用者信息的方法。因此,现在必须为调用者的文件、行号、类和包创建自己的字段。因此,您不仅没有从中受益,而且实际上比您自己做更多的工作。
  2. Log4net使用旧的c# -4.0之前的方法来抓取调用者信息,这是缓慢的。
  3. 如果不包装配置,您将无法完全包装log4net。调用者必须在代码或他们的app.config中配置记录器。如果他们在他们的app.config中这样做,那么他们将log4net特定的东西放在他们的应用程序中,所以你无法用包装器隐藏它。但是,如果您让包装器代码自动执行配置,那么您就失去了log4net的灵活性。第三种选择是进行自己的配置,但是log4net对您有什么好处呢?你刚刚又重写了一段。
  4. 您只能使用log4net自带的日志级别。在我们的应用程序中,我们需要"类别"而不是"级别",然后我必须将其映射到log4net下的"级别"。现在,所有预定义的log4net过滤器对我来说都没有用。
  5. 无论如何,任何使用您的包装器的人仍然必须在他们的项目中引用log4net。
  6. 如果您的包装器需要一种方法来处理错误,或者将它们传递给调用者,您将遇到麻烦。Log4net有它自己的内部错误处理,您需要钩到它并提供您自己的错误处理。否则,错误(如配置错误的appender)将直接输出到控制台。如果它被设计成一个用于制作记录器的库,它只会抛出异常或提供一个简单的事件。

我们想从log4net中得到的一件事是能够编写不同的输出,而无需我们自己编写代码。我从来没有写过事件日志,我认为log4net可以做到这一点。但是,对我来说,去掉事件日志代码可能比尝试包装它更容易。过滤器也是一样。

我在log4net中遇到了一些其他问题,这些问题与尝试包装它没有直接关系。

  1. 代码陈旧。接口没有在应该使用泛型的地方使用泛型。很多对象。
  2. 他们使用旧系统。集合集合。与#1类似。
  3. 它有。net 1和。net 2的ifdefs,以及过时的紧凑框架的ifdefs。嗯。
  4. 它被设计为记录字符串,而不是结构化对象。我做了自己的代码来做这件事,这些人也做了:http://stephenjamescode.blogspot.com/2014/01/logging-custom-objects-and-fields-with.html和http://element533.blogspot.com/2010/05/mapping-message-object-properties-to.html,但这感觉像是基本的功能。
  5. 它不支持CSV,添加起来很麻烦。http://element533.blogspot.com/2010/05/writing-to-csv-using-log4net.html
  6. 没有任何类型的日志"服务"
  7. 不提供读取或解析日志的方法。
  8. 我发现配置appender比编写自己的appender更费力。例如:我将一堆字段映射到AdoNetAppender,但它会花费我更少时间来重写AdoNetAppender。调试XML中的数据库字段映射比调试等价的c# + ADO更难。NET代码。XML更冗长,类型安全性更差。这可能是特定于我的,因为我有一个非常结构化的数据集和许多字段。

很抱歉写了这么长的文章,我对这个话题有很多很多的想法。我并不是真的不喜欢log4net,我只是觉得它过时了,如果你要包装它,你最好自己写一个。