Index: Core/LoggingEvent.cs
===================================================================
--- Core/LoggingEvent.cs (revision 1581269)
+++ Core/LoggingEvent.cs (working copy)
@@ -828,31 +828,7 @@
{
if (m_data.UserName == null && this.m_cacheUpdatable)
{
-#if NETCF
- // On compact framework there's no notion of current Windows user
- m_data.UserName = SystemInfo.NotAvailableText;
-#else
- try
- {
- WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
- if (windowsIdentity != null && windowsIdentity.Name != null)
- {
- m_data.UserName = windowsIdentity.Name;
- }
- else
- {
- m_data.UserName = "";
- }
- }
- catch(System.Security.SecurityException)
- {
- // This security exception will occur if the caller does not have
- // some undefined set of SecurityPermission flags.
- LogLog.Debug(declaringType, "Security exception while trying to get current windows identity. Error Ignored. Empty user name.");
-
- m_data.UserName = "";
- }
-#endif
+ m_data.UserName = SystemInfo.GetCurrentUserName();
}
return m_data.UserName;
}
@@ -876,41 +852,7 @@
{
if (m_data.Identity == null && this.m_cacheUpdatable)
{
-#if NETCF
- // On compact framework there's no notion of current thread principals
- m_data.Identity = SystemInfo.NotAvailableText;
-#else
- try
- {
- if (System.Threading.Thread.CurrentPrincipal != null &&
- System.Threading.Thread.CurrentPrincipal.Identity != null &&
- System.Threading.Thread.CurrentPrincipal.Identity.Name != null)
- {
- m_data.Identity = System.Threading.Thread.CurrentPrincipal.Identity.Name;
- }
- else
- {
- m_data.Identity = "";
- }
- }
- catch (ObjectDisposedException)
- {
- // This exception will occur if System.Threading.Thread.CurrentPrincipal.Identity is not null but
- // the getter of the property Name tries to access disposed objects.
- // Seen to happen on IIS 7 or greater with windows authentication.
- LogLog.Debug(declaringType, "Object disposed exception while trying to get current thread principal. Error Ignored. Empty identity name.");
-
- m_data.Identity = "";
- }
- catch (System.Security.SecurityException)
- {
- // This security exception will occur if the caller does not have
- // some undefined set of SecurityPermission flags.
- LogLog.Debug(declaringType, "Security exception while trying to get current thread principal. Error Ignored. Empty identity name.");
-
- m_data.Identity = "";
- }
-#endif
+ m_data.Identity = SystemInfo.GetCurrentIdentity();
}
return m_data.Identity;
}
@@ -1337,7 +1279,6 @@
// event properties
PropertiesDictionary eventProperties = new PropertiesDictionary();
- eventProperties[UserNameProperty] = UserName;
eventProperties[IdentityProperty] = Identity;
m_compositeProperties.Add(eventProperties);
Index: Util/CompositeProperties.cs
===================================================================
--- Util/CompositeProperties.cs (revision 1581269)
+++ Util/CompositeProperties.cs (working copy)
@@ -36,6 +36,7 @@
{
#region Private Instance Fields
+ private string m_currentUserName = null;
private PropertiesDictionary m_flattened = null;
private ArrayList m_nestedProperties = new ArrayList();
@@ -82,6 +83,17 @@
{
get
{
+ // treat the UserName property specially
+ if (key == log4net.Core.LoggingEvent.UserNameProperty)
+ {
+ if (m_currentUserName == null)
+ {
+ // get the current user name and cache it
+ m_currentUserName = SystemInfo.GetCurrentUserName();
+ }
+ return m_currentUserName;
+ }
+
// Look in the flattened properties first
if (m_flattened != null)
{
Index: Util/SystemInfo.cs
===================================================================
--- Util/SystemInfo.cs (revision 1581269)
+++ Util/SystemInfo.cs (working copy)
@@ -24,6 +24,7 @@
using System.IO;
using System.Runtime.InteropServices;
using System.Collections;
+using System.Security.Principal;
namespace log4net.Util
{
@@ -1002,6 +1003,133 @@
return new Hashtable(StringComparer.OrdinalIgnoreCase);
}
+ ///
+ /// Gets the name of the current user.
+ ///
+ ///
+ /// The name of the current user, or NOT AVAILABLE when the
+ /// underlying runtime has no support for retrieving the name of the
+ /// current user.
+ ///
+ ///
+ ///
+ /// Calls WindowsIdentity.GetCurrent().Name to get the name of
+ /// the current windows user.
+ ///
+ ///
+ /// To improve performance, we could cache the string representation of
+ /// the name, and reuse that as long as the identity stayed constant.
+ /// Once the identity changed, we would need to re-assign and re-render
+ /// the string.
+ ///
+ ///
+ /// However, the WindowsIdentity.GetCurrent() call seems to
+ /// return different objects every time, so the current implementation
+ /// doesn't do this type of caching.
+ ///
+ ///
+ /// Timing for these operations:
+ ///
+ ///
+ ///
+ /// Method
+ /// Results
+ ///
+ /// -
+ /// WindowsIdentity.GetCurrent()
+ /// 10000 loops, 00:00:00.2031250 seconds
+ ///
+ /// -
+ /// WindowsIdentity.GetCurrent().Name
+ /// 10000 loops, 00:00:08.0468750 seconds
+ ///
+ ///
+ ///
+ /// This means we could speed things up almost 40 times by caching the
+ /// value of the WindowsIdentity.GetCurrent().Name property, since
+ /// this takes (8.04-0.20) = 7.84375 seconds.
+ ///
+ ///
+ public static string GetCurrentUserName()
+ {
+#if NETCF
+ // On compact framework there's no notion of current Windows user
+ return NotAvailableText;
+#else
+ try
+ {
+ WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
+ if (windowsIdentity != null && windowsIdentity.Name != null)
+ {
+ return windowsIdentity.Name;
+ }
+ else
+ {
+ return "";
+ }
+ }
+ catch (System.Security.SecurityException)
+ {
+ // This security exception will occur if the caller does not have
+ // some undefined set of SecurityPermission flags.
+ LogLog.Debug(declaringType, "Security exception while trying to get current windows identity. Error Ignored. Empty user name.");
+
+ return "";
+ }
+#endif
+ }
+
+ ///
+ /// Gets the identity of the current thread principal.
+ ///
+ ///
+ /// The string name of the identity of the current thread principal.
+ ///
+ ///
+ ///
+ /// Calls System.Threading.Thread.CurrentPrincipal.Identity.Name to get
+ /// the name of the current thread principal.
+ ///
+ ///
+ public static string GetCurrentIdentity()
+ {
+#if NETCF
+ // On compact framework there's no notion of current thread principals
+ return SystemInfo.NotAvailableText;
+#else
+ try
+ {
+ if (System.Threading.Thread.CurrentPrincipal != null &&
+ System.Threading.Thread.CurrentPrincipal.Identity != null &&
+ System.Threading.Thread.CurrentPrincipal.Identity.Name != null)
+ {
+ return System.Threading.Thread.CurrentPrincipal.Identity.Name;
+ }
+ else
+ {
+ return "";
+ }
+ }
+ catch (ObjectDisposedException)
+ {
+ // This exception will occur if System.Threading.Thread.CurrentPrincipal.Identity is not null but
+ // the getter of the property Name tries to access disposed objects.
+ // Seen to happen on IIS 7 or greater with windows authentication.
+ LogLog.Debug(declaringType, "Object disposed exception while trying to get current thread principal. Error Ignored. Empty identity name.");
+
+ return "";
+ }
+ catch (System.Security.SecurityException)
+ {
+ // This security exception will occur if the caller does not have
+ // some undefined set of SecurityPermission flags.
+ LogLog.Debug(declaringType, "Security exception while trying to get current thread principal. Error Ignored. Empty identity name.");
+
+ return "";
+ }
+#endif
+ }
+
#endregion Public Static Methods
#region Private Static Methods