Loading base/include/base/logging.h +45 −15 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #ifndef BASE_LOGGING_H #define BASE_LOGGING_H #include <functional> #include <memory> #include <ostream> Loading @@ -35,10 +36,32 @@ enum LogSeverity { }; enum LogId { DEFAULT, MAIN, SYSTEM, }; typedef std::function<void(LogId, LogSeverity, const char*, const char*, unsigned int, const char*)> LogFunction; extern void StderrLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*); #ifdef __ANDROID__ // We expose this even though it is the default because a user that wants to // override the default log buffer will have to construct this themselves. class LogdLogger { public: explicit LogdLogger(LogId default_log_id = android::base::MAIN); void operator()(LogId, LogSeverity, const char* tag, const char* file, unsigned int line, const char* message); private: LogId default_log_id_; }; #endif // Configure logging based on ANDROID_LOG_TAGS environment variable. // We need to parse a string that looks like // Loading @@ -47,8 +70,15 @@ enum LogId { // The tag (or '*' for the global level) comes first, followed by a colon and a // letter indicating the minimum priority level we're expected to log. This can // be used to reveal or conceal logs with specific tags. extern void InitLogging(char* argv[], LogFunction&& logger); // Configures logging using the default logger (logd for the device, stderr for // the host). extern void InitLogging(char* argv[]); // Replace the current logger. extern void SetLogger(LogFunction&& logger); // Returns the command line used to invoke the current tool or nullptr if // InitLogging hasn't been performed. extern const char* GetCmdLine(); Loading @@ -66,7 +96,7 @@ extern const char* ProgramInvocationShortName(); // // LOG(FATAL) << "We didn't expect to reach here"; #define LOG(severity) \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::MAIN, \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ ::android::base::severity, -1).stream() // Logs a message to logcat with the specified log ID on Android otherwise to Loading @@ -78,7 +108,7 @@ extern const char* ProgramInvocationShortName(); // 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::MAIN, \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ ::android::base::severity, errno).stream() // Behaves like PLOG, but logs to the specified log ID. Loading @@ -98,7 +128,7 @@ extern const char* ProgramInvocationShortName(); // "Check failed: false == true". #define CHECK(x) \ if (UNLIKELY(!(x))) \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::MAIN, \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ ::android::base::FATAL, -1).stream() \ << "Check failed: " #x << " " Loading @@ -107,7 +137,7 @@ extern const char* ProgramInvocationShortName(); 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::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ ::android::base::FATAL, -1).stream() \ << "Check failed: " << #LHS << " " << #OP << " " << #RHS \ << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") " Loading base/logging.cpp +78 −46 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <mutex> #include <sstream> #include <string> #include <utility> #include <vector> #include "base/strings.h" Loading @@ -40,6 +41,12 @@ namespace base { static std::mutex logging_lock; #ifdef __ANDROID__ static LogFunction gLogger = LogdLogger(); #else static LogFunction gLogger = StderrLogger; #endif static LogSeverity gMinimumLogSeverity = INFO; static std::unique_ptr<std::string> gCmdLine; static std::unique_ptr<std::string> gProgramInvocationName; Loading @@ -61,6 +68,58 @@ const char* ProgramInvocationShortName() { : "unknown"; } void StderrLogger(LogId, LogSeverity severity, const char*, const char* file, unsigned int line, const char* message) { static const char* log_characters = "VDIWEF"; CHECK_EQ(strlen(log_characters), FATAL + 1U); char severity_char = log_characters[severity]; fprintf(stderr, "%s %c %5d %5d %s:%u] %s\n", ProgramInvocationShortName(), severity_char, getpid(), gettid(), file, line, message); } #ifdef __ANDROID__ LogdLogger::LogdLogger(LogId default_log_id) : default_log_id_(default_log_id) { } static const android_LogPriority kLogSeverityToAndroidLogPriority[] = { ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, }; static_assert(arraysize(kLogSeverityToAndroidLogPriority) == FATAL + 1, "Mismatch in size of kLogSeverityToAndroidLogPriority and values " "in LogSeverity"); static const log_id kLogIdToAndroidLogId[] = { LOG_ID_MAX, LOG_ID_MAIN, LOG_ID_SYSTEM, }; static_assert(arraysize(kLogIdToAndroidLogId) == SYSTEM + 1, "Mismatch in size of kLogIdToAndroidLogId and values in LogId"); void LogdLogger::operator()(LogId id, LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message) { int priority = kLogSeverityToAndroidLogPriority[severity]; if (id == DEFAULT) { id = default_log_id_; } log_id lg_id = kLogIdToAndroidLogId[id]; if (priority == ANDROID_LOG_FATAL) { __android_log_buf_print(lg_id, priority, tag, "%s:%u] %s", file, line, message); } else { __android_log_buf_print(lg_id, priority, tag, "%s", message); } } #endif void InitLogging(char* argv[], LogFunction&& logger) { SetLogger(std::forward<LogFunction>(logger)); InitLogging(argv); } void InitLogging(char* argv[]) { if (gCmdLine.get() != nullptr) { return; Loading Loading @@ -124,6 +183,11 @@ void InitLogging(char* argv[]) { } } void SetLogger(LogFunction&& logger) { std::lock_guard<std::mutex> lock(logging_lock); gLogger = std::move(logger); } // This indirection greatly reduces the stack impact of having lots of // checks/logging in a function. class LogMessageData { Loading Loading @@ -194,9 +258,6 @@ LogMessage::~LogMessage() { } std::string msg(data_->ToString()); // Do the actual logging with the lock held. { std::lock_guard<std::mutex> lock(logging_lock); if (msg.find('\n') == std::string::npos) { LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetId(), data_->GetSeverity(), msg.c_str()); Loading @@ -211,7 +272,6 @@ LogMessage::~LogMessage() { i = nl + 1; } } } // Abort if necessary. if (data_->GetSeverity() == FATAL) { Loading @@ -226,39 +286,11 @@ std::ostream& LogMessage::stream() { return data_->GetBuffer(); } #ifdef __ANDROID__ static const android_LogPriority kLogSeverityToAndroidLogPriority[] = { ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL}; 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, LogId id, LogSeverity log_severity, const char* message) { #ifdef __ANDROID__ LogSeverity severity, const char* message) { const char* tag = ProgramInvocationShortName(); int priority = kLogSeverityToAndroidLogPriority[log_severity]; log_id lg_id = kLogIdToAndroidLogId[id]; if (priority == ANDROID_LOG_FATAL) { __android_log_buf_print(lg_id, priority, tag, "%s:%u] %s", file, line, message); } else { __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]; fprintf(stderr, "%s %c %5d %5d %s:%u] %s\n", ProgramInvocationShortName(), severity, getpid(), gettid(), file, line, message); #endif std::lock_guard<std::mutex> lock(logging_lock); gLogger(id, severity, tag, file, line, message); } ScopedLogSeverity::ScopedLogSeverity(LogSeverity level) { Loading base/logging_test.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ class CapturedStderr { int old_stderr_; }; HOST_TEST(logging, CHECK) { TEST(logging, CHECK) { ASSERT_DEATH(CHECK(false), "Check failed: false "); CHECK(true); Loading @@ -82,7 +82,7 @@ std::string make_log_pattern(android::base::LogSeverity severity, log_char, message); } HOST_TEST(logging, LOG) { TEST(logging, LOG) { ASSERT_DEATH(LOG(FATAL) << "foobar", "foobar"); { Loading Loading @@ -136,7 +136,7 @@ HOST_TEST(logging, LOG) { } } HOST_TEST(logging, PLOG) { TEST(logging, PLOG) { { CapturedStderr cap; errno = ENOENT; Loading @@ -152,7 +152,7 @@ HOST_TEST(logging, PLOG) { } } HOST_TEST(logging, UNIMPLEMENTED) { TEST(logging, UNIMPLEMENTED) { { CapturedStderr cap; errno = ENOENT; Loading base/test_main.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,6 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); android::base::InitLogging(argv); android::base::InitLogging(argv, android::base::StderrLogger); return RUN_ALL_TESTS(); } Loading
base/include/base/logging.h +45 −15 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #ifndef BASE_LOGGING_H #define BASE_LOGGING_H #include <functional> #include <memory> #include <ostream> Loading @@ -35,10 +36,32 @@ enum LogSeverity { }; enum LogId { DEFAULT, MAIN, SYSTEM, }; typedef std::function<void(LogId, LogSeverity, const char*, const char*, unsigned int, const char*)> LogFunction; extern void StderrLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*); #ifdef __ANDROID__ // We expose this even though it is the default because a user that wants to // override the default log buffer will have to construct this themselves. class LogdLogger { public: explicit LogdLogger(LogId default_log_id = android::base::MAIN); void operator()(LogId, LogSeverity, const char* tag, const char* file, unsigned int line, const char* message); private: LogId default_log_id_; }; #endif // Configure logging based on ANDROID_LOG_TAGS environment variable. // We need to parse a string that looks like // Loading @@ -47,8 +70,15 @@ enum LogId { // The tag (or '*' for the global level) comes first, followed by a colon and a // letter indicating the minimum priority level we're expected to log. This can // be used to reveal or conceal logs with specific tags. extern void InitLogging(char* argv[], LogFunction&& logger); // Configures logging using the default logger (logd for the device, stderr for // the host). extern void InitLogging(char* argv[]); // Replace the current logger. extern void SetLogger(LogFunction&& logger); // Returns the command line used to invoke the current tool or nullptr if // InitLogging hasn't been performed. extern const char* GetCmdLine(); Loading @@ -66,7 +96,7 @@ extern const char* ProgramInvocationShortName(); // // LOG(FATAL) << "We didn't expect to reach here"; #define LOG(severity) \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::MAIN, \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ ::android::base::severity, -1).stream() // Logs a message to logcat with the specified log ID on Android otherwise to Loading @@ -78,7 +108,7 @@ extern const char* ProgramInvocationShortName(); // 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::MAIN, \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ ::android::base::severity, errno).stream() // Behaves like PLOG, but logs to the specified log ID. Loading @@ -98,7 +128,7 @@ extern const char* ProgramInvocationShortName(); // "Check failed: false == true". #define CHECK(x) \ if (UNLIKELY(!(x))) \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::MAIN, \ ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ ::android::base::FATAL, -1).stream() \ << "Check failed: " #x << " " Loading @@ -107,7 +137,7 @@ extern const char* ProgramInvocationShortName(); 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::LogMessage(__FILE__, __LINE__, ::android::base::DEFAULT, \ ::android::base::FATAL, -1).stream() \ << "Check failed: " << #LHS << " " << #OP << " " << #RHS \ << " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") " Loading
base/logging.cpp +78 −46 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <mutex> #include <sstream> #include <string> #include <utility> #include <vector> #include "base/strings.h" Loading @@ -40,6 +41,12 @@ namespace base { static std::mutex logging_lock; #ifdef __ANDROID__ static LogFunction gLogger = LogdLogger(); #else static LogFunction gLogger = StderrLogger; #endif static LogSeverity gMinimumLogSeverity = INFO; static std::unique_ptr<std::string> gCmdLine; static std::unique_ptr<std::string> gProgramInvocationName; Loading @@ -61,6 +68,58 @@ const char* ProgramInvocationShortName() { : "unknown"; } void StderrLogger(LogId, LogSeverity severity, const char*, const char* file, unsigned int line, const char* message) { static const char* log_characters = "VDIWEF"; CHECK_EQ(strlen(log_characters), FATAL + 1U); char severity_char = log_characters[severity]; fprintf(stderr, "%s %c %5d %5d %s:%u] %s\n", ProgramInvocationShortName(), severity_char, getpid(), gettid(), file, line, message); } #ifdef __ANDROID__ LogdLogger::LogdLogger(LogId default_log_id) : default_log_id_(default_log_id) { } static const android_LogPriority kLogSeverityToAndroidLogPriority[] = { ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, }; static_assert(arraysize(kLogSeverityToAndroidLogPriority) == FATAL + 1, "Mismatch in size of kLogSeverityToAndroidLogPriority and values " "in LogSeverity"); static const log_id kLogIdToAndroidLogId[] = { LOG_ID_MAX, LOG_ID_MAIN, LOG_ID_SYSTEM, }; static_assert(arraysize(kLogIdToAndroidLogId) == SYSTEM + 1, "Mismatch in size of kLogIdToAndroidLogId and values in LogId"); void LogdLogger::operator()(LogId id, LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message) { int priority = kLogSeverityToAndroidLogPriority[severity]; if (id == DEFAULT) { id = default_log_id_; } log_id lg_id = kLogIdToAndroidLogId[id]; if (priority == ANDROID_LOG_FATAL) { __android_log_buf_print(lg_id, priority, tag, "%s:%u] %s", file, line, message); } else { __android_log_buf_print(lg_id, priority, tag, "%s", message); } } #endif void InitLogging(char* argv[], LogFunction&& logger) { SetLogger(std::forward<LogFunction>(logger)); InitLogging(argv); } void InitLogging(char* argv[]) { if (gCmdLine.get() != nullptr) { return; Loading Loading @@ -124,6 +183,11 @@ void InitLogging(char* argv[]) { } } void SetLogger(LogFunction&& logger) { std::lock_guard<std::mutex> lock(logging_lock); gLogger = std::move(logger); } // This indirection greatly reduces the stack impact of having lots of // checks/logging in a function. class LogMessageData { Loading Loading @@ -194,9 +258,6 @@ LogMessage::~LogMessage() { } std::string msg(data_->ToString()); // Do the actual logging with the lock held. { std::lock_guard<std::mutex> lock(logging_lock); if (msg.find('\n') == std::string::npos) { LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetId(), data_->GetSeverity(), msg.c_str()); Loading @@ -211,7 +272,6 @@ LogMessage::~LogMessage() { i = nl + 1; } } } // Abort if necessary. if (data_->GetSeverity() == FATAL) { Loading @@ -226,39 +286,11 @@ std::ostream& LogMessage::stream() { return data_->GetBuffer(); } #ifdef __ANDROID__ static const android_LogPriority kLogSeverityToAndroidLogPriority[] = { ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL}; 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, LogId id, LogSeverity log_severity, const char* message) { #ifdef __ANDROID__ LogSeverity severity, const char* message) { const char* tag = ProgramInvocationShortName(); int priority = kLogSeverityToAndroidLogPriority[log_severity]; log_id lg_id = kLogIdToAndroidLogId[id]; if (priority == ANDROID_LOG_FATAL) { __android_log_buf_print(lg_id, priority, tag, "%s:%u] %s", file, line, message); } else { __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]; fprintf(stderr, "%s %c %5d %5d %s:%u] %s\n", ProgramInvocationShortName(), severity, getpid(), gettid(), file, line, message); #endif std::lock_guard<std::mutex> lock(logging_lock); gLogger(id, severity, tag, file, line, message); } ScopedLogSeverity::ScopedLogSeverity(LogSeverity level) { Loading
base/logging_test.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ class CapturedStderr { int old_stderr_; }; HOST_TEST(logging, CHECK) { TEST(logging, CHECK) { ASSERT_DEATH(CHECK(false), "Check failed: false "); CHECK(true); Loading @@ -82,7 +82,7 @@ std::string make_log_pattern(android::base::LogSeverity severity, log_char, message); } HOST_TEST(logging, LOG) { TEST(logging, LOG) { ASSERT_DEATH(LOG(FATAL) << "foobar", "foobar"); { Loading Loading @@ -136,7 +136,7 @@ HOST_TEST(logging, LOG) { } } HOST_TEST(logging, PLOG) { TEST(logging, PLOG) { { CapturedStderr cap; errno = ENOENT; Loading @@ -152,7 +152,7 @@ HOST_TEST(logging, PLOG) { } } HOST_TEST(logging, UNIMPLEMENTED) { TEST(logging, UNIMPLEMENTED) { { CapturedStderr cap; errno = ENOENT; Loading
base/test_main.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,6 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); android::base::InitLogging(argv); android::base::InitLogging(argv, android::base::StderrLogger); return RUN_ALL_TESTS(); }