【问题标题】:Log4Net setting contexts for multiple requests with multiple file logging?Log4Net 为具有多个文件日志记录的多个请求设置上下文?
【发布时间】:2016-10-05 15:36:00
【问题描述】:

我们正在尝试使用向 WCF 服务请求的 log4net 日志进程。为此,我们的目标是根据请求的某些参数登录不同的文件。为此,我们使用了 log4net 的 Context 属性,在每次调用服务时设置它的上下文,但是,由于可能存在并发问题,我们不能使用“GlobalContext”。

想(好像想错了)wcf每次调用使用一个线程,我们在收到请求的时候设置ThreadContext属性,比如这样:

GlobalContext.Properties("fulldate") = Now.ToString("yyyyMMdd")
GlobalContext.Properties("date") = Now.ToString("yyyyMM")

ThreadContext.Properties("center") = center //it comes with the request header

XmlConfigurator.Configure()

并且 appender 在配置文件中定义如下:

<appender name="IntAppender" type="log4net.Appender.FileAppender"> 
<file type="log4net.Util.PatternString" value="c:\\Logs\\%property{center}\\%property{date}\\%property{fulldate}\\theLog.log" /> 
<datePattern value=".yyyyMMdd.'log'" /> 
<appendToFile value="true" /> 
<layout type="log4net.Layout.PatternLayout"> 
  <conversionPattern value="%date [%thread] %-5level - [%ndc] %message%newline" /> 
</layout> 

但有时,应该在一个中心的日志中的日志在另一个中心的日志中,似乎问题在于WCF如何管理线程。我不想将服务设置为按请求实例化。你能给我一个关于 WCF 如何管理线程的链接或文档吗?我一直找不到。是否有可能完成我想要做的事情?即在该中心的日志文件中记录一个中心的所有请求。

谢谢。

【问题讨论】:

    标签: vb.net multithreading wcf log4net


    【解决方案1】:

    这样不行,和WCF的线程模型无关。

    Log4net 在记录器之间共享您定义的单个附加程序,从而在线程之间共享。 当一个线程更改文件附加程序上的文件值时,这适用于所有线程,因此查看错误实际最终在哪个日志中是一种竞争条件!

    要做到这一点,您需要每个“中心”的每个日志文件都有一个文件附加程序。如果事先知道中心,您可以在配置中设置它们,否则很容易set them up programatically

    【讨论】:

    • 谢谢!很高兴知道这不是因为线程,会更复杂。是的,这些中心是事先知道的,所以这就足够了,我这周会试试这个。
    • 试过这个并且与过滤器结合使用或多或少地工作得很好。但是有一个问题:如果过滤器不让记录器写入文件,是否可以阻止记录器创建文件?如果一天一个中心没有一个请求,我不想有一千个空文件。
    • 记录器在配置时创建文件,因此您必须将配置从配置移至代码并按需创建文件。