我想在我的wcf服务中使用以下内容在日志消息中记录用户:
log4net.ThreadContext.Properties["user"] = this.currentUser.LoginName;
我已将服务设置为在InstanceContextMode.PerSession
中运行。在对wcf服务的初始调用中,我将此ThreadContext
属性设置为已登录的当前用户,但每次后续调用都不会记录此属性。
我非常确定,对于每次调用服务,它都在不同的线程上运行任务,即使它已设置为使用PerSession
。我假设它使用线程池来处理请求。
答案 0 :(得分:2)
我遇到了同样的问题,这就是我开始工作的方式。您可以使用GlobalContext,因为无论如何都会对每个调用进行评估。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MyService : IMyService
{
//static constructor
static MyService()
{
log4net.Config.XmlConfigurator.Configure();
log4net.GlobalContext.Properties["user"] = new UserLogHelper();
}
...
}
然后你必须定义一个简单的类:
private class UserLogHelper
{
public override string ToString()
{
var instanceContext = OperationContext.Current.InstanceContext;
var myServiceInstance = instanceContext.GetServiceInstance() as MyService;
return myServiceInstance?.currentUser?.LoginName;
}
}
答案 1 :(得分:1)
Log4net支持“计算的上下文值”。通过使用它,你可以写一个这样的类:
public class UserNameContext
{
public override string ToString()
{
string userName = ...; // get the name of the current user
return userName;
}
}
如果将其添加到全局上下文中,则可以访问appender中的属性(就像您习惯的那样)。每次都会执行'ToString'方法,从而获得正确的用户名。
有关上下文值的更多信息,请参阅此精彩教程: http://www.beefycode.com/post/Log4Net-Tutorial-pt-6-Log-Event-Context.aspx