Log4Net can't find %username property when I name the file in my appender

前端 未结 5 1292
滥情空心
滥情空心 2020-12-19 10:48

log4net doesn\'t do the correct PatternString substitution for my login name. I want my log to be

Logs\\YYYYMMDD\\MSMQcore_[username].lo

5条回答
  •  既然无缘
    2020-12-19 11:44

    Using the environment variable pattern works for me:

    
    

    Update: if the USERNAME environment variable is not an option, subclassing PatternString could be an alternative. Here is a simple implementation:

    public class MyPatternString : PatternString
    {
        public MyPatternString()
        {
            AddConverter("usernameonly", typeof(UserNameOnlyConverter));
        }    
    }
    
    public class UserNameOnlyConverter : PatternConverter 
    {
        override protected void Convert(TextWriter writer, object state) 
        {
            var windowsIdentity = WindowsIdentity.GetCurrent();
            if (windowsIdentity != null && windowsIdentity.Name != null)
            {
                var name = windowsIdentity.Name.Split('\\')[1];
                writer.Write(name);
            }
        }
    }
    

    The new setting will look like this:

    
    

    Update 2: to answer why %identity and %property{user} doesn't work:

    The %identity pattern picks up the identity property on the current thread. This property is in my tests null, and is probably so until one assigns a specific Windows identity to the running thread. This will not work in the context of the appender because you will not know which thread will perform the actual appending.

    The %property pattern picks up properties from the GlobalContext and ThreadContext classes. By default, only the log4net:HostName (LoggingEvent.HostNameProperty) is registered in the GlobalContext. So unless you actively register properties in those contexts you cannot use them with the %property pattern. Again, ThreadContext is useless in the context of the appender since you have no way of knowing which thread will be doing the appending.

    That said, registering a property called username in the GlobalContext.Properties collection, somewhere in the application startup routine perhaps, will enable the %property{username} to work as expected.

提交回复
热议问题