Logging: Add a flag to specify the minimum log level

--log_level = (0=error, 1=warning, 2=info, 3=debug)
This commit is contained in:
DrChat 2017-03-24 16:28:41 -05:00
parent 92a4b90ed0
commit e699be0118
6 changed files with 85 additions and 41 deletions

View File

@ -65,27 +65,33 @@ void av_log_callback(void* avcl, int level, const char* fmt, va_list va) {
} }
char level_char = '?'; char level_char = '?';
LogLevel log_level;
switch (level) { switch (level) {
case AV_LOG_ERROR: case AV_LOG_ERROR:
level_char = '!'; level_char = '!';
log_level = xe::LogLevel::LOG_LEVEL_ERROR;
break; break;
case AV_LOG_WARNING: case AV_LOG_WARNING:
level_char = 'w'; level_char = 'w';
log_level = xe::LogLevel::LOG_LEVEL_WARNING;
break; break;
case AV_LOG_INFO: case AV_LOG_INFO:
level_char = 'i'; level_char = 'i';
log_level = xe::LogLevel::LOG_LEVEL_INFO;
break; break;
case AV_LOG_VERBOSE: case AV_LOG_VERBOSE:
level_char = 'v'; level_char = 'v';
log_level = xe::LogLevel::LOG_LEVEL_DEBUG;
break; break;
case AV_LOG_DEBUG: case AV_LOG_DEBUG:
level_char = 'd'; level_char = 'd';
log_level = xe::LogLevel::LOG_LEVEL_DEBUG;
break; break;
} }
StringBuffer buff; StringBuffer buff;
buff.AppendVarargs(fmt, va); 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) { X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) {

View File

@ -38,6 +38,9 @@ DEFINE_string(
"Logs are written to the given file (specify stdout for command line)"); "Logs are written to the given file (specify stdout for command line)");
DEFINE_bool(log_debugprint, false, "Dump the log to DebugPrint."); DEFINE_bool(log_debugprint, false, "Dump the log to DebugPrint.");
DEFINE_bool(flush_log, true, "Flush log file after each log line batch."); 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 { namespace xe {
@ -71,12 +74,17 @@ class Logger {
fclose(file_); fclose(file_);
} }
void AppendLine(uint32_t thread_id, const char level_char, const char* buffer, void AppendLine(uint32_t thread_id, LogLevel level, const char prefix_char,
size_t buffer_length) { const char* buffer, size_t buffer_length) {
if (static_cast<int32_t>(level) > FLAGS_log_level) {
// Discard this line.
return;
}
LogLine line; LogLine line;
line.buffer_length = buffer_length; line.buffer_length = buffer_length;
line.thread_id = thread_id; 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 // 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 // head without any problems. If so, cmpxchg it to reserve some space in the
@ -125,7 +133,9 @@ class Logger {
struct LogLine { struct LogLine {
size_t buffer_length; size_t buffer_length;
uint32_t thread_id; 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) { void Write(const char* buf, size_t size) {
@ -151,7 +161,7 @@ class Logger {
LogLine line; LogLine line;
rb.Read(&line, sizeof(line)); rb.Read(&line, sizeof(line));
char prefix[] = { char prefix[] = {
line.level_char, line.prefix_char,
'>', '>',
' ', ' ',
'0', // Thread ID gets placed here (8 chars). '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); 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_list args;
va_start(args, fmt); va_start(args, fmt);
int chars_written = vsnprintf(log_format_buffer_.data(), int chars_written = vsnprintf(log_format_buffer_.data(),
log_format_buffer_.capacity(), fmt, args); log_format_buffer_.capacity(), fmt, args);
va_end(args); va_end(args);
if (chars_written >= 0 && chars_written < log_format_buffer_.capacity()) { if (chars_written >= 0 && chars_written < log_format_buffer_.capacity()) {
logger_->AppendLine(xe::threading::current_thread_id(), level_char, logger_->AppendLine(xe::threading::current_thread_id(), log_level,
log_format_buffer_.data(), chars_written); prefix_char, log_format_buffer_.data(), chars_written);
} else if (chars_written >= 0) { } else if (chars_written >= 0) {
logger_->AppendLine(xe::threading::current_thread_id(), level_char, fmt, logger_->AppendLine(xe::threading::current_thread_id(), log_level,
std::strlen(fmt)); 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(), int chars_written = vsnprintf(log_format_buffer_.data(),
log_format_buffer_.capacity(), fmt, args); log_format_buffer_.capacity(), fmt, args);
if (chars_written < 0) { if (chars_written < 0) {
@ -252,25 +264,27 @@ void LogLineVarargs(const char level_char, const char* fmt, va_list args) {
auto size = auto size =
std::min(size_t(chars_written), log_format_buffer_.capacity() - 1); std::min(size_t(chars_written), log_format_buffer_.capacity() - 1);
logger_->AppendLine(xe::threading::current_thread_id(), level_char, logger_->AppendLine(xe::threading::current_thread_id(), log_level,
log_format_buffer_.data(), size); 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( 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); str_length == std::string::npos ? std::strlen(str) : str_length);
} }
void LogLine(const char level_char, const std::string& str) { void LogLine(LogLevel log_level, const char prefix_char,
logger_->AppendLine(xe::threading::current_thread_id(), level_char, const std::string& str) {
str.c_str(), str.length()); logger_->AppendLine(xe::threading::current_thread_id(), log_level,
prefix_char, str.c_str(), str.length());
} }
void FatalError(const char* fmt, ...) { void FatalError(const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
LogLineVarargs('X', fmt, args); LogLineVarargs(LogLevel::LOG_LEVEL_ERROR, 'X', fmt, args);
va_end(args); va_end(args);
#if XE_PLATFORM_WIN32 #if XE_PLATFORM_WIN32

View File

@ -19,17 +19,27 @@ namespace xe {
#define XE_OPTION_ENABLE_LOGGING 1 #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. // Initializes the logging system and any outputs requested.
// Must be called on startup. // Must be called on startup.
void InitializeLogging(const std::wstring& app_name); void InitializeLogging(const std::wstring& app_name);
// Appends a line to the log with printf-style formatting. // Appends a line to the log with printf-style formatting.
void LogLineFormat(const char level_char, const char* fmt, ...); void LogLineFormat(LogLevel log_level, const char prefix_char, const char* 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);
// Appends a line to the log. // 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); 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. // Logs a fatal error with printf-style formatting and aborts the program.
void FatalError(const char* fmt, ...); void FatalError(const char* fmt, ...);
@ -37,23 +47,33 @@ void FatalError(const char* fmt, ...);
void FatalError(const std::string& str); void FatalError(const std::string& str);
#if XE_OPTION_ENABLE_LOGGING #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 #else
#define XELOGCORE(level, fmt, ...) \ #define XELOGCORE(level, fmt, ...) \
do { \ do { \
} while (false) } while (false)
#endif // ENABLE_LOGGING #endif // ENABLE_LOGGING
#define XELOGE(fmt, ...) XELOGCORE('!', fmt, ##__VA_ARGS__) #define XELOGE(fmt, ...) \
#define XELOGW(fmt, ...) XELOGCORE('w', fmt, ##__VA_ARGS__) XELOGCORE(xe::LogLevel::LOG_LEVEL_ERROR, '!', fmt, ##__VA_ARGS__)
#define XELOGI(fmt, ...) XELOGCORE('i', fmt, ##__VA_ARGS__) #define XELOGW(fmt, ...) \
#define XELOGD(fmt, ...) XELOGCORE('d', fmt, ##__VA_ARGS__) 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 XELOGCPU(fmt, ...) \
#define XELOGAPU(fmt, ...) XELOGCORE('A', fmt, ##__VA_ARGS__) XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'C', fmt, ##__VA_ARGS__)
#define XELOGGPU(fmt, ...) XELOGCORE('G', fmt, ##__VA_ARGS__) #define XELOGAPU(fmt, ...) \
#define XELOGKERNEL(fmt, ...) XELOGCORE('K', fmt, ##__VA_ARGS__) XELOGCORE(xe::LogLevel::LOG_LEVEL_INFO, 'A', fmt, ##__VA_ARGS__)
#define XELOGFS(fmt, ...) XELOGCORE('F', 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 } // namespace xe

View File

@ -32,11 +32,13 @@ bool trace_enabled = true;
#define THREAD_MATCH \ #define THREAD_MATCH \
(!TARGET_THREAD || thread_state->thread_id() == TARGET_THREAD) (!TARGET_THREAD || thread_state->thread_id() == TARGET_THREAD)
#define IFLUSH() #define IFLUSH()
#define IPRINT(s) \ #define IPRINT(s) \
if (trace_enabled && THREAD_MATCH) xe::LogLine('t', s) if (trace_enabled && THREAD_MATCH) \
xe::LogLine(xe::LogLevel::LOG_LEVEL_DEBUG, 't', s)
#define DFLUSH() #define DFLUSH()
#define DPRINT(...) \ #define DPRINT(...) \
if (trace_enabled && THREAD_MATCH) xe::LogLineFormat('t', __VA_ARGS__) if (trace_enabled && THREAD_MATCH) \
xe::LogLineFormat(xe::LogLevel::LOG_LEVEL_DEBUG, 't', __VA_ARGS__)
uint32_t GetTracingMode() { uint32_t GetTracingMode() {
uint32_t mode = 0; uint32_t mode = 0;

View File

@ -743,7 +743,7 @@ void UserModule::Dump() {
sb.AppendFormat("\n"); sb.AppendFormat("\n");
} }
xe::LogLine('i', sb.GetString()); xe::LogLine(xe::LogLevel::LOG_LEVEL_INFO, 'i', sb.GetString());
} }
} // namespace kernel } // namespace kernel

View File

@ -450,9 +450,11 @@ void PrintKernelCall(cpu::Export* export_entry, const Tuple& params) {
AppendKernelCallParams(string_buffer, export_entry, params); AppendKernelCallParams(string_buffer, export_entry, params);
string_buffer.Append(')'); string_buffer.Append(')');
if (export_entry->tags & xe::cpu::ExportTag::kImportant) { 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 { } else {
xe::LogLine('d', string_buffer.GetString(), string_buffer.length()); xe::LogLine(xe::LogLevel::LOG_LEVEL_DEBUG, 'd', string_buffer.GetString(),
string_buffer.length());
} }
} }