From 1923e768efeaf637bd368f93faa41ea45f542685 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Mon, 5 Mar 2018 10:00:19 -0800 Subject: [PATCH] Base: Add default tag manipulation Allow the default tag (the program name) to be overwritten. Bug: 34867873 Test: m Test: logging_test Test: manual Change-Id: I4ef32bad413a7cc82e46ce16a2f26212925964b1 --- base/include/android-base/logging.h | 3 +++ base/logging.cpp | 38 +++++++++++++++++++++++------ base/logging_test.cpp | 29 +++++++++++++++++++--- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/base/include/android-base/logging.h b/base/include/android-base/logging.h index afff2c951..cc7aaf68c 100644 --- a/base/include/android-base/logging.h +++ b/base/include/android-base/logging.h @@ -105,6 +105,9 @@ void StderrLogger(LogId, LogSeverity, const char*, const char*, unsigned int, co void DefaultAborter(const char* abort_message); +std::string GetDefaultTag(); +void SetDefaultTag(const std::string& tag); + #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. diff --git a/base/logging.cpp b/base/logging.cpp index 1f7bc2ab9..a31feefab 100644 --- a/base/logging.cpp +++ b/base/logging.cpp @@ -139,9 +139,27 @@ static AbortFunction& Aborter() { return aborter; } -static std::string& ProgramInvocationName() { - static auto& programInvocationName = *new std::string(getprogname()); - return programInvocationName; +static std::recursive_mutex& TagLock() { + static auto& tag_lock = *new std::recursive_mutex(); + return tag_lock; +} +static std::string* gDefaultTag; +std::string GetDefaultTag() { + std::lock_guard lock(TagLock()); + if (gDefaultTag == nullptr) { + return ""; + } + return *gDefaultTag; +} +void SetDefaultTag(const std::string& tag) { + std::lock_guard lock(TagLock()); + if (gDefaultTag != nullptr) { + delete gDefaultTag; + gDefaultTag = nullptr; + } + if (!tag.empty()) { + gDefaultTag = new std::string(tag); + } } static bool gInitialized = false; @@ -269,8 +287,7 @@ void InitLogging(char* argv[], LogFunction&& logger, AbortFunction&& aborter) { // Linux to recover this, but we don't have that luxury on the Mac/Windows, // and there are a couple of argv[0] variants that are commonly used. if (argv != nullptr) { - std::lock_guard lock(LoggingLock()); - ProgramInvocationName() = basename(argv[0]); + SetDefaultTag(basename(argv[0])); } const char* tags = getenv("ANDROID_LOG_TAGS"); @@ -448,8 +465,15 @@ std::ostream& LogMessage::stream() { void LogMessage::LogLine(const char* file, unsigned int line, LogId id, LogSeverity severity, const char* tag, const char* message) { - if (tag == nullptr) tag = ProgramInvocationName().c_str(); - Logger()(id, severity, tag, file, line, message); + if (tag == nullptr) { + std::lock_guard lock(TagLock()); + if (gDefaultTag == nullptr) { + gDefaultTag = new std::string(getprogname()); + } + Logger()(id, severity, gDefaultTag->c_str(), file, line, message); + } else { + Logger()(id, severity, tag, file, line, message); + } } void LogMessage::LogLine(const char* file, unsigned int line, LogId id, LogSeverity severity, diff --git a/base/logging_test.cpp b/base/logging_test.cpp index 6f05d9b7f..5f689faf3 100644 --- a/base/logging_test.cpp +++ b/base/logging_test.cpp @@ -206,8 +206,8 @@ static std::string make_log_pattern(android::base::LogSeverity severity, } #endif -static void CheckMessage(const CapturedStderr& cap, - android::base::LogSeverity severity, const char* expected) { +static void CheckMessage(const CapturedStderr& cap, android::base::LogSeverity severity, + const char* expected, const char* expected_tag = nullptr) { std::string output; ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET)); android::base::ReadFdToString(cap.fd(), &output); @@ -217,9 +217,18 @@ static void CheckMessage(const CapturedStderr& cap, // many characters are in the log message. ASSERT_GT(output.length(), strlen(expected)); ASSERT_NE(nullptr, strstr(output.c_str(), expected)) << output; + if (expected_tag != nullptr) { + ASSERT_NE(nullptr, strstr(output.c_str(), expected_tag)) << output; + } #if !defined(_WIN32) - std::regex message_regex(make_log_pattern(severity, expected)); + std::string regex_str; + if (expected_tag != nullptr) { + regex_str.append(expected_tag); + regex_str.append(" "); + } + regex_str.append(make_log_pattern(severity, expected)); + std::regex message_regex(regex_str); ASSERT_TRUE(std::regex_search(output, message_regex)) << output; #endif } @@ -600,3 +609,17 @@ TEST(logging, LOG_FATAL_ABORTER_MESSAGE) { __attribute__((constructor)) void TestLoggingInConstructor() { LOG(ERROR) << "foobar"; } + +TEST(logging, SetDefaultTag) { + constexpr const char* expected_tag = "test_tag"; + constexpr const char* expected_msg = "foobar"; + CapturedStderr cap; + { + std::string old_default_tag = android::base::GetDefaultTag(); + android::base::SetDefaultTag(expected_tag); + android::base::ScopedLogSeverity sls(android::base::LogSeverity::INFO); + LOG(INFO) << expected_msg; + android::base::SetDefaultTag(old_default_tag); + } + CheckMessage(cap, android::base::LogSeverity::INFO, expected_msg, expected_tag); +}