简体   繁体   English

log4Net困境

[英]log4Net dilemma

I have a C# solution containing multiple C# projects. 我有一个包含多个C#项目的C#解决方案。 I am planning to add logging in it. 我打算在其中添加日志记录。 This logging should be available in all the projects and preferably use log4Net with rolling file logs. 此日志记录应该在所有项目中都可用,并且最好使用带有滚动文件日志的log4Net。

With the above said premise, I could think of two ways to do that. 有了上述前提,我可以想到两种方法。

  1. Initialize logger in entry point (Program class) of the solution & Get the logger instance & use it as a member variable for every class that needs logging. 在解决方案的入口点(程序类)中初始化记录器并获取记录器实例并将其用作需要记录的每个类的成员变量。

  2. Add another project, Utilities & define a Logging class with static logging methods. 添加另一个项目,Utilities并使用静态日志记录方法定义Logging类。 This class should be initialized in entry point (Program class) of the solution. 该类应该在解决方案的入口点(程序类)中初始化。

What could be the best possible solution? 什么是最好的解决方案?

I have a similar situation. 我有类似的情况。 What we've done is use 1 app config for all the projects and use links to reference it. 我们所做的是为所有项目使用1 app config并使用链接来引用它。

In the app.config for your app you set the log4net config Section 在app的app.config中,设置log4net config部分

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>

And later set the Appender: 后来设置了Appender:

<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
...

And in each class you want to log you put a line similar to this: 在每个要记录的课程中,你都会添加一行类似于:

private static readonly ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

Then each class grabs the same logger (singleton). 然后每个类抓取相同的记录器(单例)。 Would that work for you? 这对你有用吗?

In my projects, I wrote a wrapper around LOG4NET to (theoretically) exchange it with other logging frameworks like NLOG without breaking my code. 在我的项目中,我编写了一个围绕LOG4NET的包装器(理论上)将其与其他日志框架(如NLOG)交换而不会破坏我的代码。

My own logging class is accessible through a static singleton. 我自己的日志类可以通过静态单例访问。 It does initialization in this singleton. 它在这个单例中进行初始化。

(BTW: I published the source code over at the Code Project some time ago, maybe it gives you some inspiration) (顺便说一下前一段时间在代码项目上发布了源代码 ,也许它会给你一些灵感)

If you're thinking about initializing something at the entry point every single time, then you're writing yourself a case for dependency injection. 如果您正在考虑每次在入口点初始化某些东西,那么您将自己编写一个依赖注入案例。 Using a DI library (like Unity, Castle, or whatever flavor you personally like), you could do either constructor injection or property injection to get your logger class (or Log4Net) initialized automatically. 使用DI库(如Unity,Castle或您喜欢的任何风格),您可以执行构造函数注入或属性注入以自动初始化您的记录器类(或Log4Net)。

Additionally, you can use the DI kernel to make it a singleton, so that you only have one instance of it active. 此外,您可以使用DI内核使其成为单例,这样您只有一个活动实例。

Building off of Queso's answer, we had .dll's that were imported with reflection at runtime. 基于Queso的答案,我们在运行时使用反射导入了.dll。 In order to get them to use Log4Net we created a log4net.config file with all the appropriate config sections. 为了让他们使用Log4Net,我们创建了一个包含所有相应配置部分的log4net.config文件。 We also used the same line of code to intialize the log in each class that Queso references. 我们还使用相同的代码行来初始化Queso引用的每个类中的日志。 The seperate config allowed us to use it throughout the entire app domain. 单独的配置允许我们在整个应用程序域中使用它。

EDIT we also had to make a modifcation to the appsettings file to allow for this. 编辑我们还必须对appsettings文件进行修改以允许这样做。

http://haacked.com/archive/2005/03/07/ConfiguringLog4NetForWebApplications.aspx http://haacked.com/archive/2005/03/07/ConfiguringLog4NetForWebApplications.aspx

Option 1 is the way to go. 选项1是要走的路。

If you use static methods you loose the ability to use hierarchical loggers. 如果使用静态方法,则无法使用分层记录器。 This feature allows you to configure your log output differently for individual classes or even for entire sub systems eg YourNameSpace.Security . 此功能允许您为各个类甚至整个子系统(例如YourNameSpace.Security配置不同的日志输出。 This tutorial elaborates on this topic (also the other chapters are a good read). 教程详细阐述了这一主题(其他章节也很好阅读)。

Building a wrapper is certainly not a bad idea, but it is not strictly necessary. 构建包装器当然不是一个坏主意,但并不是绝对必要的。 It does allow for a few things though: change log framework, use DI, add additional log levels (eg log.Verbose()) or different overloads for logging... 它确实允许一些事情:更改日志框架,使用DI,添加额外的日志级别(例如log.Verbose())或不同的重载用于记录...

Btw. 顺便说一句。 I would initialize the loggers like this: 我会像这样初始化记录器:

ILog log = LogManager.GetLogger(typeof(YourClass));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM