DiagnosticTrace.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / tx / System / Transactions / Trace / DiagnosticTrace.cs / 1305376 / DiagnosticTrace.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Transactions.Diagnostics 
{ 
    /// 
    /// Server side infrastructure file on the server for use 
    /// by Indigo infrastructure classes
    ///
    /// DiagnosticTrace consists of static methods, properties and collections
    /// that can be accessed by Indigo infrastructure code to provide 
    /// instrumentation.
    ///  
 
    using System;
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Runtime.Remoting.Messaging; 
    using System.Security;
    using System.Text; 
    using System.Threading; 
    using System.Web;
    using System.Xml; 
    using System.Xml.XPath;
    using System.ComponentModel;

    internal static class DiagnosticTrace 
    {
        internal const string DefaultTraceListenerName = "Default"; 
        static TraceSource traceSource = null; 
        static bool tracingEnabled = true;
        static bool haveListeners = false; 
        static Dictionary traceEventTypeNames;
        static object localSyncObject = new object();
        static int traceFailureCount = 0;
        static int traceFailureThreshold = 0; 
        static SourceLevels level;
        static bool calledShutdown = false; 
        static bool shouldCorrelate = false; 
        static bool shouldTraceVerbose = false;
        static bool shouldTraceInformation = false; 
        static bool shouldTraceWarning = false;
        static bool shouldTraceError = false;
        static bool shouldTraceCritical = false;
        internal static Guid EmptyGuid = Guid.Empty; 
        static string AppDomainFriendlyName = null;
 
        const string subType = ""; 
        const string version = "1";
 
        const int traceFailureLogThreshold = 10;
        const string EventLogSourceName = ".NET Runtime";
        const string TraceSourceName = "System.Transactions";
        const string TraceRecordVersion = "http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"; 

        // System.Diagnostics.Process has a FullTrust link demand. We satisfy that FullTrust demand and do not leak the 
        // Process object out of this call. 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        static string ProcessName 
        {
            get
            {
                string retval = null; 
                using (Process process = Process.GetCurrentProcess())
                { 
                    retval = process.ProcessName; 
                }
                return retval; 
            }
        }

 
        // System.Diagnostics.Process has a FullTrust link demand. We satisfy that FullTrust demand and do not leak the
        // Process object out of this call. 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        static int ProcessId
        { 
            get
            {
                int retval = -1;
                using (Process process = Process.GetCurrentProcess()) 
                {
                    retval = process.Id; 
                } 

                return retval; 
            }
        }

        static TraceSource TraceSource 
        {
            get 
            { 
                return DiagnosticTrace.traceSource;
            } 

            set
            {
                DiagnosticTrace.traceSource = value; 
            }
        } 
 
        static Dictionary TraceEventTypeNames
        { 
            get
            {
                return DiagnosticTrace.traceEventTypeNames;
            } 
        }
 
        static 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;
            }

            return (level & ~SourceLevels.Warning) != 0 ? level | SourceLevels.ActivityTracing : level; 
        }
 
        static void SetLevel(SourceLevels level) 
        {
            SourceLevels fixedLevel = FixLevel(level); 
            DiagnosticTrace.level = fixedLevel;
            if (DiagnosticTrace.TraceSource != null)
            {
                DiagnosticTrace.TraceSource.Switch.Level = fixedLevel; 
                DiagnosticTrace.shouldCorrelate = DiagnosticTrace.ShouldTrace(TraceEventType.Transfer);
                DiagnosticTrace.shouldTraceVerbose = DiagnosticTrace.ShouldTrace(TraceEventType.Verbose); 
                DiagnosticTrace.shouldTraceInformation = DiagnosticTrace.ShouldTrace(TraceEventType.Information); 
                DiagnosticTrace.shouldTraceWarning = DiagnosticTrace.ShouldTrace(TraceEventType.Warning);
                DiagnosticTrace.shouldTraceError = DiagnosticTrace.ShouldTrace(TraceEventType.Error); 
                DiagnosticTrace.shouldTraceCritical = DiagnosticTrace.ShouldTrace(TraceEventType.Critical);
            }
        }
 
        static void SetLevelThreadSafe(SourceLevels level)
        { 
            if (DiagnosticTrace.TracingEnabled && level != DiagnosticTrace.Level) 
            {
                lock (DiagnosticTrace.localSyncObject) 
                {
                    SetLevel(level);
                }
            } 
        }
 
        internal static SourceLevels Level 
        {
            //Do not call this property from Initialize! 
            get
            {
                if (DiagnosticTrace.TraceSource != null && (DiagnosticTrace.TraceSource.Switch.Level != DiagnosticTrace.level))
                { 
                    DiagnosticTrace.level = DiagnosticTrace.TraceSource.Switch.Level;
                } 
                return DiagnosticTrace.level; 
            }
 
            set
            {
                SetLevelThreadSafe(value);
            } 
        }
 
        internal static bool HaveListeners 
        {
            get 
            {
                return DiagnosticTrace.haveListeners;
            }
        } 

        internal static bool TracingEnabled 
        { 
            get
            { 
                return DiagnosticTrace.tracingEnabled && DiagnosticTrace.traceSource != null;
            }
        }
 
        static DiagnosticTrace()
        { 
            // We own the resource and it hasn't been filled in yet. 
            //needed for logging events to event log
            DiagnosticTrace.AppDomainFriendlyName = AppDomain.CurrentDomain.FriendlyName; 
            DiagnosticTrace.traceEventTypeNames = new Dictionary();
            // Initialize the values here to avoid bringing in unnecessary pages.
            // Address MB#20806
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Critical] = "Critical"; 
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Error] = "Error";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Warning] = "Warning"; 
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Information] = "Information"; 
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Verbose] = "Verbose";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Resume] = "Resume"; 
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Start] = "Start";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Stop] = "Stop";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Suspend] = "Suspend";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Transfer] = "Transfer"; 

#if DEBUG 
            // The following asserts are established to make sure that 
            // the strings we have above continue to be correct. Any failures
            // should be discoverable during development time since this 
            // code is in the main path.
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Critical], TraceEventType.Critical.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Error], TraceEventType.Error.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Warning], TraceEventType.Warning.ToString(), StringComparison.Ordinal)); 
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Information], TraceEventType.Information.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Verbose], TraceEventType.Verbose.ToString(), StringComparison.Ordinal)); 
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Resume], TraceEventType.Resume.ToString(), StringComparison.Ordinal)); 
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Start], TraceEventType.Start.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Stop], TraceEventType.Stop.ToString(), StringComparison.Ordinal)); 
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Suspend], TraceEventType.Suspend.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Transfer], TraceEventType.Transfer.ToString(), StringComparison.Ordinal));
#endif
            DiagnosticTrace.TraceFailureThreshold = DiagnosticTrace.traceFailureLogThreshold; 
            DiagnosticTrace.TraceFailureCount = DiagnosticTrace.TraceFailureThreshold + 1;
 
            try 
            {
                DiagnosticTrace.traceSource = new TraceSource(DiagnosticTrace.TraceSourceName, SourceLevels.Critical); 
                AppDomain currentDomain = AppDomain.CurrentDomain;

                if (DiagnosticTrace.TraceSource.Switch.ShouldTrace(TraceEventType.Critical))
                { 
                    currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
                } 
                currentDomain.DomainUnload += new EventHandler(ExitOrUnloadEventHandler); 
                currentDomain.ProcessExit += new EventHandler(ExitOrUnloadEventHandler);
                DiagnosticTrace.haveListeners = DiagnosticTrace.TraceSource.Listeners.Count > 0; 
                DiagnosticTrace.SetLevel(DiagnosticTrace.TraceSource.Switch.Level);
            }
            catch (System.Configuration.ConfigurationErrorsException)
            { 
                throw;
            } 
            catch (OutOfMemoryException) 
            {
                throw; 
            }
            catch (StackOverflowException)
            {
                throw; 
            }
            catch (ThreadAbortException) 
            { 
                throw;
            } 
            catch (Exception e)
            {
                if (DiagnosticTrace.TraceSource == null)
                { 
                    LogEvent(TraceEventType.Error, String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FailedToCreateTraceSource), e), true);
                } 
                else 
                {
                    DiagnosticTrace.TraceSource = null; 
                    LogEvent(TraceEventType.Error, String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FailedToInitializeTraceSource), e), true);
                }
            }
        } 

        internal static bool ShouldTrace(TraceEventType type) 
        { 
            return 0 != ((int)type & (int)DiagnosticTrace.Level) &&
                (DiagnosticTrace.TraceSource != null) && 
                (DiagnosticTrace.HaveListeners);
        }

        internal static bool ShouldCorrelate 
        {
            get { return DiagnosticTrace.shouldCorrelate; } 
        } 

        internal static bool Critical 
        {
            get { return DiagnosticTrace.shouldTraceCritical; }
        }
 
        internal static bool Error
        { 
            get { return DiagnosticTrace.shouldTraceError; } 
        }
 
        internal static bool Warning
        {
            get { return DiagnosticTrace.shouldTraceWarning; }
        } 

        internal static bool Information 
        { 
            get { return DiagnosticTrace.shouldTraceInformation; }
        } 

        internal static bool Verbose
        {
            get { return DiagnosticTrace.shouldTraceVerbose; } 
        }
 
        static internal void TraceEvent(TraceEventType type, string code, string description) 
        {
            DiagnosticTrace.TraceEvent(type, code, description, null, null, ref DiagnosticTrace.EmptyGuid, false, null); 
        }

        static internal void TraceEvent(TraceEventType type, string code, string description, TraceRecord trace)
        { 
            DiagnosticTrace.TraceEvent(type, code, description, trace, null, ref DiagnosticTrace.EmptyGuid, false, null);
        } 
 
        static internal void TraceEvent(TraceEventType type, string code, string description, TraceRecord trace, Exception exception)
        { 
            DiagnosticTrace.TraceEvent(type, code, description, trace, exception, ref DiagnosticTrace.EmptyGuid, false, null);
        }

        static internal void TraceEvent(TraceEventType type, string code, string description, TraceRecord trace, Exception exception, ref Guid activityId, bool emitTransfer, object source) 
        {
#if DEBUG 
            Debug.Assert(exception == null || type <= TraceEventType.Information); 
            Debug.Assert(!string.IsNullOrEmpty(description), "All TraceCodes should have a description");
#endif 
            if (DiagnosticTrace.ShouldTrace(type))
            {
                using (Activity.CreateActivity(activityId, emitTransfer))
                { 
                    XPathNavigator navigator = BuildTraceString(type, code, description, trace, exception, source);
                    try 
                    { 
                        DiagnosticTrace.TraceSource.TraceData(type, 0, navigator);
                        if (DiagnosticTrace.calledShutdown) 
                        {
                            DiagnosticTrace.TraceSource.Flush();
                        }
                    } 
                    catch (OutOfMemoryException)
                    { 
                        throw; 
                    }
                    catch (StackOverflowException) 
                    {
                        throw;
                    }
                    catch (ThreadAbortException) 
                    {
                        throw; 
                    } 
                    catch (Exception e)
                    { 
                        string traceString = SR.GetString(SR.TraceFailure,
                            type.ToString(),
                            code,
                            description, 
                            source == null ? string.Empty : DiagnosticTrace.CreateSourceString(source));
                        LogTraceFailure(traceString, e); 
                    } 
                }
            } 
        }

        static internal void TraceAndLogEvent(TraceEventType type, string code, string description, TraceRecord trace, Exception exception, ref Guid activityId, object source)
        { 
            bool shouldTrace = DiagnosticTrace.ShouldTrace(type);
            string traceString = null; 
            try 
            {
                LogEvent(type, code, description, trace, exception, source); 

                if (shouldTrace)
                {
                    DiagnosticTrace.TraceEvent(type, code, description, trace, exception, ref activityId, false, source); 
                }
            } 
            catch (OutOfMemoryException) 
            {
                throw; 
            }
            catch (StackOverflowException)
            {
                throw; 
            }
            catch (ThreadAbortException) 
            { 
                throw;
            } 
            catch (Exception e)
            {
                LogTraceFailure(traceString, e);
            } 
        }
 
        static internal void TraceTransfer(Guid newId) 
        {
            Guid oldId = DiagnosticTrace.GetActivityId(); 
            if (DiagnosticTrace.ShouldCorrelate && newId != oldId)
            {
                if (DiagnosticTrace.HaveListeners)
                { 
                    try
                    { 
                        if (newId != oldId) 
                        {
                            DiagnosticTrace.TraceSource.TraceTransfer(0, null, newId); 
                        }
                    }
                    catch (OutOfMemoryException)
                    { 
                        throw;
                    } 
                    catch (StackOverflowException) 
                    {
                        throw; 
                    }
                    catch (ThreadAbortException)
                    {
                        throw; 
                    }
                    catch (Exception e) 
                    { 
                        LogTraceFailure(null, e);
                    } 
                }
            }
        }
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        static internal Guid GetActivityId() 
        { 
            object id = Trace.CorrelationManager.ActivityId;
            return id == null ? Guid.Empty : (Guid)id; 
        }

        static internal void GetActivityId(ref Guid guid)
        { 
            //If activity id propagation is disabled for performance, we return nothing avoiding CallContext access.
            if (DiagnosticTrace.ShouldCorrelate) 
            { 
                guid = DiagnosticTrace.GetActivityId();
            } 
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        static internal void SetActivityId(Guid id) 
        {
            Trace.CorrelationManager.ActivityId = id; 
        } 

        static string CreateSourceString(object source) 
        {
            return source.GetType().ToString() + "/" + source.GetHashCode().ToString(CultureInfo.CurrentCulture);
        }
 
        static void LogEvent(TraceEventType type, string code, string description, TraceRecord trace, Exception exception, object source)
        { 
            StringBuilder traceString = new StringBuilder(SR.GetString(SR.EventLogValue, 
                DiagnosticTrace.ProcessName,
                DiagnosticTrace.ProcessId.ToString(CultureInfo.CurrentCulture), 
                code,
                description));
            if (source != null)
            { 
                traceString.AppendLine(SR.GetString(SR.EventLogSourceValue, DiagnosticTrace.CreateSourceString(source)));
            } 
 
            if (exception != null)
            { 
                traceString.AppendLine(SR.GetString(SR.EventLogExceptionValue, exception.ToString()));
            }

            if (trace != null) 
            {
                traceString.AppendLine(SR.GetString(SR.EventLogEventIdValue, trace.EventId)); 
                traceString.AppendLine(SR.GetString(SR.EventLogTraceValue, trace.ToString())); 
            }
 
            LogEvent(type, traceString.ToString(), false);
        }

        static internal void LogEvent(TraceEventType type, string message, bool addProcessInfo) 
        {
            if (addProcessInfo) 
            { 
                message = String.Format(CultureInfo.CurrentCulture, "{0}: {1}\n{2}: {3}\n{4}", DiagnosticStrings.ProcessName, DiagnosticTrace.ProcessName, DiagnosticStrings.ProcessId, DiagnosticTrace.ProcessId, message);
            } 

            LogEvent(type, message);
        }
 
        static internal void LogEvent(TraceEventType type, string message)
        { 
            try 
            {
                const int MaxEventLogLength = 8192; 
                if (!string.IsNullOrEmpty(message) && message.Length >= MaxEventLogLength)
                {
                    message = message.Substring(0, MaxEventLogLength - 1);
                } 
                EventLog.WriteEntry(DiagnosticTrace.EventLogSourceName, message, EventLogEntryTypeFromEventType(type));
            } 
            catch (OutOfMemoryException) 
            {
                throw; 
            }
            catch (StackOverflowException)
            {
                throw; 
            }
            catch (ThreadAbortException) 
            { 
                throw;
            } 
            catch
            {
            }
        } 

        static string LookupSeverity(TraceEventType type) 
        { 
            int level = (int)type & (int)SourceLevels.Verbose;
            if (((int)type & ((int)TraceEventType.Start | (int)TraceEventType.Stop)) != 0) 
            {
                level = (int)type;
            }
            else if (level == 0) 
            {
                level = (int)TraceEventType.Verbose; 
            } 
            return DiagnosticTrace.TraceEventTypeNames[level];
        } 

        static int TraceFailureCount
        {
            get { return DiagnosticTrace.traceFailureCount; } 
            set { DiagnosticTrace.traceFailureCount = value; }
        } 
 
        static int TraceFailureThreshold
        { 
            get { return DiagnosticTrace.traceFailureThreshold; }
            set { DiagnosticTrace.traceFailureThreshold = value; }
        }
 
        //log failure every traceFailureLogThreshold time, increase the threshold progressively
        static void LogTraceFailure(string traceString, Exception e) 
        { 
            if (e != null)
            { 
                traceString = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FailedToTraceEvent), e, traceString != null ? traceString : "");
            }
            lock (DiagnosticTrace.localSyncObject)
            { 
                if (DiagnosticTrace.TraceFailureCount > DiagnosticTrace.TraceFailureThreshold)
                { 
                    DiagnosticTrace.TraceFailureCount = 1; 
                    DiagnosticTrace.TraceFailureThreshold *= 2;
                    LogEvent(TraceEventType.Error, traceString, true); 
                }
                else
                {
                    DiagnosticTrace.TraceFailureCount++; 
                }
            } 
        } 

        static void ShutdownTracing() 
        {
            if (null != DiagnosticTrace.TraceSource)
            {
                try 
                {
                    if (DiagnosticTrace.Level != SourceLevels.Off) 
                    { 
                        if (DiagnosticTrace.Information)
                        { 
                            Dictionary values = new Dictionary(3);
                            values["AppDomain.FriendlyName"] = AppDomain.CurrentDomain.FriendlyName;
                            values["ProcessName"] = DiagnosticTrace.ProcessName;
                            values["ProcessId"] = DiagnosticTrace.ProcessId.ToString(CultureInfo.CurrentCulture); 
                            DiagnosticTrace.TraceEvent(TraceEventType.Information, DiagnosticTraceCode.AppDomainUnload, SR.GetString(SR.TraceCodeAppDomainUnloading),
                                new DictionaryTraceRecord(values), null, ref DiagnosticTrace.EmptyGuid, false, null); 
                        } 
                        DiagnosticTrace.calledShutdown = true;
                        DiagnosticTrace.TraceSource.Flush(); 
                    }
                }
                catch (OutOfMemoryException)
                { 
                    throw;
                } 
                catch (StackOverflowException) 
                {
                    throw; 
                }
                catch (ThreadAbortException)
                {
                    throw; 
                }
                catch (Exception exception) 
                { 
                    LogTraceFailure(null, exception);
                } 
            }
        }

        static void ExitOrUnloadEventHandler(object sender, EventArgs e) 
        {
            ShutdownTracing(); 
        } 

        static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) 
        {
            Exception e = (Exception)args.ExceptionObject;
            TraceEvent(TraceEventType.Critical, DiagnosticTraceCode.UnhandledException, SR.GetString(SR.UnhandledException), null, e, ref DiagnosticTrace.EmptyGuid, false, null);
            ShutdownTracing(); 
        }
 
        static XPathNavigator BuildTraceString(TraceEventType type, 
                                      string code,
                                      string description, 
                                      TraceRecord trace,
                                      Exception exception,
                                      object source)
        { 
            return DiagnosticTrace.BuildTraceString(new PlainXmlWriter(), type, code, description, trace, exception, source);
        } 
 
        static XPathNavigator BuildTraceString(PlainXmlWriter xml,
                                       TraceEventType type, 
                                       string code,
                                       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, code);
            xml.WriteElementString(DiagnosticStrings.DescriptionTag, description);
            xml.WriteElementString(DiagnosticStrings.AppDomain, DiagnosticTrace.AppDomainFriendlyName); 

            if (source != null) 
            { 
                xml.WriteElementString(DiagnosticStrings.SourceTag, DiagnosticTrace.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);
                DiagnosticTrace.AddExceptionToTraceString(xml, exception); 
                xml.WriteEndElement(); 
            }
 
            xml.WriteEndElement();

            return xml.ToNavigator();
        } 

        static void AddExceptionToTraceString(XmlWriter xml, Exception exception) 
        { 
            xml.WriteElementString(DiagnosticStrings.ExceptionTypeTag, DiagnosticTrace.XmlEncode(exception.GetType().AssemblyQualifiedName));
            xml.WriteElementString(DiagnosticStrings.MessageTag, DiagnosticTrace.XmlEncode(exception.Message)); 
            xml.WriteElementString(DiagnosticStrings.StackTraceTag, DiagnosticTrace.XmlEncode(DiagnosticTrace.StackTraceString(exception)));
            xml.WriteElementString(DiagnosticStrings.ExceptionStringTag, 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);
                    //Fix for Watson bug CSDMain 136718 - Add the null check incase the value is null. Only if both the key and value are non null, 
                    //write out the xml elements corresponding to them 
                    if(dataItem != null && exception.Data[dataItem] != null)
                    { 
                        xml.WriteElementString(DiagnosticStrings.KeyTag, DiagnosticTrace.XmlEncode(dataItem.ToString()));
                        xml.WriteElementString(DiagnosticStrings.ValueTag, DiagnosticTrace.XmlEncode(exception.Data[dataItem].ToString()));
                    }
                    xml.WriteEndElement(); 
                }
                xml.WriteEndElement(); 
            } 
            if (exception.InnerException != null)
            { 
                xml.WriteStartElement(DiagnosticStrings.InnerExceptionTag);
                DiagnosticTrace.AddExceptionToTraceString(xml, exception.InnerException);
                xml.WriteEndElement();
            } 
        }
 
        static 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(true); 
                System.Diagnostics.StackFrame[] stackFrames = stackTrace.GetFrames();
                int numFramesToSkip = 0; 
                foreach (System.Diagnostics.StackFrame stackFrame in stackFrames) 
                {
                    Type declaringType = stackFrame.GetMethod().DeclaringType; 
                    if (declaringType == typeof(DiagnosticTrace))
                    {
                        ++numFramesToSkip;
                    } 
                    else
                    { 
                        break; 
                    }
                } 
                stackTrace = new StackTrace(numFramesToSkip);
                retval = stackTrace.ToString();
            }
            return retval; 
        }
 
        //only used for exceptions, perf is not important 
        static internal string XmlEncode(string text)
        { 
            if (text == null)
            {
                return null;
            } 

            int len = text.Length; 
            StringBuilder encodedText = new StringBuilder(len + 8); //perf optimization, expecting no more than 2 > characters 

            for (int i = 0; i < len; ++i) 
            {
                char ch = text[i];
                switch (ch)
                { 
                    case '<':
                        encodedText.Append("<"); 
                        break; 
                    case '>':
                        encodedText.Append(">"); 
                        break;
                    case '&':
                        encodedText.Append("&");
                        break; 
                    default:
                        encodedText.Append(ch); 
                        break; 
                }
            } 
            return encodedText.ToString();
        }

        // 
        // Converts incompatible serverity enumeration TraceEvetType into EventLogEntryType
        // 
        static EventLogEntryType EventLogEntryTypeFromEventType(TraceEventType type) 
        {
            EventLogEntryType retval = EventLogEntryType.Information; 
            switch (type)
            {
                case TraceEventType.Critical:
                case TraceEventType.Error: 
                    retval = EventLogEntryType.Error;
                    break; 
                case TraceEventType.Warning: 
                    retval = EventLogEntryType.Warning;
                    break; 
            }
            return retval;
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Transactions.Diagnostics 
{ 
    /// 
    /// Server side infrastructure file on the server for use 
    /// by Indigo infrastructure classes
    ///
    /// DiagnosticTrace consists of static methods, properties and collections
    /// that can be accessed by Indigo infrastructure code to provide 
    /// instrumentation.
    ///  
 
    using System;
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Runtime.Remoting.Messaging; 
    using System.Security;
    using System.Text; 
    using System.Threading; 
    using System.Web;
    using System.Xml; 
    using System.Xml.XPath;
    using System.ComponentModel;

    internal static class DiagnosticTrace 
    {
        internal const string DefaultTraceListenerName = "Default"; 
        static TraceSource traceSource = null; 
        static bool tracingEnabled = true;
        static bool haveListeners = false; 
        static Dictionary traceEventTypeNames;
        static object localSyncObject = new object();
        static int traceFailureCount = 0;
        static int traceFailureThreshold = 0; 
        static SourceLevels level;
        static bool calledShutdown = false; 
        static bool shouldCorrelate = false; 
        static bool shouldTraceVerbose = false;
        static bool shouldTraceInformation = false; 
        static bool shouldTraceWarning = false;
        static bool shouldTraceError = false;
        static bool shouldTraceCritical = false;
        internal static Guid EmptyGuid = Guid.Empty; 
        static string AppDomainFriendlyName = null;
 
        const string subType = ""; 
        const string version = "1";
 
        const int traceFailureLogThreshold = 10;
        const string EventLogSourceName = ".NET Runtime";
        const string TraceSourceName = "System.Transactions";
        const string TraceRecordVersion = "http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"; 

        // System.Diagnostics.Process has a FullTrust link demand. We satisfy that FullTrust demand and do not leak the 
        // Process object out of this call. 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        static string ProcessName 
        {
            get
            {
                string retval = null; 
                using (Process process = Process.GetCurrentProcess())
                { 
                    retval = process.ProcessName; 
                }
                return retval; 
            }
        }

 
        // System.Diagnostics.Process has a FullTrust link demand. We satisfy that FullTrust demand and do not leak the
        // Process object out of this call. 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        static int ProcessId
        { 
            get
            {
                int retval = -1;
                using (Process process = Process.GetCurrentProcess()) 
                {
                    retval = process.Id; 
                } 

                return retval; 
            }
        }

        static TraceSource TraceSource 
        {
            get 
            { 
                return DiagnosticTrace.traceSource;
            } 

            set
            {
                DiagnosticTrace.traceSource = value; 
            }
        } 
 
        static Dictionary TraceEventTypeNames
        { 
            get
            {
                return DiagnosticTrace.traceEventTypeNames;
            } 
        }
 
        static 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;
            }

            return (level & ~SourceLevels.Warning) != 0 ? level | SourceLevels.ActivityTracing : level; 
        }
 
        static void SetLevel(SourceLevels level) 
        {
            SourceLevels fixedLevel = FixLevel(level); 
            DiagnosticTrace.level = fixedLevel;
            if (DiagnosticTrace.TraceSource != null)
            {
                DiagnosticTrace.TraceSource.Switch.Level = fixedLevel; 
                DiagnosticTrace.shouldCorrelate = DiagnosticTrace.ShouldTrace(TraceEventType.Transfer);
                DiagnosticTrace.shouldTraceVerbose = DiagnosticTrace.ShouldTrace(TraceEventType.Verbose); 
                DiagnosticTrace.shouldTraceInformation = DiagnosticTrace.ShouldTrace(TraceEventType.Information); 
                DiagnosticTrace.shouldTraceWarning = DiagnosticTrace.ShouldTrace(TraceEventType.Warning);
                DiagnosticTrace.shouldTraceError = DiagnosticTrace.ShouldTrace(TraceEventType.Error); 
                DiagnosticTrace.shouldTraceCritical = DiagnosticTrace.ShouldTrace(TraceEventType.Critical);
            }
        }
 
        static void SetLevelThreadSafe(SourceLevels level)
        { 
            if (DiagnosticTrace.TracingEnabled && level != DiagnosticTrace.Level) 
            {
                lock (DiagnosticTrace.localSyncObject) 
                {
                    SetLevel(level);
                }
            } 
        }
 
        internal static SourceLevels Level 
        {
            //Do not call this property from Initialize! 
            get
            {
                if (DiagnosticTrace.TraceSource != null && (DiagnosticTrace.TraceSource.Switch.Level != DiagnosticTrace.level))
                { 
                    DiagnosticTrace.level = DiagnosticTrace.TraceSource.Switch.Level;
                } 
                return DiagnosticTrace.level; 
            }
 
            set
            {
                SetLevelThreadSafe(value);
            } 
        }
 
        internal static bool HaveListeners 
        {
            get 
            {
                return DiagnosticTrace.haveListeners;
            }
        } 

        internal static bool TracingEnabled 
        { 
            get
            { 
                return DiagnosticTrace.tracingEnabled && DiagnosticTrace.traceSource != null;
            }
        }
 
        static DiagnosticTrace()
        { 
            // We own the resource and it hasn't been filled in yet. 
            //needed for logging events to event log
            DiagnosticTrace.AppDomainFriendlyName = AppDomain.CurrentDomain.FriendlyName; 
            DiagnosticTrace.traceEventTypeNames = new Dictionary();
            // Initialize the values here to avoid bringing in unnecessary pages.
            // Address MB#20806
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Critical] = "Critical"; 
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Error] = "Error";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Warning] = "Warning"; 
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Information] = "Information"; 
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Verbose] = "Verbose";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Resume] = "Resume"; 
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Start] = "Start";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Stop] = "Stop";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Suspend] = "Suspend";
            DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Transfer] = "Transfer"; 

#if DEBUG 
            // The following asserts are established to make sure that 
            // the strings we have above continue to be correct. Any failures
            // should be discoverable during development time since this 
            // code is in the main path.
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Critical], TraceEventType.Critical.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Error], TraceEventType.Error.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Warning], TraceEventType.Warning.ToString(), StringComparison.Ordinal)); 
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Information], TraceEventType.Information.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Verbose], TraceEventType.Verbose.ToString(), StringComparison.Ordinal)); 
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Resume], TraceEventType.Resume.ToString(), StringComparison.Ordinal)); 
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Start], TraceEventType.Start.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Stop], TraceEventType.Stop.ToString(), StringComparison.Ordinal)); 
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Suspend], TraceEventType.Suspend.ToString(), StringComparison.Ordinal));
            Debug.Assert(string.Equals(DiagnosticTrace.traceEventTypeNames[(int)TraceEventType.Transfer], TraceEventType.Transfer.ToString(), StringComparison.Ordinal));
#endif
            DiagnosticTrace.TraceFailureThreshold = DiagnosticTrace.traceFailureLogThreshold; 
            DiagnosticTrace.TraceFailureCount = DiagnosticTrace.TraceFailureThreshold + 1;
 
            try 
            {
                DiagnosticTrace.traceSource = new TraceSource(DiagnosticTrace.TraceSourceName, SourceLevels.Critical); 
                AppDomain currentDomain = AppDomain.CurrentDomain;

                if (DiagnosticTrace.TraceSource.Switch.ShouldTrace(TraceEventType.Critical))
                { 
                    currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
                } 
                currentDomain.DomainUnload += new EventHandler(ExitOrUnloadEventHandler); 
                currentDomain.ProcessExit += new EventHandler(ExitOrUnloadEventHandler);
                DiagnosticTrace.haveListeners = DiagnosticTrace.TraceSource.Listeners.Count > 0; 
                DiagnosticTrace.SetLevel(DiagnosticTrace.TraceSource.Switch.Level);
            }
            catch (System.Configuration.ConfigurationErrorsException)
            { 
                throw;
            } 
            catch (OutOfMemoryException) 
            {
                throw; 
            }
            catch (StackOverflowException)
            {
                throw; 
            }
            catch (ThreadAbortException) 
            { 
                throw;
            } 
            catch (Exception e)
            {
                if (DiagnosticTrace.TraceSource == null)
                { 
                    LogEvent(TraceEventType.Error, String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FailedToCreateTraceSource), e), true);
                } 
                else 
                {
                    DiagnosticTrace.TraceSource = null; 
                    LogEvent(TraceEventType.Error, String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FailedToInitializeTraceSource), e), true);
                }
            }
        } 

        internal static bool ShouldTrace(TraceEventType type) 
        { 
            return 0 != ((int)type & (int)DiagnosticTrace.Level) &&
                (DiagnosticTrace.TraceSource != null) && 
                (DiagnosticTrace.HaveListeners);
        }

        internal static bool ShouldCorrelate 
        {
            get { return DiagnosticTrace.shouldCorrelate; } 
        } 

        internal static bool Critical 
        {
            get { return DiagnosticTrace.shouldTraceCritical; }
        }
 
        internal static bool Error
        { 
            get { return DiagnosticTrace.shouldTraceError; } 
        }
 
        internal static bool Warning
        {
            get { return DiagnosticTrace.shouldTraceWarning; }
        } 

        internal static bool Information 
        { 
            get { return DiagnosticTrace.shouldTraceInformation; }
        } 

        internal static bool Verbose
        {
            get { return DiagnosticTrace.shouldTraceVerbose; } 
        }
 
        static internal void TraceEvent(TraceEventType type, string code, string description) 
        {
            DiagnosticTrace.TraceEvent(type, code, description, null, null, ref DiagnosticTrace.EmptyGuid, false, null); 
        }

        static internal void TraceEvent(TraceEventType type, string code, string description, TraceRecord trace)
        { 
            DiagnosticTrace.TraceEvent(type, code, description, trace, null, ref DiagnosticTrace.EmptyGuid, false, null);
        } 
 
        static internal void TraceEvent(TraceEventType type, string code, string description, TraceRecord trace, Exception exception)
        { 
            DiagnosticTrace.TraceEvent(type, code, description, trace, exception, ref DiagnosticTrace.EmptyGuid, false, null);
        }

        static internal void TraceEvent(TraceEventType type, string code, string description, TraceRecord trace, Exception exception, ref Guid activityId, bool emitTransfer, object source) 
        {
#if DEBUG 
            Debug.Assert(exception == null || type <= TraceEventType.Information); 
            Debug.Assert(!string.IsNullOrEmpty(description), "All TraceCodes should have a description");
#endif 
            if (DiagnosticTrace.ShouldTrace(type))
            {
                using (Activity.CreateActivity(activityId, emitTransfer))
                { 
                    XPathNavigator navigator = BuildTraceString(type, code, description, trace, exception, source);
                    try 
                    { 
                        DiagnosticTrace.TraceSource.TraceData(type, 0, navigator);
                        if (DiagnosticTrace.calledShutdown) 
                        {
                            DiagnosticTrace.TraceSource.Flush();
                        }
                    } 
                    catch (OutOfMemoryException)
                    { 
                        throw; 
                    }
                    catch (StackOverflowException) 
                    {
                        throw;
                    }
                    catch (ThreadAbortException) 
                    {
                        throw; 
                    } 
                    catch (Exception e)
                    { 
                        string traceString = SR.GetString(SR.TraceFailure,
                            type.ToString(),
                            code,
                            description, 
                            source == null ? string.Empty : DiagnosticTrace.CreateSourceString(source));
                        LogTraceFailure(traceString, e); 
                    } 
                }
            } 
        }

        static internal void TraceAndLogEvent(TraceEventType type, string code, string description, TraceRecord trace, Exception exception, ref Guid activityId, object source)
        { 
            bool shouldTrace = DiagnosticTrace.ShouldTrace(type);
            string traceString = null; 
            try 
            {
                LogEvent(type, code, description, trace, exception, source); 

                if (shouldTrace)
                {
                    DiagnosticTrace.TraceEvent(type, code, description, trace, exception, ref activityId, false, source); 
                }
            } 
            catch (OutOfMemoryException) 
            {
                throw; 
            }
            catch (StackOverflowException)
            {
                throw; 
            }
            catch (ThreadAbortException) 
            { 
                throw;
            } 
            catch (Exception e)
            {
                LogTraceFailure(traceString, e);
            } 
        }
 
        static internal void TraceTransfer(Guid newId) 
        {
            Guid oldId = DiagnosticTrace.GetActivityId(); 
            if (DiagnosticTrace.ShouldCorrelate && newId != oldId)
            {
                if (DiagnosticTrace.HaveListeners)
                { 
                    try
                    { 
                        if (newId != oldId) 
                        {
                            DiagnosticTrace.TraceSource.TraceTransfer(0, null, newId); 
                        }
                    }
                    catch (OutOfMemoryException)
                    { 
                        throw;
                    } 
                    catch (StackOverflowException) 
                    {
                        throw; 
                    }
                    catch (ThreadAbortException)
                    {
                        throw; 
                    }
                    catch (Exception e) 
                    { 
                        LogTraceFailure(null, e);
                    } 
                }
            }
        }
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        static internal Guid GetActivityId() 
        { 
            object id = Trace.CorrelationManager.ActivityId;
            return id == null ? Guid.Empty : (Guid)id; 
        }

        static internal void GetActivityId(ref Guid guid)
        { 
            //If activity id propagation is disabled for performance, we return nothing avoiding CallContext access.
            if (DiagnosticTrace.ShouldCorrelate) 
            { 
                guid = DiagnosticTrace.GetActivityId();
            } 
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        static internal void SetActivityId(Guid id) 
        {
            Trace.CorrelationManager.ActivityId = id; 
        } 

        static string CreateSourceString(object source) 
        {
            return source.GetType().ToString() + "/" + source.GetHashCode().ToString(CultureInfo.CurrentCulture);
        }
 
        static void LogEvent(TraceEventType type, string code, string description, TraceRecord trace, Exception exception, object source)
        { 
            StringBuilder traceString = new StringBuilder(SR.GetString(SR.EventLogValue, 
                DiagnosticTrace.ProcessName,
                DiagnosticTrace.ProcessId.ToString(CultureInfo.CurrentCulture), 
                code,
                description));
            if (source != null)
            { 
                traceString.AppendLine(SR.GetString(SR.EventLogSourceValue, DiagnosticTrace.CreateSourceString(source)));
            } 
 
            if (exception != null)
            { 
                traceString.AppendLine(SR.GetString(SR.EventLogExceptionValue, exception.ToString()));
            }

            if (trace != null) 
            {
                traceString.AppendLine(SR.GetString(SR.EventLogEventIdValue, trace.EventId)); 
                traceString.AppendLine(SR.GetString(SR.EventLogTraceValue, trace.ToString())); 
            }
 
            LogEvent(type, traceString.ToString(), false);
        }

        static internal void LogEvent(TraceEventType type, string message, bool addProcessInfo) 
        {
            if (addProcessInfo) 
            { 
                message = String.Format(CultureInfo.CurrentCulture, "{0}: {1}\n{2}: {3}\n{4}", DiagnosticStrings.ProcessName, DiagnosticTrace.ProcessName, DiagnosticStrings.ProcessId, DiagnosticTrace.ProcessId, message);
            } 

            LogEvent(type, message);
        }
 
        static internal void LogEvent(TraceEventType type, string message)
        { 
            try 
            {
                const int MaxEventLogLength = 8192; 
                if (!string.IsNullOrEmpty(message) && message.Length >= MaxEventLogLength)
                {
                    message = message.Substring(0, MaxEventLogLength - 1);
                } 
                EventLog.WriteEntry(DiagnosticTrace.EventLogSourceName, message, EventLogEntryTypeFromEventType(type));
            } 
            catch (OutOfMemoryException) 
            {
                throw; 
            }
            catch (StackOverflowException)
            {
                throw; 
            }
            catch (ThreadAbortException) 
            { 
                throw;
            } 
            catch
            {
            }
        } 

        static string LookupSeverity(TraceEventType type) 
        { 
            int level = (int)type & (int)SourceLevels.Verbose;
            if (((int)type & ((int)TraceEventType.Start | (int)TraceEventType.Stop)) != 0) 
            {
                level = (int)type;
            }
            else if (level == 0) 
            {
                level = (int)TraceEventType.Verbose; 
            } 
            return DiagnosticTrace.TraceEventTypeNames[level];
        } 

        static int TraceFailureCount
        {
            get { return DiagnosticTrace.traceFailureCount; } 
            set { DiagnosticTrace.traceFailureCount = value; }
        } 
 
        static int TraceFailureThreshold
        { 
            get { return DiagnosticTrace.traceFailureThreshold; }
            set { DiagnosticTrace.traceFailureThreshold = value; }
        }
 
        //log failure every traceFailureLogThreshold time, increase the threshold progressively
        static void LogTraceFailure(string traceString, Exception e) 
        { 
            if (e != null)
            { 
                traceString = String.Format(CultureInfo.CurrentCulture, SR.GetString(SR.FailedToTraceEvent), e, traceString != null ? traceString : "");
            }
            lock (DiagnosticTrace.localSyncObject)
            { 
                if (DiagnosticTrace.TraceFailureCount > DiagnosticTrace.TraceFailureThreshold)
                { 
                    DiagnosticTrace.TraceFailureCount = 1; 
                    DiagnosticTrace.TraceFailureThreshold *= 2;
                    LogEvent(TraceEventType.Error, traceString, true); 
                }
                else
                {
                    DiagnosticTrace.TraceFailureCount++; 
                }
            } 
        } 

        static void ShutdownTracing() 
        {
            if (null != DiagnosticTrace.TraceSource)
            {
                try 
                {
                    if (DiagnosticTrace.Level != SourceLevels.Off) 
                    { 
                        if (DiagnosticTrace.Information)
                        { 
                            Dictionary values = new Dictionary(3);
                            values["AppDomain.FriendlyName"] = AppDomain.CurrentDomain.FriendlyName;
                            values["ProcessName"] = DiagnosticTrace.ProcessName;
                            values["ProcessId"] = DiagnosticTrace.ProcessId.ToString(CultureInfo.CurrentCulture); 
                            DiagnosticTrace.TraceEvent(TraceEventType.Information, DiagnosticTraceCode.AppDomainUnload, SR.GetString(SR.TraceCodeAppDomainUnloading),
                                new DictionaryTraceRecord(values), null, ref DiagnosticTrace.EmptyGuid, false, null); 
                        } 
                        DiagnosticTrace.calledShutdown = true;
                        DiagnosticTrace.TraceSource.Flush(); 
                    }
                }
                catch (OutOfMemoryException)
                { 
                    throw;
                } 
                catch (StackOverflowException) 
                {
                    throw; 
                }
                catch (ThreadAbortException)
                {
                    throw; 
                }
                catch (Exception exception) 
                { 
                    LogTraceFailure(null, exception);
                } 
            }
        }

        static void ExitOrUnloadEventHandler(object sender, EventArgs e) 
        {
            ShutdownTracing(); 
        } 

        static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) 
        {
            Exception e = (Exception)args.ExceptionObject;
            TraceEvent(TraceEventType.Critical, DiagnosticTraceCode.UnhandledException, SR.GetString(SR.UnhandledException), null, e, ref DiagnosticTrace.EmptyGuid, false, null);
            ShutdownTracing(); 
        }
 
        static XPathNavigator BuildTraceString(TraceEventType type, 
                                      string code,
                                      string description, 
                                      TraceRecord trace,
                                      Exception exception,
                                      object source)
        { 
            return DiagnosticTrace.BuildTraceString(new PlainXmlWriter(), type, code, description, trace, exception, source);
        } 
 
        static XPathNavigator BuildTraceString(PlainXmlWriter xml,
                                       TraceEventType type, 
                                       string code,
                                       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, code);
            xml.WriteElementString(DiagnosticStrings.DescriptionTag, description);
            xml.WriteElementString(DiagnosticStrings.AppDomain, DiagnosticTrace.AppDomainFriendlyName); 

            if (source != null) 
            { 
                xml.WriteElementString(DiagnosticStrings.SourceTag, DiagnosticTrace.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);
                DiagnosticTrace.AddExceptionToTraceString(xml, exception); 
                xml.WriteEndElement(); 
            }
 
            xml.WriteEndElement();

            return xml.ToNavigator();
        } 

        static void AddExceptionToTraceString(XmlWriter xml, Exception exception) 
        { 
            xml.WriteElementString(DiagnosticStrings.ExceptionTypeTag, DiagnosticTrace.XmlEncode(exception.GetType().AssemblyQualifiedName));
            xml.WriteElementString(DiagnosticStrings.MessageTag, DiagnosticTrace.XmlEncode(exception.Message)); 
            xml.WriteElementString(DiagnosticStrings.StackTraceTag, DiagnosticTrace.XmlEncode(DiagnosticTrace.StackTraceString(exception)));
            xml.WriteElementString(DiagnosticStrings.ExceptionStringTag, 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);
                    //Fix for Watson bug CSDMain 136718 - Add the null check incase the value is null. Only if both the key and value are non null, 
                    //write out the xml elements corresponding to them 
                    if(dataItem != null && exception.Data[dataItem] != null)
                    { 
                        xml.WriteElementString(DiagnosticStrings.KeyTag, DiagnosticTrace.XmlEncode(dataItem.ToString()));
                        xml.WriteElementString(DiagnosticStrings.ValueTag, DiagnosticTrace.XmlEncode(exception.Data[dataItem].ToString()));
                    }
                    xml.WriteEndElement(); 
                }
                xml.WriteEndElement(); 
            } 
            if (exception.InnerException != null)
            { 
                xml.WriteStartElement(DiagnosticStrings.InnerExceptionTag);
                DiagnosticTrace.AddExceptionToTraceString(xml, exception.InnerException);
                xml.WriteEndElement();
            } 
        }
 
        static 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(true); 
                System.Diagnostics.StackFrame[] stackFrames = stackTrace.GetFrames();
                int numFramesToSkip = 0; 
                foreach (System.Diagnostics.StackFrame stackFrame in stackFrames) 
                {
                    Type declaringType = stackFrame.GetMethod().DeclaringType; 
                    if (declaringType == typeof(DiagnosticTrace))
                    {
                        ++numFramesToSkip;
                    } 
                    else
                    { 
                        break; 
                    }
                } 
                stackTrace = new StackTrace(numFramesToSkip);
                retval = stackTrace.ToString();
            }
            return retval; 
        }
 
        //only used for exceptions, perf is not important 
        static internal string XmlEncode(string text)
        { 
            if (text == null)
            {
                return null;
            } 

            int len = text.Length; 
            StringBuilder encodedText = new StringBuilder(len + 8); //perf optimization, expecting no more than 2 > characters 

            for (int i = 0; i < len; ++i) 
            {
                char ch = text[i];
                switch (ch)
                { 
                    case '<':
                        encodedText.Append("<"); 
                        break; 
                    case '>':
                        encodedText.Append(">"); 
                        break;
                    case '&':
                        encodedText.Append("&");
                        break; 
                    default:
                        encodedText.Append(ch); 
                        break; 
                }
            } 
            return encodedText.ToString();
        }

        // 
        // Converts incompatible serverity enumeration TraceEvetType into EventLogEntryType
        // 
        static EventLogEntryType EventLogEntryTypeFromEventType(TraceEventType type) 
        {
            EventLogEntryType retval = EventLogEntryType.Information; 
            switch (type)
            {
                case TraceEventType.Critical:
                case TraceEventType.Error: 
                    retval = EventLogEntryType.Error;
                    break; 
                case TraceEventType.Warning: 
                    retval = EventLogEntryType.Warning;
                    break; 
            }
            return retval;
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK