我有一个接收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指定文件锁定?
答案 0 :(得分:1)
由于并发问题,该代码无法按预期工作。 log4net.Config.XmlConfigurator.Configure强制应用新属性值,但它会影响所有线程,因此其他并发请求的消息将被重定向到新文件。
我唯一能使用ILoggerRepository的解决方案。
答案 1 :(得分:0)
如果你不想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个客户端使用服务和日志记录似乎工作
精细!所以默认情况下,不需要锁定。