Implement OutputAccessLogToSdCard and expose an FS access log option (#700)
* Add OutputAccessLogToSdCard * Add config options for the FS access log
This commit is contained in:
parent
5c1bc52409
commit
350a3667f7
9 changed files with 136 additions and 20 deletions
|
@ -6,6 +6,8 @@ namespace Ryujinx.Common.Logging
|
|||
Stub,
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
Error,
|
||||
Guest,
|
||||
AccessLog
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,12 @@ namespace Ryujinx.Common.Logging
|
|||
m_EnabledLevels = new bool[Enum.GetNames(typeof(LogLevel)).Length];
|
||||
m_EnabledClasses = new bool[Enum.GetNames(typeof(LogClass)).Length];
|
||||
|
||||
m_EnabledLevels[(int)LogLevel.Stub] = true;
|
||||
m_EnabledLevels[(int)LogLevel.Info] = true;
|
||||
m_EnabledLevels[(int)LogLevel.Warning] = true;
|
||||
m_EnabledLevels[(int)LogLevel.Error] = true;
|
||||
m_EnabledLevels[(int)LogLevel.Stub] = true;
|
||||
m_EnabledLevels[(int)LogLevel.Info] = true;
|
||||
m_EnabledLevels[(int)LogLevel.Warning] = true;
|
||||
m_EnabledLevels[(int)LogLevel.Error] = true;
|
||||
m_EnabledLevels[(int)LogLevel.Guest] = true;
|
||||
m_EnabledLevels[(int)LogLevel.AccessLog] = true;
|
||||
|
||||
for (int index = 0; index < m_EnabledClasses.Length; index++)
|
||||
{
|
||||
|
@ -101,6 +103,16 @@ namespace Ryujinx.Common.Logging
|
|||
Print(LogLevel.Stub, logClass, GetFormattedMessage(logClass, "Stubbed. " + message, caller), obj);
|
||||
}
|
||||
|
||||
public static void PrintGuest(LogClass logClass, string message, [CallerMemberName] string caller = "")
|
||||
{
|
||||
Print(LogLevel.Guest, logClass, GetFormattedMessage(logClass, message, caller));
|
||||
}
|
||||
|
||||
public static void PrintAccessLog(LogClass logClass, string message)
|
||||
{
|
||||
Print(LogLevel.AccessLog, logClass, message);
|
||||
}
|
||||
|
||||
private static void Print(LogLevel logLevel, LogClass logClass, string message)
|
||||
{
|
||||
if (m_EnabledLevels[(int)logLevel] && m_EnabledClasses[(int)logClass])
|
||||
|
|
|
@ -105,6 +105,8 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
public IntegrityCheckLevel FsIntegrityCheckLevel { get; set; }
|
||||
|
||||
public int GlobalAccessLogMode { get; set; }
|
||||
|
||||
internal long HidBaseAddress { get; private set; }
|
||||
|
||||
public Horizon(Switch device)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using LibHac;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.NcaUtils;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using Ryujinx.HLE.Utilities;
|
||||
|
@ -32,7 +33,8 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
|
|||
{ 200, OpenDataStorageByCurrentProcess },
|
||||
{ 202, OpenDataStorageByDataId },
|
||||
{ 203, OpenPatchDataStorageByCurrentProcess },
|
||||
{ 1005, GetGlobalAccessLogMode }
|
||||
{ 1005, GetGlobalAccessLogMode },
|
||||
{ 1006, OutputAccessLogToSdCard }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -208,7 +210,20 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
|
|||
// GetGlobalAccessLogMode() -> u32 logMode
|
||||
public long GetGlobalAccessLogMode(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write(0);
|
||||
int mode = context.Device.System.GlobalAccessLogMode;
|
||||
|
||||
context.ResponseData.Write(mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OutputAccessLogToSdCard(buffer<bytes, 5> log_text)
|
||||
public long OutputAccessLogToSdCard(ServiceCtx context)
|
||||
{
|
||||
string message = ReadUtf8StringSend(context);
|
||||
|
||||
// FS ends each line with a newline. Remove it because Ryujinx logging adds its own newline
|
||||
Logger.PrintAccessLog(LogClass.ServiceFs, message.TrimEnd('\n'));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ namespace Ryujinx.HLE.HOS.Services.Lm
|
|||
|
||||
sb.AppendLine("Guest log:");
|
||||
|
||||
sb.AppendLine($" Log level: {(LmLogLevel)level}");
|
||||
|
||||
while (ms.Position < ms.Length)
|
||||
{
|
||||
byte type = reader.ReadByte();
|
||||
|
@ -86,14 +88,7 @@ namespace Ryujinx.HLE.HOS.Services.Lm
|
|||
|
||||
string text = sb.ToString();
|
||||
|
||||
switch((LmLogLevel)level)
|
||||
{
|
||||
case LmLogLevel.Trace: Logger.PrintDebug (LogClass.ServiceLm, text); break;
|
||||
case LmLogLevel.Info: Logger.PrintInfo (LogClass.ServiceLm, text); break;
|
||||
case LmLogLevel.Warning: Logger.PrintWarning(LogClass.ServiceLm, text); break;
|
||||
case LmLogLevel.Error: Logger.PrintError (LogClass.ServiceLm, text); break;
|
||||
case LmLogLevel.Critical: Logger.PrintError (LogClass.ServiceLm, text); break;
|
||||
}
|
||||
Logger.PrintGuest(LogClass.ServiceLm, text);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -72,5 +72,28 @@ namespace Ryujinx.HLE.Utilities
|
|||
return Encoding.UTF8.GetString(ms.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadUtf8StringSend(ServiceCtx context, int index = 0)
|
||||
{
|
||||
long position = context.Request.SendBuff[index].Position;
|
||||
long size = context.Request.SendBuff[index].Size;
|
||||
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
while (size-- > 0)
|
||||
{
|
||||
byte value = context.Memory.ReadByte(position++);
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ms.WriteByte(value);
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString(ms.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,12 @@
|
|||
// Enable print error logs
|
||||
"logging_enable_error": true,
|
||||
|
||||
// Enable printing guest logs
|
||||
"logging_enable_guest": true,
|
||||
|
||||
// Enable printing FS access logs. fs_global_access_log_mode must be 2 or 3
|
||||
"logging_enable_fs_access_log": false,
|
||||
|
||||
// Filtered log classes, in a JSON array, eg. `[ "Loader", "ServiceFs" ]`
|
||||
"logging_filtered_classes": [ ],
|
||||
|
||||
|
@ -44,6 +50,9 @@
|
|||
// Enable integrity checks on Switch content files
|
||||
"enable_fs_integrity_checks": true,
|
||||
|
||||
// Sets the "GlobalAccessLogMode". Possible modes are 0-3
|
||||
"fs_global_access_log_mode": 0,
|
||||
|
||||
// Enable or disable aggressive CPU optimizations
|
||||
"enable_aggressive_cpu_opts": true,
|
||||
|
||||
|
|
|
@ -52,6 +52,16 @@ namespace Ryujinx
|
|||
/// </summary>
|
||||
public bool LoggingEnableError { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables printing guest log messages
|
||||
/// </summary>
|
||||
public bool LoggingEnableGuest { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables printing FS access log messages
|
||||
/// </summary>
|
||||
public bool LoggingEnableFsAccessLog { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls which log messages are written to the log targets
|
||||
/// </summary>
|
||||
|
@ -92,6 +102,11 @@ namespace Ryujinx
|
|||
/// </summary>
|
||||
public bool EnableFsIntegrityChecks { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables FS access log output to the console. Possible modes are 0-3
|
||||
/// </summary>
|
||||
public int FsGlobalAccessLogMode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enable or Disable aggressive CPU optimizations
|
||||
/// </summary>
|
||||
|
@ -184,11 +199,13 @@ namespace Ryujinx
|
|||
));
|
||||
}
|
||||
|
||||
Logger.SetEnable(LogLevel.Debug, Instance.LoggingEnableDebug);
|
||||
Logger.SetEnable(LogLevel.Stub, Instance.LoggingEnableStub);
|
||||
Logger.SetEnable(LogLevel.Info, Instance.LoggingEnableInfo);
|
||||
Logger.SetEnable(LogLevel.Warning, Instance.LoggingEnableWarn);
|
||||
Logger.SetEnable(LogLevel.Error, Instance.LoggingEnableError);
|
||||
Logger.SetEnable(LogLevel.Debug, Instance.LoggingEnableDebug);
|
||||
Logger.SetEnable(LogLevel.Stub, Instance.LoggingEnableStub);
|
||||
Logger.SetEnable(LogLevel.Info, Instance.LoggingEnableInfo);
|
||||
Logger.SetEnable(LogLevel.Warning, Instance.LoggingEnableWarn);
|
||||
Logger.SetEnable(LogLevel.Error, Instance.LoggingEnableError);
|
||||
Logger.SetEnable(LogLevel.Guest, Instance.LoggingEnableGuest);
|
||||
Logger.SetEnable(LogLevel.AccessLog, Instance.LoggingEnableFsAccessLog);
|
||||
|
||||
if (Instance.LoggingFilteredClasses.Length > 0)
|
||||
{
|
||||
|
@ -220,6 +237,8 @@ namespace Ryujinx
|
|||
? IntegrityCheckLevel.ErrorOnInvalid
|
||||
: IntegrityCheckLevel.None;
|
||||
|
||||
device.System.GlobalAccessLogMode = Instance.FsGlobalAccessLogMode;
|
||||
|
||||
if (Instance.EnableAggressiveCpuOpts)
|
||||
{
|
||||
Optimizations.AssumeStrictAbiCompliance = true;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
"logging_enable_info",
|
||||
"logging_enable_warn",
|
||||
"logging_enable_error",
|
||||
"logging_enable_guest",
|
||||
"logging_enable_fs_access_log",
|
||||
"logging_filtered_classes",
|
||||
"enable_file_log",
|
||||
"system_language",
|
||||
|
@ -17,6 +19,7 @@
|
|||
"enable_vsync",
|
||||
"enable_multicore_scheduling",
|
||||
"enable_fs_integrity_checks",
|
||||
"fs_global_access_log_mode",
|
||||
"enable_aggressive_cpu_opts",
|
||||
"controller_type",
|
||||
"enable_keyboard",
|
||||
|
@ -265,6 +268,28 @@
|
|||
false
|
||||
]
|
||||
},
|
||||
"logging_enable_guest": {
|
||||
"$id": "#/properties/logging_enable_guest",
|
||||
"type": "boolean",
|
||||
"title": "Logging Enable Guest",
|
||||
"description": "Enables printing guest log messages",
|
||||
"default": true,
|
||||
"examples": [
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"logging_enable_fs_access": {
|
||||
"$id": "#/properties/logging_enable_fs_access_log",
|
||||
"type": "boolean",
|
||||
"title": "Logging Enable FS Access Log",
|
||||
"description": "Enables printing FS access log messages",
|
||||
"default": true,
|
||||
"examples": [
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"logging_filtered_classes": {
|
||||
"$id": "#/properties/logging_filtered_classes",
|
||||
"type": "array",
|
||||
|
@ -412,6 +437,20 @@
|
|||
false
|
||||
]
|
||||
},
|
||||
"fs_global_access_log_mode": {
|
||||
"$id": "#/properties/fs_global_access_log_mode",
|
||||
"type": "integer",
|
||||
"title": "Enable FS access log",
|
||||
"description": "Enables FS access log output. Possible modes are 0-3. Modes 2 and 3 output to the console.",
|
||||
"default": 0,
|
||||
"minimum": 0,
|
||||
"examples": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
},
|
||||
"enable_aggressive_cpu_opts": {
|
||||
"$id": "#/properties/enable_aggressive_cpu_opts",
|
||||
"type": "boolean",
|
||||
|
|
Reference in a new issue