C# log4net和每个线程的唯一日志文件
我有一个接收WCF请求的Windows服务进程。对于每个请求,它都会创建一个新线程来执行一些工作。我想为主机进程创建一个日志文件,并为每个线程实例单独创建一个唯一的日志文件。例如,我希望日志文件类似于“%date{yyyyymmdd}{uu%property{UniqueId}.log”。这是我到目前为止所拥有的C# log4net和每个线程的唯一日志文件,c#,log4net,C#,Log4net,我有一个接收WCF请求的Windows服务进程。对于每个请求,它都会创建一个新线程来执行一些工作。我想为主机进程创建一个日志文件,并为每个线程实例单独创建一个唯一的日志文件。例如,我希望日志文件类似于“%date{yyyyymmdd}{uu%property{UniqueId}.log”。这是我到目前为止所拥有的 然后,在我的线程中,我使用LogicalContext.Properties[“FileID”]=。 我还在assemblyinfo.cs文件中有[assembly:log4net
然后,在我的线程中,我使用LogicalContext.Properties[“FileID”]=
。
我还在assemblyinfo.cs文件中有[assembly:log4net.Config.XmlConfigurator(Watch=true)]
行
几乎一切都正常:)。一个问题是,当我启动Windows服务时,它会自动创建新的%date{HHmmss}(null).log文件。我需要配置什么,以便log4net不会创建这个虚拟文件?另外,是否需要为ServiceAppender和ThreadAppender指定文件锁定?在WCF服务中为每个线程创建唯一的日志文件
如果不想让log4net创建一个文件ID为空的文件(例如c:\Logs\19850101\131510\u 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>);
}
//
///开始应用程序请求。
///
///事件的来源。
///包含事件数据的。
受保护的无效应用程序\u BeginRequest(对象发送方,事件参数e)
{
log4net.LogicalContext.Properties[“FileID”]=;
//配置log4net。log4net将加载设置并创建新的
//文件,如果它还不存在。
log4net.Config.XmlConfigurator.Configure();
log4net.ILog logger=log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
logger.Debug();
}
开始记录
现在,使用以下代码段在每个类中创建一个记录器:
/// <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);
//
///可用于报告消息、错误等的记录器。
///
私有静态log4net.ILog Logger=log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
关于锁定
不确定是否需要对ServiceAppender和ThreadAppender使用锁定。默认情况下,每个WCF服务都会将“并发模式”设置为“单一”,并将 “实例上下文模式”改为“PerSession” 这意味着在任何给定时刻只处理一个请求。我测试了
这在一个虚拟机上,有一个客户端使用该服务,并且日志记录似乎可以正常工作
好的因此,默认情况下,不需要锁定 由于并发问题,该代码无法按预期工作。log4net.Config.XmlConfigurator.Configure强制应用新的属性值,但它将影响所有线程,因此其他并发请求的消息将重定向到新文件
唯一可行的解决方案是使用iLogger存储库。是否有初始化记录器的静态字段?这将在设置FileId之前发生