我目前正在使用.NET 4.5在WCF中开发一系列Web服务。对于我的日志记录,我选择了log4net框架,但我发现在项目设计中使用它是一个很大的问题。
我将所有内容分成如下项目:
所有服务项目都包含更多服务。
我需要我的日志文件看起来像 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。)
或者是否有任何模式可以让我摆脱这种情况?
答案 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。然后你可以从外面给出一个想要的记录器。