Improved Logger (#1292)
* Logger class changes only Now compile-time checking is possible with the help of Nullable Value types. * Misc formatting * Manual optimizations PrintGuestLog PrintGuestStackTrace Surfaceflinger DequeueBuffer * Reduce SendVibrationXX log level to Debug * Add Notice log level This level is always enabled and used to print system info, etc... Also, rewrite LogColor to switch expression as colors are static * Unify unhandled exception event handlers * Print enabled LogLevels during init * Re-add App Exit disposes in proper order nit: switch case spacing * Revert PrintGuestStackTrace to Info logs due to #1407 PrintGuestStackTrace is now called in some critical error handlers so revert to old behavior as KThread isn't part of Guest. * Batch replace Logger statements
This commit is contained in:
parent
60db4c3530
commit
a33dc2f491
120 changed files with 800 additions and 809 deletions
|
@ -33,7 +33,10 @@ namespace Ryujinx
|
|||
string systemPath = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
|
||||
Environment.SetEnvironmentVariable("Path", $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin")};{systemPath}");
|
||||
|
||||
GLib.ExceptionManager.UnhandledException += Glib_UnhandledException;
|
||||
// Hook unhandled exception and process exit events
|
||||
GLib.ExceptionManager.UnhandledException += (GLib.UnhandledExceptionArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
|
||||
AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating);
|
||||
AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => ProgramExit();
|
||||
|
||||
// Initialize the configuration
|
||||
ConfigurationState.Initialize();
|
||||
|
@ -77,11 +80,7 @@ namespace Ryujinx
|
|||
ConfigurationState.Instance.ToFileFormat().SaveConfig(globalConfigurationPath);
|
||||
}
|
||||
|
||||
Logger.PrintInfo(LogClass.Application, $"Ryujinx Version: {Version}");
|
||||
|
||||
Logger.PrintInfo(LogClass.Application, $"Operating System: {SystemInfo.Instance.OsDescription}");
|
||||
Logger.PrintInfo(LogClass.Application, $"CPU: {SystemInfo.Instance.CpuName}");
|
||||
Logger.PrintInfo(LogClass.Application, $"Total RAM: {SystemInfo.Instance.RamSizeInMB}");
|
||||
PrintSystemInfo();
|
||||
|
||||
Profile.Initialize();
|
||||
|
||||
|
@ -105,22 +104,41 @@ namespace Ryujinx
|
|||
Application.Run();
|
||||
}
|
||||
|
||||
private static void Glib_UnhandledException(GLib.UnhandledExceptionArgs e)
|
||||
private static void PrintSystemInfo()
|
||||
{
|
||||
Exception exception = e.ExceptionObject as Exception;
|
||||
Logger.Notice.Print(LogClass.Application, $"Ryujinx Version: {Version}");
|
||||
|
||||
Logger.PrintError(LogClass.Application, $"Unhandled exception caught: {exception}");
|
||||
Logger.Notice.Print(LogClass.Application, $"Operating System: {SystemInfo.Instance.OsDescription}");
|
||||
Logger.Notice.Print(LogClass.Application, $"CPU: {SystemInfo.Instance.CpuName}");
|
||||
Logger.Notice.Print(LogClass.Application, $"Total RAM: {SystemInfo.Instance.RamSizeInMB}");
|
||||
|
||||
var enabledLogs = Logger.GetEnabledLevels();
|
||||
Logger.Notice.Print(LogClass.Application, $"Logs Enabled: {(enabledLogs.Count == 0 ? "<None>" : string.Join(", ", enabledLogs))}");
|
||||
}
|
||||
|
||||
private static void ProcessUnhandledException(Exception e, bool isTerminating)
|
||||
{
|
||||
Ptc.Close();
|
||||
PtcProfiler.Stop();
|
||||
|
||||
if (e.IsTerminating)
|
||||
{
|
||||
Logger.Shutdown();
|
||||
string message = $"Unhandled exception caught: {e}";
|
||||
|
||||
Ptc.Dispose();
|
||||
PtcProfiler.Dispose();
|
||||
Logger.Error?.PrintMsg(LogClass.Application, message);
|
||||
|
||||
if (Logger.Error == null) Logger.Notice.PrintMsg(LogClass.Application, message);
|
||||
|
||||
if (isTerminating)
|
||||
{
|
||||
ProgramExit();
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProgramExit()
|
||||
{
|
||||
Ptc.Dispose();
|
||||
PtcProfiler.Dispose();
|
||||
|
||||
Logger.Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"Failed to get access to directory: \"{dir}\"");
|
||||
Logger.Warning?.Print(LogClass.Application, $"Failed to get access to directory: \"{dir}\"");
|
||||
}
|
||||
|
||||
if (content.Length > 0)
|
||||
|
@ -70,7 +70,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"Failed to get access to directory: \"{dir}\"");
|
||||
Logger.Warning?.Print(LogClass.Application, $"Failed to get access to directory: \"{dir}\"");
|
||||
}
|
||||
|
||||
if (content.Length > 0)
|
||||
|
@ -103,7 +103,7 @@ namespace Ryujinx.Ui
|
|||
|
||||
if (!Directory.Exists(appDir))
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"The \"game_dirs\" section in \"Config.json\" contains an invalid directory: \"{appDir}\"");
|
||||
Logger.Warning?.Print(LogClass.Application, $"The \"game_dirs\" section in \"Config.json\" contains an invalid directory: \"{appDir}\"");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -265,18 +265,18 @@ namespace Ryujinx.Ui
|
|||
{
|
||||
applicationIcon = Path.GetExtension(applicationPath).ToLower() == ".xci" ? _xciIcon : _nspIcon;
|
||||
|
||||
Logger.PrintWarning(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}");
|
||||
Logger.Warning?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}");
|
||||
}
|
||||
catch (InvalidDataException)
|
||||
{
|
||||
applicationIcon = Path.GetExtension(applicationPath).ToLower() == ".xci" ? _xciIcon : _nspIcon;
|
||||
|
||||
Logger.PrintWarning(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {applicationPath}");
|
||||
Logger.Warning?.Print(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {applicationPath}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
|
||||
Logger.PrintDebug(LogClass.Application, exception.ToString());
|
||||
Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
|
||||
Logger.Debug?.Print(LogClass.Application, exception.ToString());
|
||||
|
||||
numApplicationsFound--;
|
||||
_loadingError = true;
|
||||
|
@ -330,7 +330,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
|
||||
Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
|
||||
|
||||
numApplicationsFound--;
|
||||
|
||||
|
@ -353,11 +353,11 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (InvalidDataException)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"The NCA header content type check has failed. This is usually because the header key is incorrect or missing. Errored File: {applicationPath}");
|
||||
Logger.Warning?.Print(LogClass.Application, $"The NCA header content type check has failed. This is usually because the header key is incorrect or missing. Errored File: {applicationPath}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
|
||||
Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
|
||||
|
||||
numApplicationsFound--;
|
||||
_loadingError = true;
|
||||
|
@ -378,7 +378,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (IOException exception)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, exception.Message);
|
||||
Logger.Warning?.Print(LogClass.Application, exception.Message);
|
||||
|
||||
numApplicationsFound--;
|
||||
_loadingError = true;
|
||||
|
@ -508,7 +508,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"Failed to parse metadata json for {titleId}. Loading defaults.");
|
||||
Logger.Warning?.Print(LogClass.Application, $"Failed to parse metadata json for {titleId}. Loading defaults.");
|
||||
|
||||
appMetadata = new ApplicationMetadata
|
||||
{
|
||||
|
@ -665,14 +665,14 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (InvalidDataException)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application,
|
||||
Logger.Warning?.Print(LogClass.Application,
|
||||
$"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {updatePath}");
|
||||
|
||||
break;
|
||||
}
|
||||
catch (MissingKeyException exception)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application,
|
||||
Logger.Warning?.Print(LogClass.Application,
|
||||
$"Your key set is missing a key with the name: {exception.Name}. Errored File: {updatePath}");
|
||||
|
||||
break;
|
||||
|
|
|
@ -105,13 +105,13 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (InvalidDataException exception)
|
||||
{
|
||||
Logger.PrintError(LogClass.Application, $"{exception.Message}. Errored File: {containerPath}");
|
||||
Logger.Error?.Print(LogClass.Application, $"{exception.Message}. Errored File: {containerPath}");
|
||||
|
||||
GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add DLC Failed!", "The NCA header content type check has failed. This is usually because the header key is incorrect or missing.");
|
||||
}
|
||||
catch (MissingKeyException exception)
|
||||
{
|
||||
Logger.PrintError(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {containerPath}");
|
||||
Logger.Error?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {containerPath}");
|
||||
|
||||
GtkDialog.CreateInfoDialog("Ryujinx - Error", "Add DLC Failed!", $"Your key set is missing a key with the name: {exception.Name}");
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ namespace Ryujinx.Ui
|
|||
control.UserAccountSaveDataSize = 0x4000;
|
||||
control.UserAccountSaveDataJournalSize = 0x4000;
|
||||
|
||||
Logger.PrintWarning(LogClass.Application,
|
||||
Logger.Warning?.Print(LogClass.Application,
|
||||
"No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ namespace Ryujinx.Ui
|
|||
|
||||
if (mainNca == null)
|
||||
{
|
||||
Logger.PrintError(LogClass.Application, "Extraction failed. The main NCA was not present in the selected file.");
|
||||
Logger.Error?.Print(LogClass.Application, "Extraction failed. The main NCA was not present in the selected file.");
|
||||
|
||||
Gtk.Application.Invoke(delegate
|
||||
{
|
||||
|
@ -389,7 +389,7 @@ namespace Ryujinx.Ui
|
|||
{
|
||||
if (resultCode.Value.IsFailure())
|
||||
{
|
||||
Logger.PrintError(LogClass.Application, $"LibHac returned error code: {resultCode.Value.ErrorCode}");
|
||||
Logger.Error?.Print(LogClass.Application, $"LibHac returned error code: {resultCode.Value.ErrorCode}");
|
||||
|
||||
Gtk.Application.Invoke(delegate
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace Ryujinx.Ui
|
|||
catch (Exception e)
|
||||
{
|
||||
error = true;
|
||||
Logger.PrintError(LogClass.Application, $"Error displaying Software Keyboard: {e}");
|
||||
Logger.Error?.Print(LogClass.Application, $"Error displaying Software Keyboard: {e}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -249,7 +249,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
else
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"The \"custom_theme_path\" section in \"Config.json\" contains an invalid path: \"{ConfigurationState.Instance.Ui.CustomThemePath}\".");
|
||||
Logger.Warning?.Print(LogClass.Application, $"The \"custom_theme_path\" section in \"Config.json\" contains an invalid path: \"{ConfigurationState.Instance.Ui.CustomThemePath}\".");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,7 +405,7 @@ namespace Ryujinx.Ui
|
|||
|
||||
UpdateGraphicsConfig();
|
||||
|
||||
Logger.PrintInfo(LogClass.Application, $"Using Firmware Version: {_contentManager.GetCurrentFirmwareVersion()?.VersionString}");
|
||||
Logger.Notice.Print(LogClass.Application, $"Using Firmware Version: {_contentManager.GetCurrentFirmwareVersion()?.VersionString}");
|
||||
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
|
@ -418,12 +418,12 @@ namespace Ryujinx.Ui
|
|||
|
||||
if (romFsFiles.Length > 0)
|
||||
{
|
||||
Logger.PrintInfo(LogClass.Application, "Loading as cart with RomFS.");
|
||||
Logger.Info?.Print(LogClass.Application, "Loading as cart with RomFS.");
|
||||
device.LoadCart(path, romFsFiles[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.PrintInfo(LogClass.Application, "Loading as cart WITHOUT RomFS.");
|
||||
Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS.");
|
||||
device.LoadCart(path);
|
||||
}
|
||||
}
|
||||
|
@ -432,34 +432,34 @@ namespace Ryujinx.Ui
|
|||
switch (System.IO.Path.GetExtension(path).ToLowerInvariant())
|
||||
{
|
||||
case ".xci":
|
||||
Logger.PrintInfo(LogClass.Application, "Loading as XCI.");
|
||||
Logger.Info?.Print(LogClass.Application, "Loading as XCI.");
|
||||
device.LoadXci(path);
|
||||
break;
|
||||
case ".nca":
|
||||
Logger.PrintInfo(LogClass.Application, "Loading as NCA.");
|
||||
Logger.Info?.Print(LogClass.Application, "Loading as NCA.");
|
||||
device.LoadNca(path);
|
||||
break;
|
||||
case ".nsp":
|
||||
case ".pfs0":
|
||||
Logger.PrintInfo(LogClass.Application, "Loading as NSP.");
|
||||
Logger.Info?.Print(LogClass.Application, "Loading as NSP.");
|
||||
device.LoadNsp(path);
|
||||
break;
|
||||
default:
|
||||
Logger.PrintInfo(LogClass.Application, "Loading as homebrew.");
|
||||
Logger.Info?.Print(LogClass.Application, "Loading as homebrew.");
|
||||
try
|
||||
{
|
||||
device.LoadProgram(path);
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
Logger.PrintError(LogClass.Application, "The file which you have specified is unsupported by Ryujinx.");
|
||||
Logger.Error?.Print(LogClass.Application, "The file which you have specified is unsupported by Ryujinx.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, "Please specify a valid XCI/NCA/NSP/PFS0/NRO file.");
|
||||
Logger.Warning?.Print(LogClass.Application, "Please specify a valid XCI/NCA/NSP/PFS0/NRO file.");
|
||||
device.Dispose();
|
||||
|
||||
return;
|
||||
|
@ -668,11 +668,12 @@ namespace Ryujinx.Ui
|
|||
|
||||
Profile.FinishProfiling();
|
||||
DiscordIntegrationModule.Exit();
|
||||
Logger.Shutdown();
|
||||
|
||||
Ptc.Dispose();
|
||||
PtcProfiler.Dispose();
|
||||
|
||||
Logger.Shutdown();
|
||||
|
||||
Application.Quit();
|
||||
}
|
||||
|
||||
|
@ -691,7 +692,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
else
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Audio, "SoundIO is not supported, falling back to dummy audio out.");
|
||||
Logger.Warning?.Print(LogClass.Audio, "SoundIO is not supported, falling back to dummy audio out.");
|
||||
}
|
||||
}
|
||||
else if (ConfigurationState.Instance.System.AudioBackend.Value == AudioBackend.OpenAl)
|
||||
|
@ -702,11 +703,11 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
else
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Audio, "OpenAL is not supported, trying to fall back to SoundIO.");
|
||||
Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, trying to fall back to SoundIO.");
|
||||
|
||||
if (SoundIoAudioOut.IsSupported)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Audio, "Found SoundIO, changing configuration.");
|
||||
Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration.");
|
||||
|
||||
ConfigurationState.Instance.System.AudioBackend.Value = AudioBackend.SoundIo;
|
||||
SaveConfig();
|
||||
|
@ -715,7 +716,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
else
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Audio, "SoundIO is not supported, falling back to dummy audio out.");
|
||||
Logger.Warning?.Print(LogClass.Audio, "SoundIO is not supported, falling back to dummy audio out.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -956,7 +957,7 @@ namespace Ryujinx.Ui
|
|||
|
||||
dialog.SecondaryText = $"A valid system firmware was not found in {filename}.";
|
||||
|
||||
Logger.PrintError(LogClass.Application, $"A valid system firmware was not found in {filename}.");
|
||||
Logger.Error?.Print(LogClass.Application, $"A valid system firmware was not found in {filename}.");
|
||||
|
||||
dialog.Run();
|
||||
dialog.Hide();
|
||||
|
@ -993,7 +994,7 @@ namespace Ryujinx.Ui
|
|||
|
||||
if (response == (int)ResponseType.Yes)
|
||||
{
|
||||
Logger.PrintInfo(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}");
|
||||
Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}");
|
||||
|
||||
Thread thread = new Thread(() =>
|
||||
{
|
||||
|
@ -1017,7 +1018,7 @@ namespace Ryujinx.Ui
|
|||
|
||||
dialog.SecondaryText = $"System version {firmwareVersion.VersionString} successfully installed.";
|
||||
|
||||
Logger.PrintInfo(LogClass.Application, $"System version {firmwareVersion.VersionString} successfully installed.");
|
||||
Logger.Info?.Print(LogClass.Application, $"System version {firmwareVersion.VersionString} successfully installed.");
|
||||
|
||||
dialog.Run();
|
||||
dialog.Dispose();
|
||||
|
@ -1038,7 +1039,7 @@ namespace Ryujinx.Ui
|
|||
dialog.SecondaryText = $"An error occured while installing system version {firmwareVersion.VersionString}." +
|
||||
" Please check logs for more info.";
|
||||
|
||||
Logger.PrintError(LogClass.Application, ex.Message);
|
||||
Logger.Error?.Print(LogClass.Application, ex.Message);
|
||||
|
||||
dialog.Run();
|
||||
dialog.Dispose();
|
||||
|
@ -1073,7 +1074,7 @@ namespace Ryujinx.Ui
|
|||
|
||||
dialog.SecondaryText = "An error occured while parsing firmware. Please check the logs for more info.";
|
||||
|
||||
Logger.PrintError(LogClass.Application, ex.Message);
|
||||
Logger.Error?.Print(LogClass.Application, ex.Message);
|
||||
|
||||
dialog.Run();
|
||||
dialog.Dispose();
|
||||
|
|
|
@ -120,7 +120,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (InvalidDataException exception)
|
||||
{
|
||||
Logger.PrintError(LogClass.Application, $"{exception.Message}. Errored File: {path}");
|
||||
Logger.Error?.Print(LogClass.Application, $"{exception.Message}. Errored File: {path}");
|
||||
|
||||
if (showErrorDialog)
|
||||
{
|
||||
|
@ -131,7 +131,7 @@ namespace Ryujinx.Ui
|
|||
}
|
||||
catch (MissingKeyException exception)
|
||||
{
|
||||
Logger.PrintError(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {path}");
|
||||
Logger.Error?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}. Errored File: {path}");
|
||||
|
||||
if (showErrorDialog)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue