使用log4net进行有问题的N层日志记录

时间:2014-08-13 16:58:54

标签: c# wcf log4net

我目前正在使用.NET 4.5在WCF中开发一系列Web服务。对于我的日志记录,我选择了log4net框架,但我发现在项目设计中使用它是一个很大的问题。

我将所有内容分成如下项目:

  • 数据访问
  • 通用
  • 等。等
  • 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>

在appenders中

<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。)

或者是否有任何模式可以让我摆脱这种情况?

2 个答案:

答案 0 :(得分:2)

我现在没有时间尝试这个,但这应该比你想象的要容易。您可以尝试将log4net配置为具有基于GlobalContext.Properties值的动态文件名。在每个服务中,放置一个值GlobalContext.Properties&#34; names&#34;服务。这应该没问题,因为每个服务本质上都是一个单独的进程,因此使用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

请注意,在使用log4net完成任何其他操作之前,必须将值设置为GlobalContext.Properties。最好的地方是应用程序/服务的静态构造函数。

此配置应该在&#34; FirstService&#34;中生成所有日志。写入FirstService日志文件以及在&#34; SecondService&#34;中生成的所有日志写入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>    

答案 1 :(得分:1)

您可以将logger作为类的参数传递。因此,您的DataAccess类可能会将记录器作为构造函数参数并将其用于loggin。然后你可以从外面给出一个想要的记录器。

相关问题