diff options
-rw-r--r-- | base/include/android-base/logging.h | 3 | ||||
-rw-r--r-- | base/logging.cpp | 38 | ||||
-rw-r--r-- | 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 | |||
105 | 105 | ||
106 | void DefaultAborter(const char* abort_message); | 106 | void DefaultAborter(const char* abort_message); |
107 | 107 | ||
108 | std::string GetDefaultTag(); | ||
109 | void SetDefaultTag(const std::string& tag); | ||
110 | |||
108 | #ifdef __ANDROID__ | 111 | #ifdef __ANDROID__ |
109 | // We expose this even though it is the default because a user that wants to | 112 | // We expose this even though it is the default because a user that wants to |
110 | // override the default log buffer will have to construct this themselves. | 113 | // 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() { | |||
139 | return aborter; | 139 | return aborter; |
140 | } | 140 | } |
141 | 141 | ||
142 | static std::string& ProgramInvocationName() { | 142 | static std::recursive_mutex& TagLock() { |
143 | static auto& programInvocationName = *new std::string(getprogname()); | 143 | static auto& tag_lock = *new std::recursive_mutex(); |
144 | return programInvocationName; | 144 | return tag_lock; |
145 | } | ||
146 | static std::string* gDefaultTag; | ||
147 | std::string GetDefaultTag() { | ||
148 | std::lock_guard<std::recursive_mutex> lock(TagLock()); | ||
149 | if (gDefaultTag == nullptr) { | ||
150 | return ""; | ||
151 | } | ||
152 | return *gDefaultTag; | ||
153 | } | ||
154 | void SetDefaultTag(const std::string& tag) { | ||
155 | std::lock_guard<std::recursive_mutex> lock(TagLock()); | ||
156 | if (gDefaultTag != nullptr) { | ||
157 | delete gDefaultTag; | ||
158 | gDefaultTag = nullptr; | ||
159 | } | ||
160 | if (!tag.empty()) { | ||
161 | gDefaultTag = new std::string(tag); | ||
162 | } | ||
145 | } | 163 | } |
146 | 164 | ||
147 | static bool gInitialized = false; | 165 | static bool gInitialized = false; |
@@ -269,8 +287,7 @@ void InitLogging(char* argv[], LogFunction&& logger, AbortFunction&& aborter) { | |||
269 | // Linux to recover this, but we don't have that luxury on the Mac/Windows, | 287 | // Linux to recover this, but we don't have that luxury on the Mac/Windows, |
270 | // and there are a couple of argv[0] variants that are commonly used. | 288 | // and there are a couple of argv[0] variants that are commonly used. |
271 | if (argv != nullptr) { | 289 | if (argv != nullptr) { |
272 | std::lock_guard<std::mutex> lock(LoggingLock()); | 290 | SetDefaultTag(basename(argv[0])); |
273 | ProgramInvocationName() = basename(argv[0]); | ||
274 | } | 291 | } |
275 | 292 | ||
276 | const char* tags = getenv("ANDROID_LOG_TAGS"); | 293 | const char* tags = getenv("ANDROID_LOG_TAGS"); |
@@ -448,8 +465,15 @@ std::ostream& LogMessage::stream() { | |||
448 | 465 | ||
449 | void LogMessage::LogLine(const char* file, unsigned int line, LogId id, LogSeverity severity, | 466 | void LogMessage::LogLine(const char* file, unsigned int line, LogId id, LogSeverity severity, |
450 | const char* tag, const char* message) { | 467 | const char* tag, const char* message) { |
451 | if (tag == nullptr) tag = ProgramInvocationName().c_str(); | 468 | if (tag == nullptr) { |
452 | Logger()(id, severity, tag, file, line, message); | 469 | std::lock_guard<std::recursive_mutex> lock(TagLock()); |
470 | if (gDefaultTag == nullptr) { | ||
471 | gDefaultTag = new std::string(getprogname()); | ||
472 | } | ||
473 | Logger()(id, severity, gDefaultTag->c_str(), file, line, message); | ||
474 | } else { | ||
475 | Logger()(id, severity, tag, file, line, message); | ||
476 | } | ||
453 | } | 477 | } |
454 | 478 | ||
455 | void LogMessage::LogLine(const char* file, unsigned int line, LogId id, LogSeverity severity, | 479 | 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, | |||
206 | } | 206 | } |
207 | #endif | 207 | #endif |
208 | 208 | ||
209 | static void CheckMessage(const CapturedStderr& cap, | 209 | static void CheckMessage(const CapturedStderr& cap, android::base::LogSeverity severity, |
210 | android::base::LogSeverity severity, const char* expected) { | 210 | const char* expected, const char* expected_tag = nullptr) { |
211 | std::string output; | 211 | std::string output; |
212 | ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET)); | 212 | ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET)); |
213 | android::base::ReadFdToString(cap.fd(), &output); | 213 | android::base::ReadFdToString(cap.fd(), &output); |
@@ -217,9 +217,18 @@ static void CheckMessage(const CapturedStderr& cap, | |||
217 | // many characters are in the log message. | 217 | // many characters are in the log message. |
218 | ASSERT_GT(output.length(), strlen(expected)); | 218 | ASSERT_GT(output.length(), strlen(expected)); |
219 | ASSERT_NE(nullptr, strstr(output.c_str(), expected)) << output; | 219 | ASSERT_NE(nullptr, strstr(output.c_str(), expected)) << output; |
220 | if (expected_tag != nullptr) { | ||
221 | ASSERT_NE(nullptr, strstr(output.c_str(), expected_tag)) << output; | ||
222 | } | ||
220 | 223 | ||
221 | #if !defined(_WIN32) | 224 | #if !defined(_WIN32) |
222 | std::regex message_regex(make_log_pattern(severity, expected)); | 225 | std::string regex_str; |
226 | if (expected_tag != nullptr) { | ||
227 | regex_str.append(expected_tag); | ||
228 | regex_str.append(" "); | ||
229 | } | ||
230 | regex_str.append(make_log_pattern(severity, expected)); | ||
231 | std::regex message_regex(regex_str); | ||
223 | ASSERT_TRUE(std::regex_search(output, message_regex)) << output; | 232 | ASSERT_TRUE(std::regex_search(output, message_regex)) << output; |
224 | #endif | 233 | #endif |
225 | } | 234 | } |
@@ -600,3 +609,17 @@ TEST(logging, LOG_FATAL_ABORTER_MESSAGE) { | |||
600 | __attribute__((constructor)) void TestLoggingInConstructor() { | 609 | __attribute__((constructor)) void TestLoggingInConstructor() { |
601 | LOG(ERROR) << "foobar"; | 610 | LOG(ERROR) << "foobar"; |
602 | } | 611 | } |
612 | |||
613 | TEST(logging, SetDefaultTag) { | ||
614 | constexpr const char* expected_tag = "test_tag"; | ||
615 | constexpr const char* expected_msg = "foobar"; | ||
616 | CapturedStderr cap; | ||
617 | { | ||
618 | std::string old_default_tag = android::base::GetDefaultTag(); | ||
619 | android::base::SetDefaultTag(expected_tag); | ||
620 | android::base::ScopedLogSeverity sls(android::base::LogSeverity::INFO); | ||
621 | LOG(INFO) << expected_msg; | ||
622 | android::base::SetDefaultTag(old_default_tag); | ||
623 | } | ||
624 | CheckMessage(cap, android::base::LogSeverity::INFO, expected_msg, expected_tag); | ||
625 | } | ||