log4net使用wcf-PerSession服务中的ThreadContext.Properties



我想在我的wcf服务中使用以下内容将用户记录在日志消息中:

log4net.ThreadContext.Properties["user"] = this.currentUser.LoginName;

我已将服务设置为在InstanceContextMode.PerSession中运行。在对wcf服务的初始调用中,我将此ThreadContext属性设置为已登录的当前用户,但每次后续调用都不会记录此属性。

我非常确信,对于服务的每个调用,它都在不同的线程上运行任务,即使它被设置为使用PerSession。我假设它使用线程池来处理请求。

有没有一种方法可以设置它,这样我就不必在每个wcf方法中都这样做了

我遇到了同样的问题,这就是我如何让它工作的。您可以使用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;
   }
}

Log4net支持"计算上下文值"。通过使用它,您可以编写这样的类:

public class UserNameContext
{
    public override string ToString()
    {
        string userName = ...; // get the name of the current user
        return userName;
    }
}

如果将其添加到全局上下文中,则可以访问附加程序中的属性(就像您习惯的那样)。每次都会执行"ToString"方法,从而获得正确的用户名。

有关上下文值的更多信息,请参阅本教程:http://www.beefycode.com/post/Log4Net-Tutorial-pt-6-Log-Event-Context.aspx

最新更新