Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2130)

Unified Diff: base/logging.cc

Issue 2034393004: Allow multiple logging::LogMessage{Handler,Listener}s Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: clean up, MockLog uses listener Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/logging.cc
diff --git a/base/logging.cc b/base/logging.cc
index 0771b47c182e5c18c868f1124a0784bf411d74a9..f1140b29aaae1976b1025ccafcf3206ffce127aa 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -49,15 +49,18 @@ typedef pthread_mutex_t* MutexHandle;
#include <algorithm>
#include <cstring>
#include <ctime>
+#include <deque>
#include <iomanip>
#include <ostream>
#include <string>
+#include <unordered_set>
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/debug/alias.h"
#include "base/debug/debugger.h"
#include "base/debug/stack_trace.h"
+#include "base/lazy_instance.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
@@ -123,8 +126,13 @@ bool show_error_dialogs = false;
// An assert handler override specified by the client to be called instead of
// the debug message dialog and process termination.
LogAssertHandlerFunction log_assert_handler = nullptr;
-// A log message handler that gets notified of every log message we process.
-LogMessageHandlerFunction log_message_handler = nullptr;
+// Log message handlers that get notified of every log message we process.
+base::LazyInstance<std::deque<LogMessageHandlerFunction>>::Leaky
+ log_message_handlers = LAZY_INSTANCE_INITIALIZER;
+// Log message listeners that get notified of every log message we process
+// before log message handlers.
+base::LazyInstance<std::unordered_set<LogMessageListenerFunction>>::Leaky
+ log_message_listeners = LAZY_INSTANCE_INITIALIZER;
// Helper functions to wrap platform differences.
@@ -342,6 +350,16 @@ void CloseLogFileUnlocked() {
} // namespace
+ScopedLogMessageListener::ScopedLogMessageListener(
+ LogMessageListenerFunction listener)
+ : listener_(listener) {
+ AddLogMessageListener(listener);
+}
+
+ScopedLogMessageListener::~ScopedLogMessageListener() {
+ RemoveLogMessageListener(listener_);
+}
+
LoggingSettings::LoggingSettings()
: logging_dest(LOG_DEFAULT),
log_file(nullptr),
@@ -409,7 +427,9 @@ bool ShouldCreateLogMessage(int severity) {
// Return true here unless we know ~LogMessage won't do anything. Note that
// ~LogMessage writes to stderr if severity_ >= kAlwaysPrintErrorLevel, even
// when g_logging_destination is LOG_NONE.
- return g_logging_destination != LOG_NONE || log_message_handler ||
+ return g_logging_destination != LOG_NONE ||
+ !log_message_handlers.Get().empty() ||
+ !log_message_listeners.Get().empty() ||
severity >= kAlwaysPrintErrorLevel;
}
@@ -443,12 +463,27 @@ void SetLogAssertHandler(LogAssertHandlerFunction handler) {
log_assert_handler = handler;
}
-void SetLogMessageHandler(LogMessageHandlerFunction handler) {
- log_message_handler = handler;
+void PushLogMessageHandler(LogMessageHandlerFunction handler) {
+ log_message_handlers.Get().push_front(handler);
+}
+
+void PopLogMessageHandler(LogMessageHandlerFunction expected) {
+ CHECK_EQ(GetTopLogMessageHandler(), expected);
+ log_message_handlers.Get().pop_front();
+}
+
+LogMessageHandlerFunction GetTopLogMessageHandler() {
+ if (log_message_handlers.Get().empty())
+ return nullptr;
+ return log_message_handlers.Get().front();
}
-LogMessageHandlerFunction GetLogMessageHandler() {
- return log_message_handler;
+void AddLogMessageListener(LogMessageListenerFunction listener) {
+ log_message_listeners.Get().insert(listener);
+}
+
+void RemoveLogMessageListener(LogMessageListenerFunction listener) {
+ CHECK_EQ(1u, log_message_listeners.Get().erase(listener));
}
// Explicit instantiations for commonly used comparisons.
@@ -537,12 +572,17 @@ LogMessage::~LogMessage() {
stream_ << std::endl;
std::string str_newline(stream_.str());
- // Give any log message handler first dibs on the message.
- if (log_message_handler &&
- log_message_handler(severity_, file_, line_,
- message_start_, str_newline)) {
- // The handler took care of it, no further processing.
- return;
+ // Broadcast to log message listeners first.
+ for (auto* listeners : log_message_listeners.Get()) {
+ listeners(severity_, file_, line_, message_start_, str_newline);
+ }
+
+ // Give log message handlers first dibs on the message.
+ for (auto* handler : log_message_handlers.Get()) {
+ if (handler(severity_, file_, line_, message_start_, str_newline)) {
+ // The handler took care of it, no further processing.
+ return;
+ }
}
if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) {

Powered by Google App Engine
This is Rietveld 408576698