使用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进行n层日志记录存在问题

我现在没有时间尝试这个,但这应该比您想象的更容易。您可以尝试配置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类应该将记录器作为构造函数参数,并将其用于登录。然后,您可以从外部提供所需的记录器。