使用log4net进行n层日志记录存在问题
本文关键字:记录 存在 问题 日志 log4net 进行 使用 | 更新日期: 2023-09-27 18:18:03
我目前正在使用。net 4.5在WCF中开发一系列web服务。对于我的日志记录,我选择了log4net框架,但我发现在我的项目设计中使用它是个大问题。
我把所有的东西分成这样的项目:
- DataAccess 共同
- 等。等。
- ExternalServicesContracts
- ExternalServices
- ExternalServicesProxies
- InternalService
所有的服务项目包含更多的服务。
<标题> 情况我需要我的日志文件看起来像这样ServiceName_YYYY_DDMM.log。
所以在log4net配置文件中,我需要在web服务的每个名称空间中使用不同的记录器。我可以通过使用这样的记录器来实现它:
第一个服务:
private static readonly ILog Log = LogManager.GetLogger(typeof(MyFirstService));
第二个服务也是如此:
private static readonly ILog Log = LogManager.GetLogger(typeof(MySecondService));
然后在配置文件中,我只是通过记录器指向它们
<logger name="ExternalServices.MyFirstService">
<appender-ref ref="FirstServiceAppender"/>
</logger>
<logger name="ExternalServices.MySecondService">
<appender-ref ref="SecondServiceAppender"/>
</logger>
<appender type="log4net.Appender.RollingFileAppender" name="FirstServiceAppender">
<file value="c:'temp'FirstService"/>
<rollingStyle value="Composite" />
<datePattern value="_yyyy_MM_dd.lo'g"/>
<maxSizeRollBackups value="-1"/>
<maximumFileSize value="100MB"/>
....
</appender>
<appender type="log4net.Appender.RollingFileAppender" name="SecondServiceAppender">
<file value="c:'temp'SecondService"/>
<rollingStyle value="Composite" />
<datePattern value="_yyyy_MM_dd.lo'g"/>
<maxSizeRollBackups value="-1"/>
<maximumFileSize value="100MB"/>
....
</appender>
<标题>在此更改之后,我无法从我的DataAccess和Common中看到任何内容,因为我必须对层内的类执行相同的策略。
那么记录器将以同样的方式加载,如下所示:
private static readonly ILog Log = LogManager.GetLogger(typeof(UsersProvider));
我可以为两个项目添加另一个记录器,但我需要从它的日志写入同一个文件(调用者使用的日志文件)。
<标题>由于客户的原因,我真的不能把服务分成更多的项目。是否有一种方法可以在调用者使用的库中使用相同的记录器?(因此,当服务使用它时,DataAccess和Common将日志写入FirstServiceAppender)
或者有什么模式可以让我摆脱这种情况?
标题>标题>标题>我现在没有时间尝试这个,但这应该比您想象的更容易。您可以尝试配置log4net,使其具有基于GlobalContext的动态文件名。属性值。在每个服务中,放置一个值GlobalContext。为服务"命名"的属性。这应该没有问题,因为每个服务本质上都是一个独立的进程,所以使用GlobalContext应该不会导致任何冲突。这样,您将只需要一个文件目标,并且您的日志记录器可以非常简单地配置(只需将输出发送到一个文件目标)。
配置应该是这样的:
<appender type="log4net.Appender.RollingFileAppender" name="RollingFileAppender">
<file type="log4net.Util.PatternString" value="C:'temp'%property{Service}"/>
<rollingStyle value="Composite" />
<datePattern value="_yyyy_MM_dd.log"/>
<maxSizeRollBackups value="-1"/>
<maximumFileSize value="100MB"/>
....
</appender>
<root>
<appender-ref ref="RollingFileAppender" />
</root>
在您的代码中,当每个服务初始化时,放入如下内容:
GlobalContext.Properties["Service"] = "FirstService"; // for FirstService
GlobalContext.Properties["Service"] = "SecondService"; // for SecondService
注意,必须将值设置为GlobalContext。属性在使用log4net完成任何其他操作之前。最好的位置是在应用程序/服务的静态构造函数中。
该配置应该将"FirstService"中生成的所有日志写入FirstService日志文件,并将"SecondService"中生成的所有日志写入SecondService日志文件。
更新:<appender name="DynamicRollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="c:'temp'%property{Service}" />
<datePattern value="_yyyy_MM_dd.lo'g" />
<appendToFile value="true" />
<maxSizeRollBackups value="-1" />
<maximumFileSize value="5000KB" />
<preserveLogFileNameExtension value="true"/>
<staticLogFileName value="false" />
<countDirection value="1"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%method] - %message%newline" />
</layout>
</appender>
您可以将logger作为类的参数传递。因此,也许您的DataAccess类应该将记录器作为构造函数参数,并将其用于登录。然后,您可以从外部提供所需的记录器。