log4net和每个线程的唯一日志文件

时间:2013-11-08 22:07:41

标签: c# log4net

我有一个接收WCF请求的Windows服务进程。对于每个请求,它会创建一个可以完成某些工作的新线程。我想为主机进程创建一个日志文件,并为每个线程实例分隔唯一的日志文件。例如,我希望日志文件类似于'%date {yyyyMMdd} _%property {UniqueId} .log'。这是我到目前为止所拥有的。

<appender name="ThreadAppender" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="c:\Logs\%date{yyyyMMdd}\%date{HHmmss}_%property{FileID}.log"/>
      <appendToFile value="true"/>
      <maxSizeRollBackups value="10"/>
      <maximumFileSize value="10MB"/>
      <rollingStyle value="Size"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <header value="[Header]
"/>
        <footer value="[Footer]
"/>
        <conversionPattern value="[%date] [%thread] [%-5level] %logger  - %message%newline"/>
      </layout>
    </appender>
    <appender name="ServiceAppender" type="log4net.Appender.RollingFileAppender">
      <file value="C:\Logs\Service.log"/>
      <appendToFile value="true"/>
      <maxSizeRollBackups value="10"/>
      <maximumFileSize value="10MB"/>
      <rollingStyle value="Size"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <header value="[Header]
"/>
        <footer value="[Footer]
"/>
        <conversionPattern value="[%date] [%thread] [%-5level] %logger  - %message%newline"/>
      </layout>
    </appender>
    <root>
      <level value="ALL"/>
      <appender-ref ref="ThreadAppender"/>
    </root>
    <logger name="ServiceLogger" additivity="false">
      <level value="INFO"/>
      <appender-ref ref="ServiceAppender"/>
    </logger>

然后,在我的帖子中,我使用LogicalContext.Properties["FileID"] = <some id>。 我在assemblyinfo.cs文件中也有[assembly: log4net.Config.XmlConfigurator(Watch = true)]行。

一切都近乎工作:)。一个问题是,当我启动Windows服务时,它会自动创建新的%date {HHmmss} _(null).log文件。我需要配置什么才能使log4net不创建这个虚拟文件?另外,我是否需要为ServiceAppender和ThreadAppender指定文件锁定?

2 个答案:

答案 0 :(得分:1)

由于并发问题,该代码无法按预期工作。 log4net.Config.XmlConfigurator.Configure强制应用新属性值,但它会影响所有线程,因此其他并发请求的消息将被重定向到新文件。

我唯一能使用ILoggerRepository的解决方案。

答案 1 :(得分:0)

在WCF服务中为每个线程创建唯一的日志文件

如果你不想log4net来创建一个空文件ID的文件(例如c:\ Logs \ 19850101 \ 131510_null.log)
您必须首先确保设置属性,然后配置log4net。

在WCF服务中,您可以执行以下步骤:
1.删​​除文件'AssemblyInfo.cs'中对XmlConfigurator的调用。
2.将全局应用程序类(Global.asax)添加到您的服务中 3.将以下位代码添加到新创建的类中。

    /// <summary>
    /// Begins the application request.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A <see cref="EventArgs"/> that contains the event data.</param>
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        log4net.LogicalContext.Properties["FileID"] = <some id>;

        // Configure log4net. Log4net will load settings and create a new 
        //   file if it does not exist yet.
        log4net.Config.XmlConfigurator.Configure();
        log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        logger.Debug(<some id>);
    }

开始记录

现在使用此代码段在每个类中创建一个记录器:

    /// <summary>
    /// Logger that can be used to report messages, errors, etc.
    /// </summary>
    private static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

关于锁定

不确定是否需要为ServiceAppender和ThreadAppender使用锁定 默认情况下,每个WCF服务都会将“并发模式”设置为“单一”和“单一” '实例上下文模式'到'PerSession'。

这意味着在任何给定的时刻只会处理一个请求。我测试了 这在虚拟机上有1个客户端使用服务和日志记录似乎工作
精细!所以默认情况下,不需要锁定。