Standardize logging locations across desktop platforms (#6238)

* Standardize logging locations across desktop platforms

* Return null instead of empty literal on exceptions

* Remove LogDirectoryPath from LoggerModule

* Catch exception when creating DirectoryInfo in FileLogTarget

* Remove redundant log path vars, handle exception better, add null check

* Address styling issues

* Remove extra newline, quote file path in log, move directory check to OpenHelper

* Add GetOrCreateLogsDir to get/create log directory during runtime

* misc format changes

* Update src/Ryujinx.Common/Configuration/AppDataManager.cs

---------

Co-authored-by: jcm <butt@butts.com>
Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
Co-authored-by: Ac_K <Acoustik666@gmail.com>
This commit is contained in:
jcm 2024-02-10 19:17:19 -06:00 committed by GitHub
parent 95c4912d58
commit 84d6e8d121
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 156 additions and 50 deletions

View File

@ -1350,16 +1350,11 @@ namespace Ryujinx.Ava.UI.ViewModels
public void OpenLogsFolder()
{
string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
if (LoggerModule.LogDirectoryPath != null)
string logPath = AppDataManager.GetOrCreateLogsDir();
if (!string.IsNullOrEmpty(logPath))
{
logPath = LoggerModule.LogDirectoryPath;
OpenHelper.OpenFolder(logPath);
}
new DirectoryInfo(logPath).Create();
OpenHelper.OpenFolder(logPath);
}
public void ToggleDockMode()

View File

@ -30,6 +30,8 @@ namespace Ryujinx.Common.Configuration
public static string KeysDirPath { get; private set; }
public static string KeysDirPathUser { get; }
public static string LogsDirPath { get; private set; }
public const string DefaultNandDir = "bis";
public const string DefaultSdcardDir = "sdcard";
private const string DefaultModsDir = "mods";
@ -46,15 +48,7 @@ namespace Ryujinx.Common.Configuration
public static void Initialize(string baseDirPath)
{
string appDataPath;
if (OperatingSystem.IsMacOS())
{
appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Application Support");
}
else
{
appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
}
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
if (appDataPath.Length == 0)
{
@ -118,9 +112,126 @@ namespace Ryujinx.Common.Configuration
SetupBasePaths();
}
public static string GetOrCreateLogsDir()
{
if (Directory.Exists(LogsDirPath))
{
return LogsDirPath;
}
Logger.Notice.Print(LogClass.Application, "Logging directory not found; attempting to create new logging directory.");
LogsDirPath = SetUpLogsDir();
return LogsDirPath;
}
private static string SetUpLogsDir()
{
string logDir = "";
if (Mode == LaunchMode.Portable)
{
logDir = Path.Combine(BaseDirPath, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
return null;
}
}
else
{
if (OperatingSystem.IsMacOS())
{
// NOTE: Should evaluate to "~/Library/Logs/Ryujinx/".
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library", "Logs", DefaultBaseDir);
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
logDir = "";
}
if (string.IsNullOrEmpty(logDir))
{
// NOTE: Should evaluate to "~/Library/Application Support/Ryujinx/Logs".
logDir = Path.Combine(BaseDirPath, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
return null;
}
}
}
else if (OperatingSystem.IsWindows())
{
// NOTE: Should evaluate to a "Logs" directory in whatever directory Ryujinx was launched from.
logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
logDir = "";
}
if (string.IsNullOrEmpty(logDir))
{
// NOTE: Should evaluate to "C:\Users\user\AppData\Roaming\Ryujinx\Logs".
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
return null;
}
}
}
else if (OperatingSystem.IsLinux())
{
// NOTE: Should evaluate to "~/.config/Ryujinx/Logs".
logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), DefaultBaseDir, "Logs");
try
{
Directory.CreateDirectory(logDir);
}
catch
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory could not be created '{logDir}'");
return null;
}
}
}
return logDir;
}
private static void SetupBasePaths()
{
Directory.CreateDirectory(BaseDirPath);
LogsDirPath = SetUpLogsDir();
Directory.CreateDirectory(GamesDirPath = Path.Combine(BaseDirPath, GamesDir));
Directory.CreateDirectory(ProfilesDirPath = Path.Combine(BaseDirPath, ProfilesDir));
Directory.CreateDirectory(KeysDirPath = Path.Combine(BaseDirPath, KeysDir));

View File

@ -23,7 +23,18 @@ namespace Ryujinx.Common.Logging.Targets
public static FileStream PrepareLogFile(string path)
{
// Ensure directory is present
DirectoryInfo logDir = new(path);
DirectoryInfo logDir;
try
{
logDir = new DirectoryInfo(path);
}
catch (ArgumentException exception)
{
Logger.Warning?.Print(LogClass.Application, $"Logging directory path ('{path}') was invalid: {exception}");
return null;
}
try
{
logDir.Create();

View File

@ -427,16 +427,12 @@ namespace Ryujinx.Headless.SDL2
if (!option.DisableFileLog)
{
FileStream logFile = FileLogTarget.PrepareLogFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"));
string logDir = AppDataManager.LogsDirPath;
FileStream logFile = null;
if (logFile == null)
if (!string.IsNullOrEmpty(logDir))
{
logFile = FileLogTarget.PrepareLogFile(Path.Combine(AppDataManager.BaseDirPath, "Logs"));
if (logFile == null)
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable.");
}
logFile = FileLogTarget.PrepareLogFile(logDir);
}
if (logFile != null)
@ -447,6 +443,10 @@ namespace Ryujinx.Headless.SDL2
AsyncLogTargetOverflowAction.Block
));
}
else
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the Logs directory, Application Data, or the Ryujinx directory is writable.");
}
}
// Setup graphics configuration

View File

@ -9,8 +9,6 @@ namespace Ryujinx.Ui.Common.Configuration
{
public static class LoggerModule
{
public static string LogDirectoryPath { get; private set; }
public static void Initialize()
{
ConfigurationState.Instance.Logger.EnableDebug.Event += ReloadEnableDebug;
@ -84,26 +82,22 @@ namespace Ryujinx.Ui.Common.Configuration
{
if (e.NewValue)
{
string logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
FileStream logFile = FileLogTarget.PrepareLogFile(logDir);
string logDir = AppDataManager.LogsDirPath;
FileStream logFile = null;
if (!string.IsNullOrEmpty(logDir))
{
logFile = FileLogTarget.PrepareLogFile(logDir);
}
if (logFile == null)
{
logDir = Path.Combine(AppDataManager.BaseDirPath, "Logs");
logFile = FileLogTarget.PrepareLogFile(logDir);
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the Logs directory, Application Data, or the Ryujinx directory is writable.");
Logger.RemoveTarget("file");
if (logFile == null)
{
Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the application directory or the Ryujinx directory is writable.");
LogDirectoryPath = null;
Logger.RemoveTarget("file");
return;
}
return;
}
LogDirectoryPath = logDir;
Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget("file", logFile),
1000,

View File

@ -1376,16 +1376,11 @@ namespace Ryujinx.Ui
private void OpenLogsFolder_Pressed(object sender, EventArgs args)
{
string logPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
if (LoggerModule.LogDirectoryPath != null)
string logPath = AppDataManager.GetOrCreateLogsDir();
if (!string.IsNullOrEmpty(logPath))
{
logPath = LoggerModule.LogDirectoryPath;
OpenHelper.OpenFolder(logPath);
}
new DirectoryInfo(logPath).Create();
OpenHelper.OpenFolder(logPath);
}
private void Exit_Pressed(object sender, EventArgs args)