log4net 在 wcf PerSession 服务中使用 ThreadContext.Properties

问题描述 投票:0回答:2

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

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

我已将服务设置为在

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

我非常确定,对于每次调用服务,它都会在不同的线程上运行任务,即使它设置为使用

PerSession
。 我假设它使用线程池来处理请求。

有没有办法设置这个,这样我就不必在每个 wcf 方法中都这样做?

wcf log4net
2个回答
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
投票

Log4net 支持“计算上下文值”。通过使用它,你可以编写一个像这样的类:

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

        return userName;
    }
}

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

文档涵盖了这一点 https://logging.apache.org/log4net/release/manual/contexts.html

© www.soinside.com 2019 - 2024. All rights reserved.