public static void ReportUnhandledException(Exception ex) { // if the user hasn't opted in/out yet, ask them if (!ReportCrashes.HasValue) { var handler = ShouldEnableReporting; if (handler != null) { ReportCrashes = handler(); } } // If crash reporting has been explicitly disabled, disregard this crash if (ReportCrashes.HasValue && !ReportCrashes.Value) { return; } byte[] data; using (var stream = new MemoryStream()) { using (var writer = System.Xml.XmlWriter.Create(stream)) { writer.WriteStartElement("CrashLog"); writer.WriteAttributeString("version", ServiceVersion); writer.WriteElementString("SystemInformation", SystemInformation.ToText()); writer.WriteElementString("Exception", ex.ToString()); writer.WriteEndElement(); } data = stream.ToArray(); } // If crash reporting has not been enabled or disabled yet, just log to disk. // Otherwise log to disk only if uploading fails. var filename = string.Format("{0}.{1}.crashlog", SystemInformation.SessionUuid, Interlocked.Increment(ref CrashId)); if (!ReportCrashes.GetValueOrDefault() || !TryUploadReport(filename, data)) { if (!Directory.Exists(CrashLogDirectory)) { Directory.CreateDirectory(CrashLogDirectory); } File.WriteAllBytes(CrashLogDirectory.Combine(filename), data); } }
public static void ProcessCache() { int origValue = -1; try { // Ensure only 1 thread at a time attempts to upload cached reports origValue = Interlocked.CompareExchange(ref Processing, 1, 0); if (origValue != 0) { return; } // Uploading is not enabled, so bail out if (!ReportCrashes.GetValueOrDefault()) { return; } // Definitely no crash reports if this doesn't exist if (!Directory.Exists(CrashLogDirectory)) { return; } foreach (var file in Directory.GetFiles(CrashLogDirectory)) { if (TryUploadReport(file, File.ReadAllBytes(file))) { File.Delete(file); } } } catch (Exception ex) { LoggingService.LogError("Exception processing cached crashes", ex); } finally { if (origValue == 0) { Interlocked.CompareExchange(ref Processing, 0, 1); } } }