From e699be0118d07cad05033c152e8b886f8e8d1ecb Mon Sep 17 00:00:00 2001 From: DrChat Date: Fri, 24 Mar 2017 16:28:41 -0500 Subject: [PATCH] Logging: Add a flag to specify the minimum log level --log_level = (0=error, 1=warning, 2=info, 3=debug) --- src/xenia/apu/xma_decoder.cc | 8 +++- src/xenia/base/logging.cc | 52 +++++++++++++++--------- src/xenia/base/logging.h | 48 +++++++++++++++------- src/xenia/cpu/backend/x64/x64_tracers.cc | 10 +++-- src/xenia/kernel/user_module.cc | 2 +- src/xenia/kernel/util/shim_utils.h | 6 ++- 6 files changed, 85 insertions(+), 41 deletions(-) diff --git a/src/xenia/apu/xma_decoder.cc b/src/xenia/apu/xma_decoder.cc index 8994ac8cb..8bc0e8607 100644 --- a/src/xenia/apu/xma_decoder.cc +++ b/src/xenia/apu/xma_decoder.cc @@ -65,27 +65,33 @@ void av_log_callback(void* avcl, int level, const char* fmt, va_list va) { } char level_char = '?'; + LogLevel log_level; switch (level) { case AV_LOG_ERROR: level_char = '!'; + log_level = xe::LogLevel::LOG_LEVEL_ERROR; break; case AV_LOG_WARNING: level_char = 'w'; + log_level = xe::LogLevel::LOG_LEVEL_WARNING; break; case AV_LOG_INFO: level_char = 'i'; + log_level = xe::LogLevel::LOG_LEVEL_INFO; break; case AV_LOG_VERBOSE: level_char = 'v'; + log_level = xe::LogLevel::LOG_LEVEL_DEBUG; break; case AV_LOG_DEBUG: level_char = 'd'; + log_level = xe::LogLevel::LOG_LEVEL_DEBUG; break; } StringBuffer buff; buff.AppendVarargs(fmt, va); - xe::LogLineFormat(level_char, "libav: %s", buff.GetString()); + xe::LogLineFormat(log_level, level_char, "libav: %s", buff.GetString()); } X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) { diff --git a/src/xenia/base/logging.cc b/src/xenia/base/logging.cc index 451514e8e..641a97e9d 100644 --- a/src/xenia/base/logging.cc +++ b/src/xenia/base/logging.cc @@ -38,6 +38,9 @@ DEFINE_string( "Logs are written to the given file (specify stdout for command line)"); DEFINE_bool(log_debugprint, false, "Dump the log to DebugPrint."); DEFINE_bool(flush_log, true, "Flush log file after each log line batch."); +DEFINE_int32( + log_level, 2, + "Maximum level to be logged. (0=error, 1=warning, 2=info, 3=debug)"); namespace xe { @@ -71,12 +74,17 @@ class Logger { fclose(file_); } - void AppendLine(uint32_t thread_id, const char level_char, const char* buffer, - size_t buffer_length) { + void AppendLine(uint32_t thread_id, LogLevel level, const char prefix_char, + const char* buffer, size_t buffer_length) { + if (static_cast(level) > FLAGS_log_level) { + // Discard this line. + return; + } + LogLine line; line.buffer_length = buffer_length; line.thread_id = thread_id; - line.level_char = level_char; + line.prefix_char = prefix_char; // First, run a check and see if we can increment write // head without any problems. If so, cmpxchg it to reserve some space in the @@ -125,7 +133,9 @@ class Logger { struct LogLine { size_t buffer_length; uint32_t thread_id; - char level_char; + uint16_t _pad_0; // (2b) padding + uint8_t _pad_1; // (1b) padding + char prefix_char; }; void Write(const char* buf, size_t size) { @@ -151,7 +161,7 @@ class Logger { LogLine line; rb.Read(&line, sizeof(line)); char prefix[] = { - line.level_char, + line.prefix_char, '>', ' ', '0', // Thread ID gets placed here (8 chars). @@ -228,22 +238,24 @@ void InitializeLogging(const std::wstring& app_name) { logger_ = new (mem) Logger(app_name); } -void LogLineFormat(const char level_char, const char* fmt, ...) { +void LogLineFormat(LogLevel log_level, const char prefix_char, const char* fmt, + ...) { va_list args; va_start(args, fmt); int chars_written = vsnprintf(log_format_buffer_.data(), log_format_buffer_.capacity(), fmt, args); va_end(args); if (chars_written >= 0 && chars_written < log_format_buffer_.capacity()) { - logger_->AppendLine(xe::threading::current_thread_id(), level_char, - log_format_buffer_.data(), chars_written); + logger_->AppendLine(xe::threading::current_thread_id(), log_level, + prefix_char, log_format_buffer_.data(), chars_written); } else if (chars_written >= 0) { - logger_->AppendLine(xe::threading::current_thread_id(), level_char, fmt, - std::strlen(fmt)); + logger_->AppendLine(xe::threading::current_thread_id(), log_level, + prefix_char, fmt, std::strlen(fmt)); } } -void LogLineVarargs(const char level_char, const char* fmt, va_list args) { +void LogLineVarargs(LogLevel log_level, const char prefix_char, const char* fmt, + va_list args) { int chars_written = vsnprintf(log_format_buffer_.data(), log_format_buffer_.capacity(), fmt, args); if (chars_written < 0) { @@ -252,25 +264,27 @@ void LogLineVarargs(const char level_char, const char* fmt, va_list args) { auto size = std::min(size_t(chars_written), log_format_buffer_.capacity() - 1); - logger_->AppendLine(xe::threading::current_thread_id(), level_char, - log_format_buffer_.data(), size); + logger_->AppendLine(xe::threading::current_thread_id(), log_level, + prefix_char, log_format_buffer_.data(), size); } -void LogLine(const char level_char, const char* str, size_t str_length) { +void LogLine(LogLevel log_level, const char prefix_char, const char* str, + size_t str_length) { logger_->AppendLine( - xe::threading::current_thread_id(), level_char, str, + xe::threading::current_thread_id(), log_level, prefix_char, str, str_length == std::string::npos ? std::strlen(str) : str_length); } -void LogLine(const char level_char, const std::string& str) { - logger_->AppendLine(xe::threading::current_thread_id(), level_char, - str.c_str(), str.length()); +void LogLine(LogLevel log_level, const char prefix_char, + const std::string& str) { + logger_->AppendLine(xe::threading::current_thread_id(), log_level, + prefix_char, str.c_str(), str.length()); } void FatalError(const char* fmt, ...) { va_list args; va_start(args, fmt); - LogLineVarargs('X', fmt, args); + LogLineVarargs(LogLevel::LOG_LEVEL_ERROR, 'X', fmt, args); va_end(args); #if XE_PLATFORM_WIN32 diff --git a/src/xenia/base/logging.h b/src/xenia/base/logging.h index 9a846eca7..07ac086e9 100644 --- a/src/xenia/base/logging.h +++ b/src/xenia/base/logging.h @@ -19,17 +19,27 @@ namespace xe { #define XE_OPTION_ENABLE_LOGGING 1 +enum class LogLevel { + LOG_LEVEL_ERROR, + LOG_LEVEL_WARNING, + LOG_LEVEL_INFO, + LOG_LEVEL_DEBUG, +}; + // Initializes the logging system and any outputs requested. // Must be called on startup. void InitializeLogging(const std::wstring& app_name); // Appends a line to the log with printf-style formatting. -void LogLineFormat(const char level_char, const char* fmt, ...); -void LogLineVarargs(const char level_char, const char* fmt, va_list args); +void LogLineFormat(LogLevel log_level, const char prefix_char, const char* fmt, + ...); +void LogLineVarargs(LogLevel log_level, const char prefix_char, const char* fmt, + va_list args); // Appends a line to the log. -void LogLine(const char level_char, const char* str, +void LogLine(LogLevel log_level, const char prefix_char, const char* str, size_t str_length = std::string::npos); -void LogLine(const char level_char, const std::string& str); +void LogLine(LogLevel log_level, const char prefix_char, + const std::string& str); // Logs a fatal error with printf-style formatting and aborts the program. void FatalError(const char* fmt, ...); @@ -37,23 +47,33 @@ void FatalError(const char* fmt, ...); void FatalError(const std::string& str); #if XE_OPTION_ENABLE_LOGGING -#define XELOGCORE(level, fmt, ...) xe::LogLineFormat(level, fmt, ##__VA_ARGS__) +#define XELOGCORE(level, prefix, fmt, ...) \ + xe::LogLineFormat(level, prefix, fmt, ##__VA_ARGS__) #else #define XELOGCORE(level, fmt, ...) \ do { \ } while (false) #endif // ENABLE_LOGGING -#define XELOGE(fmt, ...) XELOGCORE('!', fmt, ##__VA_ARGS__) -#define XELOGW(fmt, ...) XELOGCORE('w', fmt, ##__VA_ARGS__) -#define XELOGI(fmt, ...) XELOGCORE('i', fmt, ##__VA_ARGS__) -#define XELOGD(fmt, ...) XELOGCORE('d', fmt, ##__VA_ARGS__) +#define XELOGE(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_ERROR, '!', fmt, ##__VA_ARGS__) +#define XELOGW(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_WARNING, 'w', fmt, ##__VA_ARGS__) +#define XELOGI(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'i', fmt, ##__VA_ARGS__) +#define XELOGD(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_DEBUG, 'd', fmt, ##__VA_ARGS__) -#define XELOGCPU(fmt, ...) XELOGCORE('C', fmt, ##__VA_ARGS__) -#define XELOGAPU(fmt, ...) XELOGCORE('A', fmt, ##__VA_ARGS__) -#define XELOGGPU(fmt, ...) XELOGCORE('G', fmt, ##__VA_ARGS__) -#define XELOGKERNEL(fmt, ...) XELOGCORE('K', fmt, ##__VA_ARGS__) -#define XELOGFS(fmt, ...) XELOGCORE('F', fmt, ##__VA_ARGS__) +#define XELOGCPU(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'C', fmt, ##__VA_ARGS__) +#define XELOGAPU(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'A', fmt, ##__VA_ARGS__) +#define XELOGGPU(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'G', fmt, ##__VA_ARGS__) +#define XELOGKERNEL(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'K', fmt, ##__VA_ARGS__) +#define XELOGFS(fmt, ...) \ + XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'F', fmt, ##__VA_ARGS__) } // namespace xe diff --git a/src/xenia/cpu/backend/x64/x64_tracers.cc b/src/xenia/cpu/backend/x64/x64_tracers.cc index ad3de8285..1b30aa16f 100644 --- a/src/xenia/cpu/backend/x64/x64_tracers.cc +++ b/src/xenia/cpu/backend/x64/x64_tracers.cc @@ -32,11 +32,13 @@ bool trace_enabled = true; #define THREAD_MATCH \ (!TARGET_THREAD || thread_state->thread_id() == TARGET_THREAD) #define IFLUSH() -#define IPRINT(s) \ - if (trace_enabled && THREAD_MATCH) xe::LogLine('t', s) +#define IPRINT(s) \ + if (trace_enabled && THREAD_MATCH) \ + xe::LogLine(xe::LogLevel::LOG_LEVEL_DEBUG, 't', s) #define DFLUSH() -#define DPRINT(...) \ - if (trace_enabled && THREAD_MATCH) xe::LogLineFormat('t', __VA_ARGS__) +#define DPRINT(...) \ + if (trace_enabled && THREAD_MATCH) \ + xe::LogLineFormat(xe::LogLevel::LOG_LEVEL_DEBUG, 't', __VA_ARGS__) uint32_t GetTracingMode() { uint32_t mode = 0; diff --git a/src/xenia/kernel/user_module.cc b/src/xenia/kernel/user_module.cc index 20dff3054..b9831fd93 100644 --- a/src/xenia/kernel/user_module.cc +++ b/src/xenia/kernel/user_module.cc @@ -743,7 +743,7 @@ void UserModule::Dump() { sb.AppendFormat("\n"); } - xe::LogLine('i', sb.GetString()); + xe::LogLine(xe::LogLevel::LOG_LEVEL_INFO, 'i', sb.GetString()); } } // namespace kernel diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index f6b094360..1b5ec0d6c 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -450,9 +450,11 @@ void PrintKernelCall(cpu::Export* export_entry, const Tuple& params) { AppendKernelCallParams(string_buffer, export_entry, params); string_buffer.Append(')'); if (export_entry->tags & xe::cpu::ExportTag::kImportant) { - xe::LogLine('i', string_buffer.GetString(), string_buffer.length()); + xe::LogLine(xe::LogLevel::LOG_LEVEL_INFO, 'i', string_buffer.GetString(), + string_buffer.length()); } else { - xe::LogLine('d', string_buffer.GetString(), string_buffer.length()); + xe::LogLine(xe::LogLevel::LOG_LEVEL_DEBUG, 'd', string_buffer.GetString(), + string_buffer.length()); } }