From c81abdde4c48c607669580ef769776623b86dcc7 Mon Sep 17 00:00:00 2001 From: emmauss Date: Thu, 31 Jan 2019 04:49:15 +0200 Subject: [PATCH] Add file logging and handle unhandled exceptions (#558) * add unhandled exception handler * added file logging * add option in config * consolidated console and file log --- Ryujinx.Common/Logging/LogClass.cs | 1 + Ryujinx.Common/Logging/Logger.cs | 2 ++ Ryujinx/Config.cs | 3 +- Ryujinx/Program.cs | 22 ++++++++++++- Ryujinx/Ryujinx.conf | 3 ++ Ryujinx/Ui/{ConsoleLog.cs => Log.cs} | 47 +++++++++++++++++++++++----- 6 files changed, 69 insertions(+), 9 deletions(-) rename Ryujinx/Ui/{ConsoleLog.cs => Log.cs} (73%) diff --git a/Ryujinx.Common/Logging/LogClass.cs b/Ryujinx.Common/Logging/LogClass.cs index 8739fbc67..f20347b6b 100644 --- a/Ryujinx.Common/Logging/LogClass.cs +++ b/Ryujinx.Common/Logging/LogClass.cs @@ -5,6 +5,7 @@ namespace Ryujinx.Common.Logging Audio, Cpu, Font, + Emulation, Gpu, Hid, Kernel, diff --git a/Ryujinx.Common/Logging/Logger.cs b/Ryujinx.Common/Logging/Logger.cs index 5e58f8064..35ca416bc 100644 --- a/Ryujinx.Common/Logging/Logger.cs +++ b/Ryujinx.Common/Logging/Logger.cs @@ -16,6 +16,8 @@ namespace Ryujinx.Common.Logging public static event EventHandler Updated; + public static bool EnableFileLog { get; set; } + static Logger() { m_EnabledLevels = new bool[Enum.GetNames(typeof(LogLevel)).Length]; diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs index d1139da92..a1d8cddf4 100644 --- a/Ryujinx/Config.cs +++ b/Ryujinx/Config.cs @@ -62,6 +62,8 @@ namespace Ryujinx } } + Logger.EnableFileLog = Convert.ToBoolean(parser.Value("Enable_File_Log")); + SystemLanguage SetLanguage = Enum.Parse(parser.Value("System_Language")); device.System.State.SetLanguage(SetLanguage); @@ -118,7 +120,6 @@ namespace Ryujinx }); NpadController = new NpadController( - Convert.ToBoolean(parser.Value("GamePad_Enable")), Convert.ToInt32 (parser.Value("GamePad_Index")), (float)Convert.ToDouble (parser.Value("GamePad_Deadzone"), CultureInfo.InvariantCulture), diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs index 4dce13c7f..335aa0ea8 100644 --- a/Ryujinx/Program.cs +++ b/Ryujinx/Program.cs @@ -22,7 +22,10 @@ namespace Ryujinx Config.Read(device); - Logger.Updated += ConsoleLog.Log; + Logger.Updated += Log.LogMessage; + + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; if (args.Length == 1) { @@ -87,6 +90,23 @@ namespace Ryujinx audioOut.Dispose(); } + private static void CurrentDomain_ProcessExit(object sender, EventArgs e) + { + Log.Close(); + } + + private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + var exception = e.ExceptionObject as Exception; + + Logger.PrintError(LogClass.Emulation, $"Unhandled exception caught: {exception}"); + + if (e.IsTerminating) + { + Log.Close(); + } + } + /// /// Picks an audio output renderer supported on this machine /// diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf index c04d7b5ac..6edcb8e67 100644 --- a/Ryujinx/Ryujinx.conf +++ b/Ryujinx/Ryujinx.conf @@ -22,6 +22,9 @@ Logging_Enable_Error = true #Filtered log classes, seperated by ", ", eg. `Logging_Filtered_Classes = Loader, ServiceFS` Logging_Filtered_Classes = +#Enable file logging +Enable_File_Log = true + #System Language list: https://gist.github.com/HorrorTroll/b6e4a88d774c3c9b3bdf54d79a7ca43b #Change System Language System_Language = AmericanEnglish diff --git a/Ryujinx/Ui/ConsoleLog.cs b/Ryujinx/Ui/Log.cs similarity index 73% rename from Ryujinx/Ui/ConsoleLog.cs rename to Ryujinx/Ui/Log.cs index ac3d41c9e..5daae1402 100644 --- a/Ryujinx/Ui/ConsoleLog.cs +++ b/Ryujinx/Ui/Log.cs @@ -1,22 +1,27 @@ -using Ryujinx.Common.Logging; +using Ryujinx.Common.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Reflection; using System.Text; using System.Threading; namespace Ryujinx { - static class ConsoleLog + static class Log { + private static readonly string _path; + + private static StreamWriter _logWriter; + private static Thread _messageThread; private static BlockingCollection _messageQueue; private static Dictionary _logColors; - static ConsoleLog() + static Log() { _logColors = new Dictionary() { @@ -47,6 +52,13 @@ namespace Ryujinx } }); + _path = Path.Combine(Environment.CurrentDirectory, "Ryujinx.log"); + + if (Logger.EnableFileLog) + { + _logWriter = new StreamWriter(File.Open(_path,FileMode.Create, FileAccess.Write)); + } + _messageThread.IsBackground = true; _messageThread.Start(); } @@ -82,26 +94,47 @@ namespace Ryujinx } } + string message = sb.ToString(); + if (_logColors.TryGetValue(e.Level, out ConsoleColor color)) { Console.ForegroundColor = color; - Console.WriteLine(sb.ToString()); + Console.WriteLine(message); Console.ResetColor(); } else { - Console.WriteLine(sb.ToString()); + Console.WriteLine(message); + } + + if (Logger.EnableFileLog) + { + _logWriter.WriteLine(message); } } - public static void Log(object sender, LogEventArgs e) + public static void LogMessage(object sender, LogEventArgs e) { if (!_messageQueue.IsAddingCompleted) { _messageQueue.Add(e); } } + + public static void Close() + { + _messageQueue.CompleteAdding(); + + _messageThread.Join(); + + if (Logger.EnableFileLog) + { + _logWriter.Flush(); + _logWriter.Close(); + _logWriter.Dispose(); + } + } } -} \ No newline at end of file +}