SetAborter and SetLogger return old function.
This is very useful when implementing a log capture RAII class.
The class can reset the logger to whatever it was before on
destruction instead of assuming it was the default.
Test: atest --host libbase_test
Change-Id: I62127c84a1d275c7fb24b0d1aafd5fcbe4a19ec6
diff --git a/include/android-base/logging.h b/include/android-base/logging.h
index 4e9d98f..9064075 100644
--- a/include/android-base/logging.h
+++ b/include/android-base/logging.h
@@ -98,21 +98,25 @@
CRASH,
};
-using LogFunction = std::function<void(LogId, LogSeverity, const char*, const char*,
- unsigned int, const char*)>;
-using AbortFunction = std::function<void(const char*)>;
+using LogFunction = std::function<void(LogId /*log_buffer_id*/,
+ LogSeverity /*severity*/,
+ const char* /*tag*/,
+ const char* /*file*/,
+ unsigned int /*line*/,
+ const char* /*message*/)>;
+using AbortFunction = std::function<void(const char* /*abort_message*/)>;
// Loggers for use with InitLogging/SetLogger.
// Log to the kernel log (dmesg).
-void KernelLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);
+void KernelLogger(LogId log_buffer_id, LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message);
// Log to stderr in the full logcat format (with pid/tid/time/tag details).
-void StderrLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);
+void StderrLogger(LogId log_buffer_id, LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message);
// Log just the message to stdout/stderr (without pid/tid/time/tag details).
// The choice of stdout versus stderr is based on the severity.
// Errors are also prefixed by the program name (as with err(3)/error(3)).
// Useful for replacing printf(3)/perror(3)/err(3)/error(3) in command-line tools.
-void StdioLogger(LogId, LogSeverity, const char*, const char*, unsigned int, const char*);
+void StdioLogger(LogId log_buffer_id, LogSeverity severity, const char* tag, const char* file, unsigned int line, const char* message);
void DefaultAborter(const char* abort_message);
@@ -151,11 +155,11 @@
AbortFunction&& aborter = DefaultAborter);
#undef INIT_LOGGING_DEFAULT_LOGGER
-// Replace the current logger.
-void SetLogger(LogFunction&& logger);
+// Replace the current logger and return the old one.
+LogFunction SetLogger(LogFunction&& logger);
-// Replace the current aborter.
-void SetAborter(AbortFunction&& aborter);
+// Replace the current aborter and return the old one.
+AbortFunction SetAborter(AbortFunction&& aborter);
// A helper macro that produces an expression that accepts both a qualified name and an
// unqualified name for a LogSeverity, and returns a LogSeverity value.
diff --git a/logging.cpp b/logging.cpp
index a0dd5f9..d6ecc78 100644
--- a/logging.cpp
+++ b/logging.cpp
@@ -397,7 +397,8 @@
}
}
-void SetLogger(LogFunction&& logger) {
+LogFunction SetLogger(LogFunction&& logger) {
+ LogFunction old_logger = std::move(Logger());
Logger() = std::move(logger);
static auto& liblog_functions = GetLibLogFunctions();
@@ -410,9 +411,11 @@
log_message->message);
});
}
+ return old_logger;
}
-void SetAborter(AbortFunction&& aborter) {
+AbortFunction SetAborter(AbortFunction&& aborter) {
+ AbortFunction old_aborter = std::move(Aborter());
Aborter() = std::move(aborter);
static auto& liblog_functions = GetLibLogFunctions();
@@ -420,6 +423,7 @@
liblog_functions->__android_log_set_aborter(
[](const char* abort_message) { Aborter()(abort_message); });
}
+ return old_aborter;
}
// This indirection greatly reduces the stack impact of having lots of
diff --git a/logging_test.cpp b/logging_test.cpp
index d8d0855..be2e042 100644
--- a/logging_test.cpp
+++ b/logging_test.cpp
@@ -619,6 +619,14 @@
EXPECT_EQ(CountLineAborter::newline_count, 1U);
}
+TEST(logging, SetAborterReturnsOldFunction) {
+ // std::function is not comparable, it only supports a null check.
+ android::base::AbortFunction old_aborter;
+ EXPECT_FALSE(old_aborter);
+ old_aborter = android::base::SetAborter(android::base::DefaultAborter);
+ EXPECT_TRUE(old_aborter);
+}
+
__attribute__((constructor)) void TestLoggingInConstructor() {
LOG(ERROR) << "foobar";
}
@@ -638,6 +646,14 @@
ASSERT_EQ(android::base::Basename(android::base::GetExecutablePath()) + ": err\n", cap_err.str());
}
+TEST(logging, SetLoggerReturnsOldFunction) {
+ // std::function is not comparable, it only supports a null check.
+ android::base::LogFunction old_function;
+ EXPECT_FALSE(old_function);
+ old_function = android::base::SetLogger(android::base::StdioLogger);
+ EXPECT_TRUE(old_function);
+}
+
TEST(logging, ForkSafe) {
#if !defined(_WIN32)
using namespace android::base;