Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / SMDiagnostics / System / ServiceModel / Diagnostics / DiagnosticTrace.cs / 1305376 / DiagnosticTrace.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Diagnostics { using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Diagnostics; using System.Globalization; using System.Runtime; using System.Runtime.Diagnostics; using System.Security; using System.Security.Permissions; using System.Text; using System.Xml; class DiagnosticTrace { const string DefaultTraceListenerName = "Default"; const int MaxTraceSize = 65535; bool tracingEnabled = true; bool haveListeners = false; object localSyncObject = new object(); // only used by ShouldTrace, only used once. DateTime lastFailure = DateTime.MinValue; SourceLevels level; bool calledShutdown = false; bool shouldUseActivity = false; string AppDomainFriendlyName = null; PiiTraceSource traceSource = null; TraceSourceKind traceSourceType = TraceSourceKind.PiiTraceSource; const string subType = ""; const string version = "1"; const int traceFailureLogThreshold = 1; string TraceSourceName = string.Empty; const string TraceRecordVersion = "http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"; const SourceLevels DefaultLevel = SourceLevels.Off; static object classLockObject = new object(); [Fx.Tag.SecurityNote(Critical = "This determines the event source name.")] [SecurityCritical] string eventSourceName = string.Empty; internal static string ProcessName { get { string retval = null; try { using (Process process = Process.GetCurrentProcess()) { retval = process.ProcessName; } } catch (SecurityException) { } return retval; } } internal static int ProcessId { get { int retval = -1; try { using (Process process = Process.GetCurrentProcess()) { retval = process.Id; } } catch (SecurityException) { } return retval; } } internal PiiTraceSource TraceSource { get { return this.traceSource; } set { this.traceSource = value; } } SourceLevels FixLevel(SourceLevels level) { //the bit fixing below is meant to keep the trace level legal even if somebody uses numbers in config if (((level & ~SourceLevels.Information) & SourceLevels.Verbose) != 0) { level |= SourceLevels.Verbose; } else if (((level & ~SourceLevels.Warning) & SourceLevels.Information) != 0) { level |= SourceLevels.Information; } else if (((level & ~SourceLevels.Error) & SourceLevels.Warning) != 0) { level |= SourceLevels.Warning; } if (((level & ~SourceLevels.Critical) & SourceLevels.Error) != 0) { level |= SourceLevels.Error; } if ((level & SourceLevels.Critical) != 0) { level |= SourceLevels.Critical; } // If only the ActivityTracing flag is set, then // we really have Off. Do not do ActivityTracing then. if (level == SourceLevels.ActivityTracing) { level = SourceLevels.Off; } return level; } void SetLevel(SourceLevels level) { SourceLevels fixedLevel = FixLevel(level); this.level = fixedLevel; if (this.TraceSource != null) { // Need this for setup from places like TransactionBridge. this.haveListeners = this.TraceSource.Listeners.Count > 0; if (this.TraceSource.Switch.Level != SourceLevels.Off && level == SourceLevels.Off) { TraceSource temp = this.TraceSource; this.CreateTraceSource(); temp.Close(); } #pragma warning disable 618 this.tracingEnabled = this.HaveListeners && (fixedLevel != SourceLevels.Off); #pragma warning restore 618 this.TraceSource.Switch.Level = fixedLevel; this.shouldUseActivity = (fixedLevel & SourceLevels.ActivityTracing) != 0; } } void SetLevelThreadSafe(SourceLevels level) { lock (this.localSyncObject) { SetLevel(level); } } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.Level instead")] internal SourceLevels Level { //Do not call this property from Initialize! get { if (this.TraceSource != null && (this.TraceSource.Switch.Level != this.level)) { this.level = this.TraceSource.Switch.Level; } return this.level; } set { SetLevelThreadSafe(value); } } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.HaveListeners instead")] internal bool HaveListeners { get { return this.haveListeners; } } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.ShouldTrace instead")] internal bool ShouldTrace(TraceEventType type) { return this.TracingEnabled && (this.TraceSource != null) && 0 != ((int)type & (int)this.Level); } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.ShouldUseActivity instead")] internal bool ShouldUseActivity { get { return this.shouldUseActivity; } } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.TracingEnabled instead")] internal bool TracingEnabled { get { return this.tracingEnabled && this.traceSource != null; } } #pragma warning disable 56500 [Obsolete("For SMDiagnostics.dll use only. Never 'new' this type up unless you are DiagnosticUtility.")] [Fx.Tag.SecurityNote(Critical = "Sets eventSourceName.")] [SecurityCritical] internal DiagnosticTrace(TraceSourceKind sourceType, string traceSourceName, string eventSourceName) { this.traceSourceType = sourceType; this.TraceSourceName = traceSourceName; this.eventSourceName = eventSourceName; // We own the resource and it hasn't been filled in yet. //needed for logging events to event log this.AppDomainFriendlyName = AppDomain.CurrentDomain.FriendlyName; try { this.CreateTraceSource(); this.UnsafeAddDomainEventHandlersForCleanup(); } catch (ConfigurationErrorsException) { throw; } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } EventLogger logger = new EventLogger(this.eventSourceName, null); logger.LogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToSetupTracing, false, e.ToString()); } } #pragma warning restore 56500 [SecurityCritical] [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)] [Obsolete("For SMDiagnostics.dll use only")] void UnsafeAddDomainEventHandlersForCleanup() { AppDomain currentDomain = AppDomain.CurrentDomain; this.haveListeners = this.TraceSource.Listeners.Count > 0; this.tracingEnabled = this.HaveListeners; if (this.TracingEnabled) { currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler); this.SetLevel(this.TraceSource.Switch.Level); currentDomain.DomainUnload += new EventHandler(ExitOrUnloadEventHandler); currentDomain.ProcessExit += new EventHandler(ExitOrUnloadEventHandler); } } [SecurityCritical] [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)] void UnsafeRemoveDefaultTraceListener(PiiTraceSource piiTraceSource) { piiTraceSource.Listeners.Remove(DiagnosticTrace.DefaultTraceListenerName); } [SecuritySafeCritical] void CreateTraceSource() { PiiTraceSource tempSource = null; if (this.traceSourceType == TraceSourceKind.PiiTraceSource) { tempSource = new PiiTraceSource(this.TraceSourceName, this.eventSourceName, DiagnosticTrace.DefaultLevel); } else { tempSource = new DiagnosticTraceSource(this.TraceSourceName, this.eventSourceName, DiagnosticTrace.DefaultLevel); } UnsafeRemoveDefaultTraceListener(tempSource); this.TraceSource = tempSource; } #pragma warning disable 56500 internal void TraceEvent(TraceEventType type, int code, string msdnTraceCode, string description, TraceRecord trace, Exception exception, object source) { #pragma warning disable 618 AssertUtility.DebugAssert(exception == null || type <= TraceEventType.Information, "Exceptions should be traced at Information or higher"); AssertUtility.DebugAssert(!string.IsNullOrEmpty(description), "All TraceCodes should have a description"); #pragma warning restore 618 TraceXPathNavigator navigator = null; try { #pragma warning disable 618 if (this.TraceSource != null && this.HaveListeners) #pragma warning restore 618 { try { BuildTrace(type, msdnTraceCode, description, trace, exception, source, out navigator); } catch (PlainXmlWriter.MaxSizeExceededException) { StringTraceRecord codeTraceRecord = new StringTraceRecord("TruncatedTraceId", msdnTraceCode); this.TraceEvent(type, DiagnosticsTraceCode.TraceTruncatedQuotaExceeded, DiagnosticTrace.GenerateMsdnTraceCode("System.ServiceModel.Diagnostics", "TraceTruncatedQuotaExceeded"), TraceSR.GetString(TraceSR.TraceCodeTraceTruncatedQuotaExceeded), codeTraceRecord, null, null); } this.TraceSource.TraceData(type, code, navigator); if (this.calledShutdown) { this.TraceSource.Flush(); } // Must have been a successful trace. this.LastFailure = DateTime.MinValue; } } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } LogTraceFailure(navigator == null ? string.Empty : navigator.ToString(), e); } } #pragma warning restore 56500 internal void TraceEvent(TraceEventType type, int code, string msdnTraceCode, string description, TraceRecord trace, Exception exception, Guid activityId, object source) { #pragma warning disable 618 using ((this.ShouldUseActivity && Guid.Empty != activityId) ? Activity.CreateActivity(activityId) : null) #pragma warning restore 618 { this.TraceEvent(type, code, msdnTraceCode, description, trace, exception, source); } } // helper for standardized trace code generation static internal string GenerateMsdnTraceCode(string traceSource, string traceCodeString) { return string.Format(CultureInfo.InvariantCulture, "http://msdn.microsoft.com/{0}/library/{1}.{2}.aspx", CultureInfo.CurrentCulture.Name, traceSource, traceCodeString); } #pragma warning disable 56500 internal void TraceTransfer(Guid newId) { #pragma warning disable 618 if (this.ShouldUseActivity) #pragma warning restore 618 { Guid oldId = DiagnosticTrace.ActivityId; if (newId != oldId) { #pragma warning disable 618 if (this.HaveListeners) #pragma warning restore 618 { try { this.TraceSource.TraceTransfer(0, null, newId); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } LogTraceFailure(null, e); } } } } } #pragma warning restore 56500 static string LookupSeverity(TraceEventType type) { string s; switch (type) { case TraceEventType.Critical: s = "Critical"; break; case TraceEventType.Error: s = "Error"; break; case TraceEventType.Warning: s = "Warning"; break; case TraceEventType.Information: s = "Information"; break; case TraceEventType.Verbose: s = "Verbose"; break; case TraceEventType.Start: s = "Start"; break; case TraceEventType.Stop: s = "Stop"; break; case TraceEventType.Suspend: s = "Suspend"; break; case TraceEventType.Transfer: s = "Transfer"; break; default: s = type.ToString(); break; } #pragma warning disable 618 AssertUtility.DebugAssert(s == type.ToString(), "Return value should equal the name of the enum"); #pragma warning restore 618 return s; } DateTime LastFailure { get { return this.lastFailure; } set { this.lastFailure = value; } } [Fx.Tag.SecurityNote(Critical = "Calls unsafe methods, UnsafeCreateEventLogger and UnsafeLogEvent.", Safe = "Event identities cannot be spoofed as they are constants determined inside the method.")] [SecuritySafeCritical] void LogTraceFailure(string traceString, Exception e) { const int FailureBlackoutDuration = 10; TimeSpan FailureBlackout = TimeSpan.FromMinutes(FailureBlackoutDuration); try { lock (this.localSyncObject) { if (DateTime.UtcNow.Subtract(this.LastFailure) >= FailureBlackout) { this.LastFailure = DateTime.UtcNow; #pragma warning disable 618 EventLogger logger = EventLogger.UnsafeCreateEventLogger(this.eventSourceName, this); #pragma warning restore 618 if (e == null) { logger.UnsafeLogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToTraceEvent, false, traceString); } else { logger.UnsafeLogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToTraceEventWithException, false, traceString, e.ToString()); } } } } #pragma warning suppress 56500 //[....]; Taken care of by FxCop catch { } } void ShutdownTracing() { if (null != this.TraceSource && !this.calledShutdown) { try { #pragma warning disable 618 if (this.Level != SourceLevels.Off) { if (this.ShouldTrace(TraceEventType.Information)) #pragma warning restore 618 { Dictionaryvalues = new Dictionary (3); values["AppDomain.FriendlyName"] = AppDomain.CurrentDomain.FriendlyName; values["ProcessName"] = DiagnosticTrace.ProcessName; values["ProcessId"] = DiagnosticTrace.ProcessId.ToString(CultureInfo.CurrentCulture); this.TraceEvent(TraceEventType.Information, DiagnosticsTraceCode.AppDomainUnload, DiagnosticTrace.GenerateMsdnTraceCode("System.ServiceModel.Diagnostics", "AppDomainUnload"), TraceSR.GetString(TraceSR.TraceCodeAppDomainUnload), new DictionaryTraceRecord(values), null, null); } this.calledShutdown = true; this.TraceSource.Flush(); } } #pragma warning suppress 56500 //[....]; Taken care of by FxCop catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } LogTraceFailure(null, exception); } } } void ExitOrUnloadEventHandler(object sender, EventArgs e) { ShutdownTracing(); } void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) { Exception e = (Exception)args.ExceptionObject; TraceEvent(TraceEventType.Critical, DiagnosticsTraceCode.UnhandledException, "UnhandledException", TraceSR.GetString(TraceSR.UnhandledException), null, e, null); ShutdownTracing(); } void BuildTrace(TraceEventType type, string msdnTraceCode, string description, TraceRecord trace, Exception exception, object source, out TraceXPathNavigator navigator) { PlainXmlWriter xmlWriter = new PlainXmlWriter(DiagnosticTrace.MaxTraceSize); navigator = xmlWriter.Navigator; this.BuildTrace(xmlWriter, type, msdnTraceCode, description, trace, exception, source); if (!this.TraceSource.ShouldLogPii) { navigator.RemovePii(DiagnosticStrings.HeadersPaths); } } static string CreateSourceString(object source) { return source.GetType().ToString() + "/" + source.GetHashCode().ToString(CultureInfo.CurrentCulture); } void BuildTrace(PlainXmlWriter xml, TraceEventType type, string msdnTraceCode, string description, TraceRecord trace, Exception exception, object source) { xml.WriteStartElement(DiagnosticStrings.TraceRecordTag); xml.WriteAttributeString(DiagnosticStrings.NamespaceTag, DiagnosticTrace.TraceRecordVersion); xml.WriteAttributeString(DiagnosticStrings.SeverityTag, DiagnosticTrace.LookupSeverity(type)); xml.WriteElementString(DiagnosticStrings.TraceCodeTag, msdnTraceCode); xml.WriteElementString(DiagnosticStrings.DescriptionTag, description); xml.WriteElementString(DiagnosticStrings.AppDomain, this.AppDomainFriendlyName); if (source != null) { xml.WriteElementString(DiagnosticStrings.SourceTag, CreateSourceString(source)); } if (trace != null) { xml.WriteStartElement(DiagnosticStrings.ExtendedDataTag); xml.WriteAttributeString(DiagnosticStrings.NamespaceTag, trace.EventId); trace.WriteTo(xml); xml.WriteEndElement(); } if (exception != null) { xml.WriteStartElement(DiagnosticStrings.ExceptionTag); this.AddExceptionToTraceString(xml, exception); xml.WriteEndElement(); } xml.WriteEndElement(); } static internal Guid ActivityId { get { return System.Runtime.Diagnostics.DiagnosticTrace.ActivityId; } set { System.Runtime.Diagnostics.DiagnosticTrace.ActivityId = value; } } void AddExceptionToTraceString(XmlWriter xml, Exception exception) { xml.WriteElementString(DiagnosticStrings.ExceptionTypeTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(exception.GetType().AssemblyQualifiedName)); xml.WriteElementString(DiagnosticStrings.MessageTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(exception.Message)); xml.WriteElementString(DiagnosticStrings.StackTraceTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(this.StackTraceString(exception))); xml.WriteElementString(DiagnosticStrings.ExceptionStringTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(exception.ToString())); Win32Exception win32Exception = exception as Win32Exception; if (win32Exception != null) { xml.WriteElementString(DiagnosticStrings.NativeErrorCodeTag, win32Exception.NativeErrorCode.ToString("X", CultureInfo.InvariantCulture)); } if (exception.Data != null && exception.Data.Count > 0) { xml.WriteStartElement(DiagnosticStrings.DataItemsTag); foreach (object dataItem in exception.Data.Keys) { xml.WriteStartElement(DiagnosticStrings.DataTag); xml.WriteElementString(DiagnosticStrings.KeyTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(dataItem.ToString())); xml.WriteElementString(DiagnosticStrings.ValueTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(exception.Data[dataItem].ToString())); xml.WriteEndElement(); } xml.WriteEndElement(); } if (exception.InnerException != null) { xml.WriteStartElement(DiagnosticStrings.InnerExceptionTag); this.AddExceptionToTraceString(xml, exception.InnerException); xml.WriteEndElement(); } } string StackTraceString(Exception exception) { string retval = exception.StackTrace; if (string.IsNullOrEmpty(retval)) { // This means that the exception hasn't been thrown yet. We need to manufacture the stack then. StackTrace stackTrace = new StackTrace(false); // Figure out how many frames should be throw away System.Diagnostics.StackFrame[] stackFrames = stackTrace.GetFrames(); int frameCount = 0; bool breakLoop = false; foreach (StackFrame frame in stackFrames) { string methodName = frame.GetMethod().Name; switch (methodName) { case "StackTraceString": case "AddExceptionToTraceString": case "BuildTrace": case "TraceEvent": case "TraceException": ++frameCount; break; default: if (methodName.StartsWith("ThrowHelper", StringComparison.Ordinal)) { ++ frameCount; } else { breakLoop = true; } break; } if (breakLoop) { break; } } stackTrace = new StackTrace(frameCount, false); retval = stackTrace.ToString(); } return retval; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Diagnostics { using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Diagnostics; using System.Globalization; using System.Runtime; using System.Runtime.Diagnostics; using System.Security; using System.Security.Permissions; using System.Text; using System.Xml; class DiagnosticTrace { const string DefaultTraceListenerName = "Default"; const int MaxTraceSize = 65535; bool tracingEnabled = true; bool haveListeners = false; object localSyncObject = new object(); // only used by ShouldTrace, only used once. DateTime lastFailure = DateTime.MinValue; SourceLevels level; bool calledShutdown = false; bool shouldUseActivity = false; string AppDomainFriendlyName = null; PiiTraceSource traceSource = null; TraceSourceKind traceSourceType = TraceSourceKind.PiiTraceSource; const string subType = ""; const string version = "1"; const int traceFailureLogThreshold = 1; string TraceSourceName = string.Empty; const string TraceRecordVersion = "http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"; const SourceLevels DefaultLevel = SourceLevels.Off; static object classLockObject = new object(); [Fx.Tag.SecurityNote(Critical = "This determines the event source name.")] [SecurityCritical] string eventSourceName = string.Empty; internal static string ProcessName { get { string retval = null; try { using (Process process = Process.GetCurrentProcess()) { retval = process.ProcessName; } } catch (SecurityException) { } return retval; } } internal static int ProcessId { get { int retval = -1; try { using (Process process = Process.GetCurrentProcess()) { retval = process.Id; } } catch (SecurityException) { } return retval; } } internal PiiTraceSource TraceSource { get { return this.traceSource; } set { this.traceSource = value; } } SourceLevels FixLevel(SourceLevels level) { //the bit fixing below is meant to keep the trace level legal even if somebody uses numbers in config if (((level & ~SourceLevels.Information) & SourceLevels.Verbose) != 0) { level |= SourceLevels.Verbose; } else if (((level & ~SourceLevels.Warning) & SourceLevels.Information) != 0) { level |= SourceLevels.Information; } else if (((level & ~SourceLevels.Error) & SourceLevels.Warning) != 0) { level |= SourceLevels.Warning; } if (((level & ~SourceLevels.Critical) & SourceLevels.Error) != 0) { level |= SourceLevels.Error; } if ((level & SourceLevels.Critical) != 0) { level |= SourceLevels.Critical; } // If only the ActivityTracing flag is set, then // we really have Off. Do not do ActivityTracing then. if (level == SourceLevels.ActivityTracing) { level = SourceLevels.Off; } return level; } void SetLevel(SourceLevels level) { SourceLevels fixedLevel = FixLevel(level); this.level = fixedLevel; if (this.TraceSource != null) { // Need this for setup from places like TransactionBridge. this.haveListeners = this.TraceSource.Listeners.Count > 0; if (this.TraceSource.Switch.Level != SourceLevels.Off && level == SourceLevels.Off) { TraceSource temp = this.TraceSource; this.CreateTraceSource(); temp.Close(); } #pragma warning disable 618 this.tracingEnabled = this.HaveListeners && (fixedLevel != SourceLevels.Off); #pragma warning restore 618 this.TraceSource.Switch.Level = fixedLevel; this.shouldUseActivity = (fixedLevel & SourceLevels.ActivityTracing) != 0; } } void SetLevelThreadSafe(SourceLevels level) { lock (this.localSyncObject) { SetLevel(level); } } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.Level instead")] internal SourceLevels Level { //Do not call this property from Initialize! get { if (this.TraceSource != null && (this.TraceSource.Switch.Level != this.level)) { this.level = this.TraceSource.Switch.Level; } return this.level; } set { SetLevelThreadSafe(value); } } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.HaveListeners instead")] internal bool HaveListeners { get { return this.haveListeners; } } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.ShouldTrace instead")] internal bool ShouldTrace(TraceEventType type) { return this.TracingEnabled && (this.TraceSource != null) && 0 != ((int)type & (int)this.Level); } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.ShouldUseActivity instead")] internal bool ShouldUseActivity { get { return this.shouldUseActivity; } } [Obsolete("For SMDiagnostics.dll use only. Call DiagnosticUtility.TracingEnabled instead")] internal bool TracingEnabled { get { return this.tracingEnabled && this.traceSource != null; } } #pragma warning disable 56500 [Obsolete("For SMDiagnostics.dll use only. Never 'new' this type up unless you are DiagnosticUtility.")] [Fx.Tag.SecurityNote(Critical = "Sets eventSourceName.")] [SecurityCritical] internal DiagnosticTrace(TraceSourceKind sourceType, string traceSourceName, string eventSourceName) { this.traceSourceType = sourceType; this.TraceSourceName = traceSourceName; this.eventSourceName = eventSourceName; // We own the resource and it hasn't been filled in yet. //needed for logging events to event log this.AppDomainFriendlyName = AppDomain.CurrentDomain.FriendlyName; try { this.CreateTraceSource(); this.UnsafeAddDomainEventHandlersForCleanup(); } catch (ConfigurationErrorsException) { throw; } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } EventLogger logger = new EventLogger(this.eventSourceName, null); logger.LogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToSetupTracing, false, e.ToString()); } } #pragma warning restore 56500 [SecurityCritical] [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)] [Obsolete("For SMDiagnostics.dll use only")] void UnsafeAddDomainEventHandlersForCleanup() { AppDomain currentDomain = AppDomain.CurrentDomain; this.haveListeners = this.TraceSource.Listeners.Count > 0; this.tracingEnabled = this.HaveListeners; if (this.TracingEnabled) { currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler); this.SetLevel(this.TraceSource.Switch.Level); currentDomain.DomainUnload += new EventHandler(ExitOrUnloadEventHandler); currentDomain.ProcessExit += new EventHandler(ExitOrUnloadEventHandler); } } [SecurityCritical] [SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)] void UnsafeRemoveDefaultTraceListener(PiiTraceSource piiTraceSource) { piiTraceSource.Listeners.Remove(DiagnosticTrace.DefaultTraceListenerName); } [SecuritySafeCritical] void CreateTraceSource() { PiiTraceSource tempSource = null; if (this.traceSourceType == TraceSourceKind.PiiTraceSource) { tempSource = new PiiTraceSource(this.TraceSourceName, this.eventSourceName, DiagnosticTrace.DefaultLevel); } else { tempSource = new DiagnosticTraceSource(this.TraceSourceName, this.eventSourceName, DiagnosticTrace.DefaultLevel); } UnsafeRemoveDefaultTraceListener(tempSource); this.TraceSource = tempSource; } #pragma warning disable 56500 internal void TraceEvent(TraceEventType type, int code, string msdnTraceCode, string description, TraceRecord trace, Exception exception, object source) { #pragma warning disable 618 AssertUtility.DebugAssert(exception == null || type <= TraceEventType.Information, "Exceptions should be traced at Information or higher"); AssertUtility.DebugAssert(!string.IsNullOrEmpty(description), "All TraceCodes should have a description"); #pragma warning restore 618 TraceXPathNavigator navigator = null; try { #pragma warning disable 618 if (this.TraceSource != null && this.HaveListeners) #pragma warning restore 618 { try { BuildTrace(type, msdnTraceCode, description, trace, exception, source, out navigator); } catch (PlainXmlWriter.MaxSizeExceededException) { StringTraceRecord codeTraceRecord = new StringTraceRecord("TruncatedTraceId", msdnTraceCode); this.TraceEvent(type, DiagnosticsTraceCode.TraceTruncatedQuotaExceeded, DiagnosticTrace.GenerateMsdnTraceCode("System.ServiceModel.Diagnostics", "TraceTruncatedQuotaExceeded"), TraceSR.GetString(TraceSR.TraceCodeTraceTruncatedQuotaExceeded), codeTraceRecord, null, null); } this.TraceSource.TraceData(type, code, navigator); if (this.calledShutdown) { this.TraceSource.Flush(); } // Must have been a successful trace. this.LastFailure = DateTime.MinValue; } } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } LogTraceFailure(navigator == null ? string.Empty : navigator.ToString(), e); } } #pragma warning restore 56500 internal void TraceEvent(TraceEventType type, int code, string msdnTraceCode, string description, TraceRecord trace, Exception exception, Guid activityId, object source) { #pragma warning disable 618 using ((this.ShouldUseActivity && Guid.Empty != activityId) ? Activity.CreateActivity(activityId) : null) #pragma warning restore 618 { this.TraceEvent(type, code, msdnTraceCode, description, trace, exception, source); } } // helper for standardized trace code generation static internal string GenerateMsdnTraceCode(string traceSource, string traceCodeString) { return string.Format(CultureInfo.InvariantCulture, "http://msdn.microsoft.com/{0}/library/{1}.{2}.aspx", CultureInfo.CurrentCulture.Name, traceSource, traceCodeString); } #pragma warning disable 56500 internal void TraceTransfer(Guid newId) { #pragma warning disable 618 if (this.ShouldUseActivity) #pragma warning restore 618 { Guid oldId = DiagnosticTrace.ActivityId; if (newId != oldId) { #pragma warning disable 618 if (this.HaveListeners) #pragma warning restore 618 { try { this.TraceSource.TraceTransfer(0, null, newId); } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } LogTraceFailure(null, e); } } } } } #pragma warning restore 56500 static string LookupSeverity(TraceEventType type) { string s; switch (type) { case TraceEventType.Critical: s = "Critical"; break; case TraceEventType.Error: s = "Error"; break; case TraceEventType.Warning: s = "Warning"; break; case TraceEventType.Information: s = "Information"; break; case TraceEventType.Verbose: s = "Verbose"; break; case TraceEventType.Start: s = "Start"; break; case TraceEventType.Stop: s = "Stop"; break; case TraceEventType.Suspend: s = "Suspend"; break; case TraceEventType.Transfer: s = "Transfer"; break; default: s = type.ToString(); break; } #pragma warning disable 618 AssertUtility.DebugAssert(s == type.ToString(), "Return value should equal the name of the enum"); #pragma warning restore 618 return s; } DateTime LastFailure { get { return this.lastFailure; } set { this.lastFailure = value; } } [Fx.Tag.SecurityNote(Critical = "Calls unsafe methods, UnsafeCreateEventLogger and UnsafeLogEvent.", Safe = "Event identities cannot be spoofed as they are constants determined inside the method.")] [SecuritySafeCritical] void LogTraceFailure(string traceString, Exception e) { const int FailureBlackoutDuration = 10; TimeSpan FailureBlackout = TimeSpan.FromMinutes(FailureBlackoutDuration); try { lock (this.localSyncObject) { if (DateTime.UtcNow.Subtract(this.LastFailure) >= FailureBlackout) { this.LastFailure = DateTime.UtcNow; #pragma warning disable 618 EventLogger logger = EventLogger.UnsafeCreateEventLogger(this.eventSourceName, this); #pragma warning restore 618 if (e == null) { logger.UnsafeLogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToTraceEvent, false, traceString); } else { logger.UnsafeLogEvent(TraceEventType.Error, EventLogCategory.Tracing, EventLogEventId.FailedToTraceEventWithException, false, traceString, e.ToString()); } } } } #pragma warning suppress 56500 //[....]; Taken care of by FxCop catch { } } void ShutdownTracing() { if (null != this.TraceSource && !this.calledShutdown) { try { #pragma warning disable 618 if (this.Level != SourceLevels.Off) { if (this.ShouldTrace(TraceEventType.Information)) #pragma warning restore 618 { Dictionary values = new Dictionary (3); values["AppDomain.FriendlyName"] = AppDomain.CurrentDomain.FriendlyName; values["ProcessName"] = DiagnosticTrace.ProcessName; values["ProcessId"] = DiagnosticTrace.ProcessId.ToString(CultureInfo.CurrentCulture); this.TraceEvent(TraceEventType.Information, DiagnosticsTraceCode.AppDomainUnload, DiagnosticTrace.GenerateMsdnTraceCode("System.ServiceModel.Diagnostics", "AppDomainUnload"), TraceSR.GetString(TraceSR.TraceCodeAppDomainUnload), new DictionaryTraceRecord(values), null, null); } this.calledShutdown = true; this.TraceSource.Flush(); } } #pragma warning suppress 56500 //[....]; Taken care of by FxCop catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } LogTraceFailure(null, exception); } } } void ExitOrUnloadEventHandler(object sender, EventArgs e) { ShutdownTracing(); } void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) { Exception e = (Exception)args.ExceptionObject; TraceEvent(TraceEventType.Critical, DiagnosticsTraceCode.UnhandledException, "UnhandledException", TraceSR.GetString(TraceSR.UnhandledException), null, e, null); ShutdownTracing(); } void BuildTrace(TraceEventType type, string msdnTraceCode, string description, TraceRecord trace, Exception exception, object source, out TraceXPathNavigator navigator) { PlainXmlWriter xmlWriter = new PlainXmlWriter(DiagnosticTrace.MaxTraceSize); navigator = xmlWriter.Navigator; this.BuildTrace(xmlWriter, type, msdnTraceCode, description, trace, exception, source); if (!this.TraceSource.ShouldLogPii) { navigator.RemovePii(DiagnosticStrings.HeadersPaths); } } static string CreateSourceString(object source) { return source.GetType().ToString() + "/" + source.GetHashCode().ToString(CultureInfo.CurrentCulture); } void BuildTrace(PlainXmlWriter xml, TraceEventType type, string msdnTraceCode, string description, TraceRecord trace, Exception exception, object source) { xml.WriteStartElement(DiagnosticStrings.TraceRecordTag); xml.WriteAttributeString(DiagnosticStrings.NamespaceTag, DiagnosticTrace.TraceRecordVersion); xml.WriteAttributeString(DiagnosticStrings.SeverityTag, DiagnosticTrace.LookupSeverity(type)); xml.WriteElementString(DiagnosticStrings.TraceCodeTag, msdnTraceCode); xml.WriteElementString(DiagnosticStrings.DescriptionTag, description); xml.WriteElementString(DiagnosticStrings.AppDomain, this.AppDomainFriendlyName); if (source != null) { xml.WriteElementString(DiagnosticStrings.SourceTag, CreateSourceString(source)); } if (trace != null) { xml.WriteStartElement(DiagnosticStrings.ExtendedDataTag); xml.WriteAttributeString(DiagnosticStrings.NamespaceTag, trace.EventId); trace.WriteTo(xml); xml.WriteEndElement(); } if (exception != null) { xml.WriteStartElement(DiagnosticStrings.ExceptionTag); this.AddExceptionToTraceString(xml, exception); xml.WriteEndElement(); } xml.WriteEndElement(); } static internal Guid ActivityId { get { return System.Runtime.Diagnostics.DiagnosticTrace.ActivityId; } set { System.Runtime.Diagnostics.DiagnosticTrace.ActivityId = value; } } void AddExceptionToTraceString(XmlWriter xml, Exception exception) { xml.WriteElementString(DiagnosticStrings.ExceptionTypeTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(exception.GetType().AssemblyQualifiedName)); xml.WriteElementString(DiagnosticStrings.MessageTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(exception.Message)); xml.WriteElementString(DiagnosticStrings.StackTraceTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(this.StackTraceString(exception))); xml.WriteElementString(DiagnosticStrings.ExceptionStringTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(exception.ToString())); Win32Exception win32Exception = exception as Win32Exception; if (win32Exception != null) { xml.WriteElementString(DiagnosticStrings.NativeErrorCodeTag, win32Exception.NativeErrorCode.ToString("X", CultureInfo.InvariantCulture)); } if (exception.Data != null && exception.Data.Count > 0) { xml.WriteStartElement(DiagnosticStrings.DataItemsTag); foreach (object dataItem in exception.Data.Keys) { xml.WriteStartElement(DiagnosticStrings.DataTag); xml.WriteElementString(DiagnosticStrings.KeyTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(dataItem.ToString())); xml.WriteElementString(DiagnosticStrings.ValueTag, System.Runtime.Diagnostics.DiagnosticTrace.XmlEncode(exception.Data[dataItem].ToString())); xml.WriteEndElement(); } xml.WriteEndElement(); } if (exception.InnerException != null) { xml.WriteStartElement(DiagnosticStrings.InnerExceptionTag); this.AddExceptionToTraceString(xml, exception.InnerException); xml.WriteEndElement(); } } string StackTraceString(Exception exception) { string retval = exception.StackTrace; if (string.IsNullOrEmpty(retval)) { // This means that the exception hasn't been thrown yet. We need to manufacture the stack then. StackTrace stackTrace = new StackTrace(false); // Figure out how many frames should be throw away System.Diagnostics.StackFrame[] stackFrames = stackTrace.GetFrames(); int frameCount = 0; bool breakLoop = false; foreach (StackFrame frame in stackFrames) { string methodName = frame.GetMethod().Name; switch (methodName) { case "StackTraceString": case "AddExceptionToTraceString": case "BuildTrace": case "TraceEvent": case "TraceException": ++frameCount; break; default: if (methodName.StartsWith("ThrowHelper", StringComparison.Ordinal)) { ++ frameCount; } else { breakLoop = true; } break; } if (breakLoop) { break; } } stackTrace = new StackTrace(frameCount, false); retval = stackTrace.ToString(); } return retval; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AdPostCacheSubstitution.cs
- Compiler.cs
- DataGridViewColumnDesigner.cs
- ReadOnlyDictionary.cs
- InheritablePropertyChangeInfo.cs
- DefaultMemberAttribute.cs
- HttpCacheParams.cs
- SQLBytesStorage.cs
- TextLineBreak.cs
- GeometryValueSerializer.cs
- SemanticResultValue.cs
- BuildResultCache.cs
- BufferModesCollection.cs
- Switch.cs
- LocalServiceSecuritySettings.cs
- ValidationHelper.cs
- ViewStateModeByIdAttribute.cs
- SmiMetaDataProperty.cs
- PrePrepareMethodAttribute.cs
- BitmapScalingModeValidation.cs
- ReadOnlyDictionary.cs
- CountAggregationOperator.cs
- TemplateNameScope.cs
- Executor.cs
- CustomError.cs
- updateconfighost.cs
- SafeArrayTypeMismatchException.cs
- LocationReferenceValue.cs
- SystemException.cs
- Module.cs
- ConnectionInterfaceCollection.cs
- CodeTypeDelegate.cs
- XPathAncestorQuery.cs
- CodeDOMUtility.cs
- MimeWriter.cs
- SwitchAttribute.cs
- EventTrigger.cs
- SignatureDescription.cs
- messageonlyhwndwrapper.cs
- OperationResponse.cs
- ContentDisposition.cs
- NullToBooleanConverter.cs
- ProofTokenCryptoHandle.cs
- KeyboardNavigation.cs
- FixedPage.cs
- StorageEntitySetMapping.cs
- TriggerActionCollection.cs
- ItemAutomationPeer.cs
- BaseTemplateBuildProvider.cs
- IList.cs
- CaseStatement.cs
- SQLMoney.cs
- DBConnection.cs
- DataFormats.cs
- AuthenticationServiceManager.cs
- LinqDataSourceDisposeEventArgs.cs
- HostingEnvironment.cs
- GetWinFXPath.cs
- WebBrowserUriTypeConverter.cs
- ClientSponsor.cs
- coordinator.cs
- ByteAnimationBase.cs
- OrderByBuilder.cs
- ScrollableControl.cs
- HitTestWithGeometryDrawingContextWalker.cs
- RecognizedWordUnit.cs
- TemplateBuilder.cs
- PointCollectionConverter.cs
- AnnotationDocumentPaginator.cs
- TypeLibConverter.cs
- SharedConnectionListener.cs
- NativeObjectSecurity.cs
- FontClient.cs
- SoapServerProtocol.cs
- CollectionBuilder.cs
- SvcFileManager.cs
- ExeContext.cs
- ConfigurationSectionGroupCollection.cs
- AssociationSetEnd.cs
- DataGridViewCellStyle.cs
- CodeMethodReturnStatement.cs
- UpdateTracker.cs
- GlyphingCache.cs
- WindowsListView.cs
- DataGridViewCellValueEventArgs.cs
- OracleFactory.cs
- WebServicesSection.cs
- TreeNodeBinding.cs
- xmlfixedPageInfo.cs
- METAHEADER.cs
- AvTraceFormat.cs
- InkCanvasAutomationPeer.cs
- RowsCopiedEventArgs.cs
- Int32.cs
- XmlEncoding.cs
- XmlHierarchicalEnumerable.cs
- NativeMethods.cs
- ObjectStateEntryDbUpdatableDataRecord.cs
- RelatedView.cs
- CultureSpecificStringDictionary.cs