📄 loggingevent.cs
字号:
// As a last resort use the hash code of the Thread object
m_data.ThreadName = System.Threading.Thread.CurrentThread.GetHashCode().ToString(System.Globalization.CultureInfo.InvariantCulture);
}
}
#endif
}
return m_data.ThreadName;
}
}
/// <summary>
/// Gets the name of the current user.
/// </summary>
/// <value>
/// The name of the current user, or <c>NOT AVAILABLE</c> when the
/// underlying runtime has no support for retrieving the name of the
/// current user.
/// </value>
/// <remarks>
/// <para>
/// Calls <c>WindowsIdentity.GetCurrent().Name</c> to get the name of
/// the current windows user.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// However, the <c>WindowsIdentity.GetCurrent()</c> call seems to
/// return different objects every time, so the current implementation
/// doesn't do this type of caching.
/// </para>
/// <para>
/// Timing for these operations:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Method</term>
/// <description>Results</description>
/// </listheader>
/// <item>
/// <term><c>WindowsIdentity.GetCurrent()</c></term>
/// <description>10000 loops, 00:00:00.2031250 seconds</description>
/// </item>
/// <item>
/// <term><c>WindowsIdentity.GetCurrent().Name</c></term>
/// <description>10000 loops, 00:00:08.0468750 seconds</description>
/// </item>
/// </list>
/// <para>
/// This means we could speed things up almost 40 times by caching the
/// value of the <c>WindowsIdentity.GetCurrent().Name</c> property, since
/// this takes (8.04-0.20) = 7.84375 seconds.
/// </para>
/// </remarks>
public string UserName
{
get
{
if (m_data.UserName == null && this.m_cacheUpdatable)
{
#if (NETCF || SSCLI)
// 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("LoggingEvent: Security exception while trying to get current windows identity. Error Ignored. Empty user name.");
m_data.UserName = "";
}
#endif
}
return m_data.UserName;
}
}
/// <summary>
/// Gets the identity of the current thread principal.
/// </summary>
/// <value>
/// The string name of the identity of the current thread principal.
/// </value>
/// <remarks>
/// <para>
/// Calls <c>System.Threading.Thread.CurrentPrincipal.Identity.Name</c> to get
/// the name of the current thread principal.
/// </para>
/// </remarks>
public string Identity
{
get
{
if (m_data.Identity == null && this.m_cacheUpdatable)
{
#if (NETCF || SSCLI)
// 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(System.Security.SecurityException)
{
// This security exception will occur if the caller does not have
// some undefined set of SecurityPermission flags.
LogLog.Debug("LoggingEvent: Security exception while trying to get current thread principal. Error Ignored. Empty identity name.");
m_data.Identity = "";
}
#endif
}
return m_data.Identity;
}
}
/// <summary>
/// Gets the AppDomain friendly name.
/// </summary>
/// <value>
/// The AppDomain friendly name.
/// </value>
/// <remarks>
/// <para>
/// Gets the AppDomain friendly name.
/// </para>
/// </remarks>
public string Domain
{
get
{
if (m_data.Domain == null && this.m_cacheUpdatable)
{
m_data.Domain = SystemInfo.ApplicationFriendlyName;
}
return m_data.Domain;
}
}
/// <summary>
/// Additional event specific properties.
/// </summary>
/// <value>
/// Additional event specific properties.
/// </value>
/// <remarks>
/// <para>
/// A logger or an appender may attach additional
/// properties to specific events. These properties
/// have a string key and an object value.
/// </para>
/// <para>
/// This property is for events that have been added directly to
/// this event. The aggregate properties (which include these
/// event properties) can be retrieved using <see cref="LookupProperty"/>
/// and <see cref="GetProperties"/>.
/// </para>
/// <para>
/// Once the properties have been fixed <see cref="Fix"/> this property
/// returns the combined cached properties. This ensures that updates to
/// this property are always reflected in the underlying storage. When
/// returning the combined properties there may be more keys in the
/// Dictionary than expected.
/// </para>
/// </remarks>
public PropertiesDictionary Properties
{
get
{
// If we have cached properties then return that otherwise changes will be lost
if (m_data.Properties != null)
{
return m_data.Properties;
}
if (m_eventProperties == null)
{
m_eventProperties = new PropertiesDictionary();
}
return m_eventProperties;
}
}
/// <summary>
/// The fixed fields in this event
/// </summary>
/// <value>
/// The set of fields that are fixed in this event
/// </value>
/// <remarks>
/// <para>
/// Fields will not be fixed if they have previously been fixed.
/// It is not possible to 'unfix' a field.
/// </para>
/// </remarks>
public FixFlags Fix
{
get { return m_fixFlags; }
set { this.FixVolatileData(value); }
}
#endregion Public Instance Properties
#region Implementation of ISerializable
#if !NETCF
/// <summary>
/// Serializes this object into the <see cref="SerializationInfo" /> provided.
/// </summary>
/// <param name="info">The <see cref="SerializationInfo" /> to populate with data.</param>
/// <param name="context">The destination for this serialization.</param>
/// <remarks>
/// <para>
/// The data in this event must be fixed before it can be serialized.
/// </para>
/// <para>
/// The <see cref="FixVolatileData()"/> method must be called during the
/// <see cref="log4net.Appender.IAppender.DoAppend"/> method call if this event
/// is to be used outside that method.
/// </para>
/// </remarks>
[System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.Demand, SerializationFormatter=true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
// The caller must call FixVolatileData before this object
// can be serialized.
info.AddValue("LoggerName", m_data.LoggerName);
info.AddValue("Level", m_data.Level);
info.AddValue("Message", m_data.Message);
info.AddValue("ThreadName", m_data.ThreadName);
info.AddValue("TimeStamp", m_data.TimeStamp);
info.AddValue("LocationInfo", m_data.LocationInfo);
info.AddValue("UserName", m_data.UserName);
info.AddValue("ExceptionString", m_data.ExceptionString);
info.AddValue("Properties", m_data.Properties);
info.AddValue("Domain", m_data.Domain);
info.AddValue("Identity", m_data.Identity);
}
#endif
#endregion Implementation of ISerializable
#region Public Instance Methods
/// <summary>
/// Gets the portable data for this <see cref="LoggingEvent" />.
/// </summary>
/// <returns>The <see cref="LoggingEventData"/> for this event.</returns>
/// <remarks>
/// <para>
/// A new <see cref="LoggingEvent"/> can be constructed using a
/// <see cref="LoggingEventData"/> instance.
/// </para>
/// <para>
/// Does a <see cref="FixFlags.Partial"/> fix of the data
/// in the logging event before returning the event data.
/// </para>
/// </remarks>
public LoggingEventData GetLoggingEventData()
{
return GetLoggingEventData(FixFlags.Partial);
}
/// <summary>
/// Gets the portable data for this <see cref="LoggingEvent" />.
/// </summary>
/// <param name="fixFlags">The set of data to ensure is fixed in the LoggingEventData</param>
/// <returns>The <see cref="LoggingEventData"/> for this event.</returns>
/// <remarks>
/// <para>
/// A new <see cref="LoggingEvent"/> can be constructed using a
/// <see cref="LoggingEventData"/> instance.
/// </para>
/// </remarks>
public LoggingEventData GetLoggingEventData(FixFlags fixFlags)
{
Fix = fixFlags;
return m_data;
}
/// <summary>
/// Returns this event's exception's rendered using the
/// <see cref="ILoggerRepository.RendererMap" />.
/// </summary>
/// <returns>
/// This event's exception's rendered using the <see cref="ILoggerRepository.RendererMap" />.
/// </returns>
/// <remarks>
/// <para>
/// <b>Obsolete. Use <see cref="GetExceptionString"/> instead.</b>
/// </para>
/// </remarks>
[Obsolete("Use GetExceptionString instead")]
public string GetExceptionStrRep()
{
return GetExceptionString();
}
/// <summary>
/// Returns this event's exception's rendered using the
/// <see cref="ILoggerRepository.RendererMap" />.
/// </summary>
/// <returns>
/// This event's exception's rendered using the <see cref="ILoggerRepository.RendererMap" />.
/// </returns>
/// <remarks>
/// <para>
/// Returns this event's exception's rendered using the
/// <see cref="ILoggerRepository.RendererMap" />.
/// </para>
/// </remarks>
public string GetExceptionString()
{
if (m_data.ExceptionString == null && this.m_cacheUpdatable)
{
if (m_thrownException != null)
{
if (m_repository != null)
{
// Render exception using the repositories renderer map
m_data.ExceptionString = m_repository.RendererMap.FindAndRender(m_thrownException);
}
else
{
// Very last resort
m_data.ExceptionString = m_thrownException.ToString();
}
}
else
{
m_data.ExceptionString = "";
}
}
return m_data.ExceptionString;
}
/// <summary>
/// Fix instance fields that hold volatile data.
/// </summary>
/// <remarks>
/// <para>
/// Some of the values in instances of <see cref="LoggingEvent"/>
/// are considered volatile, that is the values are correct at the
/// time the event is delivered to appenders, but will not be consistent
/// at any time afterwards. If an event is to be stored and then processed
/// at a later time these volatile values must be fixed by calling
/// <see cref="FixVolatileData()"/>. There is a performance penalty
/// incurred by calling <see cref="FixVolatileData()"/> but it
/// is essential to maintaining data consistency.
/// </para>
/// <para>
/// Calling <see cref="FixVolatileData()"/> is equivalent to
/// calling <see cref="FixVolatileData(bool)"/> passing the parameter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -