log4Net 困境
我有一个包含多个 C# 项目的 C# 解决方案。我打算在其中添加登录功能。此日志记录应该在所有项目中可用,并且最好使用带有滚动文件日志的 log4Net。
有了上述前提,我可以想到两种方法来做到这一点。
在解决方案的入口点(程序类)初始化记录器获取记录器实例&将其用作每个需要日志记录的类的成员变量。
添加另一个项目,实用程序和应用程序。使用静态日志记录方法定义 Logging 类。此类应在解决方案的入口点(程序类)中初始化。
最好的解决方案是什么?
I have a C# solution containing multiple C# projects. 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.
With the above said premise, I could think of two ways to do that.
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.
Add another project, Utilities & define a Logging class with static logging methods. This class should be initialized in entry point (Program class) of the solution.
What could be the best possible solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我也有类似的情况。我们所做的是为所有项目使用 1 个应用程序配置,并使用链接来引用它。
在您的应用程序的 app.config 中,您设置 log4net config 部分
,然后设置 Appender:
在您想要记录的每个类中,您放置与此类似的行:
然后每个类获取相同的记录器(单例)。
这对你有用吗?
I have a similar situation. What we've done is use 1 app config for all the projects and use links to reference it.
In the app.config for your app you set the log4net config Section
And later set the Appender:
And in each class you want to log you put a line similar to this:
Then each class grabs the same logger (singleton).
Would that work for you?
在我的项目中,我围绕 LOG4NET 编写了一个包装器,以便(理论上)将其与 NLOG 等其他日志框架进行交换,而不会破坏我的代码。
我自己的日志记录类可以通过静态单例访问。它在这个单例中进行初始化。
(顺便说一句:我不久前在代码项目上发布了源代码,或许能给你一些启发)
In my projects, I wrote a wrapper around LOG4NET to (theoretically) exchange it with other logging frameworks like NLOG without breaking my code.
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)
如果您每次都考虑在入口点初始化某些内容,那么您就是在为自己编写一个依赖注入的案例。使用 DI 库(例如 Unity、Castle 或您个人喜欢的任何风格),您可以执行构造函数注入或属性注入来自动初始化记录器类(或 Log4Net)。
此外,您可以使用 DI 内核使其成为单例,这样您就只有一个活动实例。
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.
Additionally, you can use the DI kernel to make it a singleton, so that you only have one instance of it active.
基于 Queso 的答案,我们有了在运行时通过反射导入的 .dll。为了让他们使用 Log4Net,我们创建了一个包含所有适当配置部分的 log4net.config 文件。我们还使用同一行代码来初始化 Queso 引用的每个类中的日志。单独的配置允许我们在整个应用程序域中使用它。
编辑我们还必须对应用程序设置文件进行修改才能实现此目的。
http://haacked.com/archive/2005/03/07/ConfiguringLog4NetForWebApplications.aspx
Building off of Queso's answer, we had .dll's that were imported with reflection at runtime. In order to get them to use Log4Net we created a log4net.config file with all the appropriate config sections. We also used the same line of code to intialize the log in each class that Queso references. 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.
http://haacked.com/archive/2005/03/07/ConfiguringLog4NetForWebApplications.aspx
选项 1 是可行的方法。
如果您使用静态方法,您将失去使用分层记录器的能力。此功能允许您为各个类甚至整个子系统(例如
YourNameSpace.Security
)配置不同的日志输出。这个教程详细介绍了这个主题(其他章节也值得一读)。构建包装器当然不是一个坏主意,但并不是绝对必要的。但它确实允许做一些事情:更改日志框架、使用 DI、添加额外的日志级别(例如 log.Verbose())或不同的日志记录重载...
顺便说一句。我会像这样初始化记录器:
Option 1 is the way to go.
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 e.g.
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 (e.g. log.Verbose()) or different overloads for logging...
Btw. I would initialize the loggers like this: