Пример #1
0
        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (!Loggers.IsUsed(this))
            {
                return;
            }

            //Can be safely cast to Exception if RuntimeCompatibilityAttribute(WrapNonException=true) has been applied to your assembly,
            //which is automatically done for you since .net 2.0. 'Non exceptions' will be wrapped in RuntimeWrappedException.
            var    ex         = e.ExceptionObject as Exception;
            var    frame      = GetApplicableFrame(ex);
            string sourceFile = frame.GetFileName();

            string description = "An unhandled exception occured and killed the application!";

            if (sourceFile == null)
            {
                description += " SourceFile and Line are not available because the application does not have (up-to-date) .pdb files included in the folder holding the binaries where the exception occured.";
            }

            //Do not notify in write exceptions, they will not be handled anyways.
            LogWriteException = null;
            //_backgroundWorkQueue is not used because its background thread gets disposed if the application halts. However, we dispose it first so there is absolutely no chance that LogEntryWriteCallback is called by 2 threads at the same time.
            _backgroundWorkQueue.Dispose();

            //Create a readable watson buckets. (_watsonBuckets holds a byte array.)
            //Watson buckets are somewhat handy for when there is no stacktrace available, or you cannot trace into third-party assemblies.
            //Only applicable with unhandled exceptions.
            //I did not simply replace the value for _watsonBuckets in the exception, because the Windows Error Report tool would not work:
            //You can get the path to the minidump there. The minidump can be analyzed using a tool like WinDbg.
            //Downside: The output contains a serialized byte array.
            //http://msdn.microsoft.com/en-us/library/ms404466(v=VS.110).aspx
            //http://mrpfister.com/programming/demystifying-clr20r3-error-messages/
            //http://mrpfister.com/programming/opcodes-msil-and-reflecting-net-code/
            ReadableWatsonBucketParameters readableWatsonBucketParameters = null;
            FieldInfo watsonBucketsField = ex.GetType().GetField("_watsonBuckets", BindingFlags.Instance | BindingFlags.NonPublic);

            if (watsonBucketsField != null)
            {
                byte[] arr = watsonBucketsField.GetValue(ex) as byte[];
                if (arr != null)
                {
                    var str = MarshalBytesToStruct <BucketParameters>(arr);
                    readableWatsonBucketParameters = new ReadableWatsonBucketParameters(str);
                }
            }

            LogEntryWriteCallback(Level.Fatal, description, ex, new object[] { sender }, frame.GetMethod().Name, sourceFile, frame.GetFileLineNumber(), LogToDebug, readableWatsonBucketParameters);
        }
Пример #2
0
        private void LogEntryWriteCallback(Level level, string description, Exception exception, object[] parameters, string member, string sourceFile, int line, bool logToDebug, ReadableWatsonBucketParameters readableWatsonBucketParameters)
        {
            if (level < CurrentLevel)
            {
                return;
            }

            //We are working around the problem that stuff closely linked to the gui /unknown stuff in another program cannot be serialized or deserialized.
            string[] parameterStrings = null;
            if (parameters != null)
            {
                parameterStrings = new string[parameters.Length];
                for (int i = 0; i != parameters.Length; i++)
                {
                    object parameter = parameters[i];
                    if (parameter != null)
                    {
                        parameterStrings[i] = parameter.ToString();
                    }
                }
            }

            var entry = new Entry {
                Timestamp = DateTimeOffset.Now.ToString("o"), Level = level, Description = description, Exception = exception, ReadableWatsonBucketParameters = readableWatsonBucketParameters, Parameters = parameterStrings, Member = member, SourceFile = sourceFile, Line = line
            };
            string json = JsonConvert.SerializeObject(entry, Formatting.None, _jsonSerializerSettings);

            if (logToDebug)
            {
                Debug.WriteLine(json, "LOGGER");
            }

            InvokeWriteLogEntry(entry, json); // Also handles write exceptions and invokes LogEntryWritten.
        }