From 0c055863ebb57c3446897e89c2c39a67442c1be4 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Fri, 27 Mar 2015 11:20:14 -0700 Subject: [PATCH] Support logging to other log buffers. LOGTO(dest, severity) and PLOGTO(dest, severity) log to other log buffers. For example, `LOGTO(SYSTEM, FATAL) << "Foobar";`. Change-Id: Id1ca1c8fdae72d69b73945ae9b006525d0be1582 --- base/include/base/logging.h | 60 +++++++++++++++++++++++-------------- base/logging.cpp | 40 +++++++++++++++++-------- 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/base/include/base/logging.h b/base/include/base/logging.h index 02832174a..346099781 100644 --- a/base/include/base/logging.h +++ b/base/include/base/logging.h @@ -34,6 +34,11 @@ enum LogSeverity { FATAL, }; +enum LogId { + MAIN, + SYSTEM, +}; + // Configure logging based on ANDROID_LOG_TAGS environment variable. // We need to parse a string that looks like // @@ -60,15 +65,26 @@ extern const char* ProgramInvocationShortName(); // FATAL it also causes an abort. For example: // // LOG(FATAL) << "We didn't expect to reach here"; -#define LOG(severity) \ - ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::severity, \ - -1).stream() +#define LOG(severity) \ + ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::MAIN, \ + ::android::base::severity, -1).stream() + +// Logs a message to logcat with the specified log ID on Android otherwise to +// stderr. If the severity is FATAL it also causes an abort. +#define LOG_TO(dest, severity) \ + ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::dest, \ + ::android::base::severity, -1).stream() // A variant of LOG that also logs the current errno value. To be used when // library calls fail. -#define PLOG(severity) \ - ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::severity, \ - errno).stream() +#define PLOG(severity) \ + ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::MAIN, \ + ::android::base::severity, errno).stream() + +// Behaves like PLOG, but logs to the specified log ID. +#define PLOG_TO(dest, severity) \ + ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::dest, \ + ::android::base::severity, errno).stream() // Marker that code is yet to be implemented. #define UNIMPLEMENTED(level) \ @@ -80,20 +96,20 @@ extern const char* ProgramInvocationShortName(); // // CHECK(false == true) results in a log message of // "Check failed: false == true". -#define CHECK(x) \ - if (UNLIKELY(!(x))) \ - ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, \ - -1).stream() \ - << "Check failed: " #x << " " +#define CHECK(x) \ + if (UNLIKELY(!(x))) \ + ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::MAIN, \ + ::android::base::FATAL, -1).stream() \ + << "Check failed: " #x << " " // Helper for CHECK_xx(x,y) macros. -#define CHECK_OP(LHS, RHS, OP) \ - for (auto _values = ::android::base::MakeEagerEvaluator(LHS, RHS); \ - UNLIKELY(!(_values.lhs OP _values.rhs)); \ - /* empty */) \ - ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, -1) \ - .stream() \ - << "Check failed: " << #LHS << " " << #OP << " " << #RHS \ +#define CHECK_OP(LHS, RHS, OP) \ + for (auto _values = ::android::base::MakeEagerEvaluator(LHS, RHS); \ + UNLIKELY(!(_values.lhs OP _values.rhs)); \ + /* empty */) \ + ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::MAIN, \ + ::android::base::FATAL, -1).stream() \ + << "Check failed: " << #LHS << " " << #OP << " " << #RHS \ << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") " // Check whether a condition holds between x and y, LOG(FATAL) if not. The value @@ -228,8 +244,8 @@ class LogMessageData; // of a CHECK. The destructor will abort if the severity is FATAL. class LogMessage { public: - LogMessage(const char* file, unsigned int line, LogSeverity severity, - int error); + LogMessage(const char* file, unsigned int line, LogId id, + LogSeverity severity, int error); ~LogMessage(); @@ -238,8 +254,8 @@ class LogMessage { std::ostream& stream(); // The routine that performs the actual logging. - static void LogLine(const char* file, unsigned int line, LogSeverity severity, - const char* msg); + static void LogLine(const char* file, unsigned int line, LogId id, + LogSeverity severity, const char* msg); private: const std::unique_ptr data_; diff --git a/base/logging.cpp b/base/logging.cpp index 144388ade..d2318cbb9 100644 --- a/base/logging.cpp +++ b/base/logging.cpp @@ -128,9 +128,13 @@ void InitLogging(char* argv[]) { // checks/logging in a function. class LogMessageData { public: - LogMessageData(const char* file, unsigned int line, LogSeverity severity, - int error) - : file_(file), line_number_(line), severity_(severity), error_(error) { + LogMessageData(const char* file, unsigned int line, LogId id, + LogSeverity severity, int error) + : file_(file), + line_number_(line), + id_(id), + severity_(severity), + error_(error) { const char* last_slash = strrchr(file, '/'); file = (last_slash == nullptr) ? file : last_slash + 1; } @@ -147,6 +151,10 @@ class LogMessageData { return severity_; } + LogId GetId() const { + return id_; + } + int GetError() const { return error_; } @@ -163,15 +171,16 @@ class LogMessageData { std::ostringstream buffer_; const char* const file_; const unsigned int line_number_; + const LogId id_; const LogSeverity severity_; const int error_; DISALLOW_COPY_AND_ASSIGN(LogMessageData); }; -LogMessage::LogMessage(const char* file, unsigned int line, +LogMessage::LogMessage(const char* file, unsigned int line, LogId id, LogSeverity severity, int error) - : data_(new LogMessageData(file, line, severity, error)) { + : data_(new LogMessageData(file, line, id, severity, error)) { } LogMessage::~LogMessage() { @@ -189,16 +198,16 @@ LogMessage::~LogMessage() { { std::lock_guard lock(logging_lock); if (msg.find('\n') == std::string::npos) { - LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetSeverity(), - msg.c_str()); + LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetId(), + data_->GetSeverity(), msg.c_str()); } else { msg += '\n'; size_t i = 0; while (i < msg.size()) { size_t nl = msg.find('\n', i); msg[nl] = '\0'; - LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetSeverity(), - &msg[i]); + LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetId(), + data_->GetSeverity(), &msg[i]); i = nl + 1; } } @@ -224,19 +233,26 @@ static const android_LogPriority kLogSeverityToAndroidLogPriority[] = { static_assert(arraysize(kLogSeverityToAndroidLogPriority) == FATAL + 1, "Mismatch in size of kLogSeverityToAndroidLogPriority and values " "in LogSeverity"); + +static const log_id kLogIdToAndroidLogId[] = {LOG_ID_MAIN, LOG_ID_SYSTEM}; +static_assert(arraysize(kLogIdToAndroidLogId) == SYSTEM + 1, + "Mismatch in size of kLogIdToAndroidLogId and values " + "in LogSeverity"); #endif -void LogMessage::LogLine(const char* file, unsigned int line, +void LogMessage::LogLine(const char* file, unsigned int line, LogId id, LogSeverity log_severity, const char* message) { #ifdef __ANDROID__ const char* tag = ProgramInvocationShortName(); int priority = kLogSeverityToAndroidLogPriority[log_severity]; + log_id lg_id = kLogIdToAndroidLogId[id]; if (priority == ANDROID_LOG_FATAL) { - LOG_PRI(priority, tag, "%s:%u] %s", file, line, message); + __android_log_buf_print(lg_id, priority, tag, "%s:%u] %s", file, line, message); } else { - LOG_PRI(priority, tag, "%s", message); + __android_log_buf_print(lg_id, priority, tag, "%s", message); } #else + UNUSED(id); static const char* log_characters = "VDIWEF"; CHECK_EQ(strlen(log_characters), FATAL + 1U); char severity = log_characters[log_severity];