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

Side by Side Diff: base/logging.cc

Issue 2497833002: support multiple log message handlers in base/logging.h (Closed)
Patch Set: Created 4 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « base/logging.h ('k') | base/logging_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/logging.h" 5 #include "base/logging.h"
6 6
7 #include <limits.h> 7 #include <limits.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 typedef FILE* FileHandle; 45 typedef FILE* FileHandle;
46 typedef pthread_mutex_t* MutexHandle; 46 typedef pthread_mutex_t* MutexHandle;
47 #endif 47 #endif
48 48
49 #include <algorithm> 49 #include <algorithm>
50 #include <cstring> 50 #include <cstring>
51 #include <ctime> 51 #include <ctime>
52 #include <iomanip> 52 #include <iomanip>
53 #include <ostream> 53 #include <ostream>
54 #include <string> 54 #include <string>
55 #include <vector>
55 56
56 #include "base/base_switches.h" 57 #include "base/base_switches.h"
57 #include "base/command_line.h" 58 #include "base/command_line.h"
58 #include "base/debug/alias.h" 59 #include "base/debug/alias.h"
59 #include "base/debug/debugger.h" 60 #include "base/debug/debugger.h"
60 #include "base/debug/stack_trace.h" 61 #include "base/debug/stack_trace.h"
61 #include "base/posix/eintr_wrapper.h" 62 #include "base/posix/eintr_wrapper.h"
62 #include "base/strings/string_piece.h" 63 #include "base/strings/string_piece.h"
63 #include "base/strings/string_util.h" 64 #include "base/strings/string_util.h"
64 #include "base/strings/stringprintf.h" 65 #include "base/strings/stringprintf.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 bool g_log_thread_id = false; 117 bool g_log_thread_id = false;
117 bool g_log_timestamp = true; 118 bool g_log_timestamp = true;
118 bool g_log_tickcount = false; 119 bool g_log_tickcount = false;
119 120
120 // Should we pop up fatal debug messages in a dialog? 121 // Should we pop up fatal debug messages in a dialog?
121 bool show_error_dialogs = false; 122 bool show_error_dialogs = false;
122 123
123 // An assert handler override specified by the client to be called instead of 124 // An assert handler override specified by the client to be called instead of
124 // the debug message dialog and process termination. 125 // the debug message dialog and process termination.
125 LogAssertHandlerFunction log_assert_handler = nullptr; 126 LogAssertHandlerFunction log_assert_handler = nullptr;
126 // A log message handler that gets notified of every log message we process. 127 // Log message handlers that get notified of every log message we process.
127 LogMessageHandlerFunction log_message_handler = nullptr; 128 std::vector<LogMessageHandlerFunction>* log_message_handlers = nullptr;
128 129
129 // Helper functions to wrap platform differences. 130 // Helper functions to wrap platform differences.
130 131
131 int32_t CurrentProcessId() { 132 int32_t CurrentProcessId() {
132 #if defined(OS_WIN) 133 #if defined(OS_WIN)
133 return GetCurrentProcessId(); 134 return GetCurrentProcessId();
134 #elif defined(OS_POSIX) 135 #elif defined(OS_POSIX)
135 return getpid(); 136 return getpid();
136 #endif 137 #endif
137 } 138 }
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 return g_min_log_level; 403 return g_min_log_level;
403 } 404 }
404 405
405 bool ShouldCreateLogMessage(int severity) { 406 bool ShouldCreateLogMessage(int severity) {
406 if (severity < g_min_log_level) 407 if (severity < g_min_log_level)
407 return false; 408 return false;
408 409
409 // Return true here unless we know ~LogMessage won't do anything. Note that 410 // Return true here unless we know ~LogMessage won't do anything. Note that
410 // ~LogMessage writes to stderr if severity_ >= kAlwaysPrintErrorLevel, even 411 // ~LogMessage writes to stderr if severity_ >= kAlwaysPrintErrorLevel, even
411 // when g_logging_destination is LOG_NONE. 412 // when g_logging_destination is LOG_NONE.
412 return g_logging_destination != LOG_NONE || log_message_handler || 413 return g_logging_destination != LOG_NONE ||
414 (log_message_handlers && log_message_handlers->size() > 0) ||
413 severity >= kAlwaysPrintErrorLevel; 415 severity >= kAlwaysPrintErrorLevel;
414 } 416 }
415 417
416 int GetVlogVerbosity() { 418 int GetVlogVerbosity() {
417 return std::max(-1, LOG_INFO - GetMinLogLevel()); 419 return std::max(-1, LOG_INFO - GetMinLogLevel());
418 } 420 }
419 421
420 int GetVlogLevelHelper(const char* file, size_t N) { 422 int GetVlogLevelHelper(const char* file, size_t N) {
421 DCHECK_GT(N, 0U); 423 DCHECK_GT(N, 0U);
422 // Note: |g_vlog_info| may change on a different thread during startup 424 // Note: |g_vlog_info| may change on a different thread during startup
(...skipping 13 matching lines...) Expand all
436 } 438 }
437 439
438 void SetShowErrorDialogs(bool enable_dialogs) { 440 void SetShowErrorDialogs(bool enable_dialogs) {
439 show_error_dialogs = enable_dialogs; 441 show_error_dialogs = enable_dialogs;
440 } 442 }
441 443
442 void SetLogAssertHandler(LogAssertHandlerFunction handler) { 444 void SetLogAssertHandler(LogAssertHandlerFunction handler) {
443 log_assert_handler = handler; 445 log_assert_handler = handler;
444 } 446 }
445 447
446 void SetLogMessageHandler(LogMessageHandlerFunction handler) { 448 void AddLogMessageHandler(LogMessageHandlerFunction handler) {
447 log_message_handler = handler; 449 if (!log_message_handlers)
450 log_message_handlers = new std::vector<LogMessageHandlerFunction>;
451 DCHECK_EQ(0, std::count(log_message_handlers->begin(),
452 log_message_handlers->end(), handler));
453 log_message_handlers->push_back(handler);
448 } 454 }
449 455
450 LogMessageHandlerFunction GetLogMessageHandler() { 456 void RemoveLogMessageHandler(LogMessageHandlerFunction handler) {
451 return log_message_handler; 457 if (log_message_handlers) {
458 auto it = std::find(log_message_handlers->begin(),
459 log_message_handlers->end(), handler);
460 if (it != log_message_handlers->end()) {
461 log_message_handlers->erase(it);
462 return;
463 }
464 }
465 NOTREACHED();
452 } 466 }
453 467
454 // Explicit instantiations for commonly used comparisons. 468 // Explicit instantiations for commonly used comparisons.
455 template std::string* MakeCheckOpString<int, int>( 469 template std::string* MakeCheckOpString<int, int>(
456 const int&, const int&, const char* names); 470 const int&, const int&, const char* names);
457 template std::string* MakeCheckOpString<unsigned long, unsigned long>( 471 template std::string* MakeCheckOpString<unsigned long, unsigned long>(
458 const unsigned long&, const unsigned long&, const char* names); 472 const unsigned long&, const unsigned long&, const char* names);
459 template std::string* MakeCheckOpString<unsigned long, unsigned int>( 473 template std::string* MakeCheckOpString<unsigned long, unsigned int>(
460 const unsigned long&, const unsigned int&, const char* names); 474 const unsigned long&, const unsigned int&, const char* names);
461 template std::string* MakeCheckOpString<unsigned int, unsigned long>( 475 template std::string* MakeCheckOpString<unsigned int, unsigned long>(
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 // Include a stack trace on a fatal, unless a debugger is attached. 545 // Include a stack trace on a fatal, unless a debugger is attached.
532 base::debug::StackTrace trace; 546 base::debug::StackTrace trace;
533 stream_ << std::endl; // Newline to separate from log message. 547 stream_ << std::endl; // Newline to separate from log message.
534 trace.OutputToStream(&stream_); 548 trace.OutputToStream(&stream_);
535 } 549 }
536 #endif 550 #endif
537 stream_ << std::endl; 551 stream_ << std::endl;
538 std::string str_newline(stream_.str()); 552 std::string str_newline(stream_.str());
539 553
540 // Give any log message handler first dibs on the message. 554 // Give any log message handler first dibs on the message.
541 if (log_message_handler && 555 if (log_message_handlers) {
542 log_message_handler(severity_, file_, line_, 556 const std::string message = str_newline.substr(message_start_);
543 message_start_, str_newline)) { 557 if (std::count_if(log_message_handlers->begin(),
544 // The handler took care of it, no further processing. 558 log_message_handlers->end(),
545 return; 559 [this, &message](auto handler) {
560 return handler(severity_, file_, line_, message);
561 }) > 0) {
562 // At least one of the handlers took care of it, no further processing.
563 return;
564 }
546 } 565 }
547 566
548 if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) { 567 if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) {
549 #if defined(OS_WIN) 568 #if defined(OS_WIN)
550 OutputDebugStringA(str_newline.c_str()); 569 OutputDebugStringA(str_newline.c_str());
551 #elif defined(OS_MACOSX) 570 #elif defined(OS_MACOSX)
552 // In LOG_TO_SYSTEM_DEBUG_LOG mode, log messages are always written to 571 // In LOG_TO_SYSTEM_DEBUG_LOG mode, log messages are always written to
553 // stderr. If stderr is /dev/null, also log via ASL (Apple System Log). If 572 // stderr. If stderr is /dev/null, also log via ASL (Apple System Log). If
554 // there's something weird about stderr, assume that log messages are going 573 // there's something weird about stderr, assume that log messages are going
555 // nowhere and log via ASL too. Messages logged via ASL show up in 574 // nowhere and log via ASL too. Messages logged via ASL show up in
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 BASE_EXPORT void LogErrorNotReached(const char* file, int line) { 940 BASE_EXPORT void LogErrorNotReached(const char* file, int line) {
922 LogMessage(file, line, LOG_ERROR).stream() 941 LogMessage(file, line, LOG_ERROR).stream()
923 << "NOTREACHED() hit."; 942 << "NOTREACHED() hit.";
924 } 943 }
925 944
926 } // namespace logging 945 } // namespace logging
927 946
928 std::ostream& std::operator<<(std::ostream& out, const wchar_t* wstr) { 947 std::ostream& std::operator<<(std::ostream& out, const wchar_t* wstr) {
929 return out << (wstr ? base::WideToUTF8(wstr) : std::string()); 948 return out << (wstr ? base::WideToUTF8(wstr) : std::string());
930 } 949 }
OLDNEW
« no previous file with comments | « base/logging.h ('k') | base/logging_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698