wcflog4net

log4net using ThreadContext.Properties in wcf PerSession service


I would like to use the following in my wcf service to log the user in the log message:

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

I have the service set up to run in InstanceContextMode.PerSession. In the initial call to the wcf service I am setting this ThreadContext property to the current user that is logged in but each subsequent call does not log this property.

I'm pretty sure that for each call to the service it's running the task on a different thread even though it's set to use PerSession. I assume it's using a thread pool to process the requests.

Is there a way to set this so that I don't have to do it in every wcf method?


Solution

  • I ran into the same problem and this is how I got it to work. You can use GlobalContext since it will be evaluated for each call anyway.

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
    public class MyService : IMyService
    {
        //static constructor
        static MyService()
        {
            log4net.Config.XmlConfigurator.Configure();
            log4net.GlobalContext.Properties["user"] = new UserLogHelper();
        }
        ...
    }
    

    Then you have to define a simple class:

    private class UserLogHelper
    {
        public override string ToString()
        {
            var instanceContext = OperationContext.Current.InstanceContext;
            var myServiceInstance = instanceContext.GetServiceInstance() as MyService;
            return myServiceInstance?.currentUser?.LoginName;
       }
    }