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:
mageven 2020-08-04 05:02:53 +05:30 committed by GitHub
parent 60db4c3530
commit a33dc2f491
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
120 changed files with 800 additions and 809 deletions

View file

@ -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();
}
}
}

View file

@ -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;

View file

@ -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}");
}

View file

@ -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
{

View file

@ -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
{

View file

@ -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();

View file

@ -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)
{