logging.h revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_LOGGING_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_LOGGING_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cassert>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/debugger.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Optional message capabilities
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertion failed messages and fatal errors are displayed in a dialog box
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// before the application exits. However, running this UI creates a message
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// loop, which causes application messages to be processed and potentially
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dispatched to existing application windows. Since the application is in a
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bad state when this assertion dialog is displayed, these messages may not
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// get processed and hang the dialog, or the application might go crazy.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Therefore, it can be beneficial to display the error dialog in a separate
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// process from the main application. When the logging system needs to display
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a fatal error dialog box, it will look for a program called
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "DebugMessage.exe" in the same directory as the application executable. It
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will run this application with the message as the command line, and will
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not include the name of the application as is traditional for easier
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// parsing.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The code for DebugMessage.exe is only one line. In WinMain, do:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   MessageBox(NULL, GetCommandLineW(), L"Fatal Error", 0);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If DebugMessage.exe is not found, the logging code will use a normal
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageBox, potentially causing the problems discussed above.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instructions
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make a bunch of macros for logging.  The way to log things is to stream
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// things to LOG(<a particular severity level>).  E.g.,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   LOG(INFO) << "Found " << num_cookies << " cookies";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You can also do conditional logging:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The CHECK(condition) macro is active in both debug and release builds and
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// effectively performs a LOG(FATAL) which terminates the process and
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// generates a crashdump unless a debugger is attached.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are also "debug mode" logging macros like the ones above:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DLOG(INFO) << "Found cookies";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All "debug mode" logging is compiled away to nothing for non-debug mode
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compiles.  LOG_IF and development flags also work well together
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// because the code can be compiled away sometimes.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We also have
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   LOG_ASSERT(assertion);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DLOG_ASSERT(assertion);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are "verbose level" logging macros.  They look like
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   VLOG(1) << "I'm printed when you run the program with --v=1 or more";
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   VLOG(2) << "I'm printed when you run the program with --v=2 or more";
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These always log at the INFO log level (when they log at all).
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The verbose logging can also be turned on module-by-module.  For instance,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//    --vmodule=profile=2,icon_loader=1,browser_*=3,*/chromeos/*=4 --v=0
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will cause:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   a. VLOG(2) and lower messages to be printed from profile.{h,cc}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   b. VLOG(1) and lower messages to be printed from icon_loader.{h,cc}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   c. VLOG(3) and lower messages to be printed from files prefixed with
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      "browser"
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   d. VLOG(4) and lower messages to be printed from files under a
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     "chromeos" directory.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   e. VLOG(0) and lower messages to be printed from elsewhere
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The wildcarding functionality shown by (c) supports both '*' (match
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 0 or more characters) and '?' (match any single character)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// wildcards.  Any pattern containing a forward or backward slash will
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be tested against the whole pathname and not just the module.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// E.g., "*/foo/bar/*=2" would change the logging level for all code
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in source files under a "foo/bar" directory.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   if (VLOG_IS_ON(2)) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     // do some logging preparation and logging
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     // that can't be accomplished with just VLOG(2) << ...;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is also a VLOG_IF "verbose level" condition macro for sample
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cases, when some extra computation and preparation for logs is not
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// needed.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   VLOG_IF(1, (size > 1024))
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//      << "I'm printed when size is more than 1024 and when you run the "
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//         "program with --v=1 or more";
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We also override the standard 'assert' to use 'DLOG_ASSERT'.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Lastly, there is:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   PLOG(ERROR) << "Couldn't do foo";
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DPLOG(ERROR) << "Couldn't do foo";
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   PLOG_IF(ERROR, cond) << "Couldn't do foo";
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DPLOG_IF(ERROR, cond) << "Couldn't do foo";
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   PCHECK(condition) << "Couldn't do foo";
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DPCHECK(condition) << "Couldn't do foo";
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which append the last system error to the message in string form (taken from
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetLastError() on Windows and errno on POSIX).
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The supported severity levels for macros that allow you to specify one
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are (in increasing order of severity) INFO, WARNING, ERROR, ERROR_REPORT,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and FATAL.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Very important: logging a message at the FATAL severity level causes
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the program to terminate (after the message is logged).
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note the special severity of ERROR_REPORT only available/relevant in normal
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mode, which displays error dialog without terminating the program. There is
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// no error dialog for severity ERROR or below in normal mode.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is also the special severity of DFATAL, which logs FATAL in
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// debug mode, ERROR in normal mode.
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace logging {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(avi): do we want to do a unification of character types here?
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef wchar_t PathChar;
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef char PathChar;
150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Where to record logging output? A flat file and/or system debug log
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// via OutputDebugString.
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochenum LoggingDestination {
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_NONE                = 0,
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_TO_FILE             = 1 << 0,
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_TO_SYSTEM_DEBUG_LOG = 1 << 1,
158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_TO_ALL = LOG_TO_FILE | LOG_TO_SYSTEM_DEBUG_LOG,
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // On Windows, use a file next to the exe; on POSIX platforms, where
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // it may not even be possible to locate the executable on disk, use
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // stderr.
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_DEFAULT = LOG_TO_FILE,
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#elif defined(OS_POSIX)
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_DEFAULT = LOG_TO_SYSTEM_DEBUG_LOG,
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicates that the log file should be locked when being written to.
172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Unless there is only one single-threaded process that is logging to
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// the log file, the file should be locked during writes to make each
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// log output atomic. Other writers will block.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All processes writing to the log file must have their locking set for it to
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// work properly. Defaults to LOCK_LOG_FILE.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum LogLockingState { LOCK_LOG_FILE, DONT_LOCK_LOG_FILE };
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On startup, should we delete or append to an existing log file (if any)?
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defaults to APPEND_TO_OLD_LOG_FILE.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum OldFileDeletionState { DELETE_OLD_LOG_FILE, APPEND_TO_OLD_LOG_FILE };
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct BASE_EXPORT LoggingSettings {
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The defaults values are:
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  logging_dest: LOG_DEFAULT
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  log_file:     NULL
189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  lock_log:     LOCK_LOG_FILE
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  delete_old:   APPEND_TO_OLD_LOG_FILE
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LoggingSettings();
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LoggingDestination logging_dest;
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The three settings below have an effect only when LOG_TO_FILE is
196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // set in |logging_dest|.
197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const PathChar* log_file;
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LogLockingState lock_log;
199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OldFileDeletionState delete_old;
200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Define different names for the BaseInitLoggingImpl() function depending on
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whether NDEBUG is defined or not so that we'll fail to link if someone tries
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to compile logging.cc with NDEBUG but includes logging.h without defining it,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or vice versa.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NDEBUG
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BaseInitLoggingImpl BaseInitLoggingImpl_built_with_NDEBUG
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BaseInitLoggingImpl BaseInitLoggingImpl_built_without_NDEBUG
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation of the InitLogging() method declared below.  We use a
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// more-specific name so we can #define it above without affecting other code
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that has named stuff "InitLogging".
215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochBASE_EXPORT bool BaseInitLoggingImpl(const LoggingSettings& settings);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the log file name and other global logging state. Calling this function
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is recommended, and is normally done at the beginning of application init.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If you don't call it, all the flags will be initialized to their default
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values, and there is a race condition that may leak a critical section
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object if two threads try to do the first log at the same time.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See the definition of the enums above for descriptions and default values.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default log file is initialized to "debug.log" in the application
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directory. You probably don't want this, especially since the program
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directory may not be writable on an enduser's system.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function may be called a second time to re-direct logging (e.g after
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// loging in to a user partition), however it should never be called more than
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// twice.
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochinline bool InitLogging(const LoggingSettings& settings) {
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return BaseInitLoggingImpl(settings);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the log level. Anything at or above this level will be written to the
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// log file/displayed to the user (if applicable). Anything below this level
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will be silently ignored. The log level defaults to 0 (everything is logged
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// up to level INFO) if this function is not called.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that log messages for VLOG(x) are logged at level -x, so setting
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the min log level to negative values enables verbose logging.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetMinLogLevel(int level);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the current log level.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT int GetMinLogLevel();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the VLOG default verbosity level.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT int GetVlogVerbosity();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the current vlog level for the given file (usually taken from
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// __FILE__).
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that |N| is the size *with* the null terminator.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT int GetVlogLevelHelper(const char* file_start, size_t N);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <size_t N>
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetVlogLevel(const char (&file)[N]) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetVlogLevelHelper(file, N);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the common items you want to be prepended to each log message.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// process and thread IDs default to off, the timestamp defaults to on.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If this function is not called, logging defaults to writing the timestamp
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// only.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetLogItems(bool enable_process_id, bool enable_thread_id,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool enable_timestamp, bool enable_tickcount);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets whether or not you'd like to see fatal debug messages popped up in
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a dialog box or not.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Dialogs are not shown by default.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetShowErrorDialogs(bool enable_dialogs);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the Log Assert Handler that will be used to notify of check failures.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default handler shows a dialog box and then terminate the process,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// however clients can use this function to override with their own handling
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (e.g. a silent one for Unit Tests)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef void (*LogAssertHandlerFunction)(const std::string& str);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetLogAssertHandler(LogAssertHandlerFunction handler);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the Log Report Handler that will be used to notify of check failures
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in non-debug mode. The default handler shows a dialog box and continues
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the execution, however clients can use this function to override with their
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// own handling.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef void (*LogReportHandlerFunction)(const std::string& str);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetLogReportHandler(LogReportHandlerFunction handler);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the Log Message Handler that gets passed every log message before
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it's sent to other log destinations (if any).
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true to signal that it handled the message and the message
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should not be sent to other log destinations.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef bool (*LogMessageHandlerFunction)(int severity,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* file, int line, size_t message_start, const std::string& str);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetLogMessageHandler(LogMessageHandlerFunction handler);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT LogMessageHandlerFunction GetLogMessageHandler();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int LogSeverity;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_VERBOSE = -1;  // This is level 1 verbosity
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: the log severities are used to index into the array of names,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// see log_severity_names.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_INFO = 0;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_WARNING = 1;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_ERROR = 2;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_ERROR_REPORT = 3;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_FATAL = 4;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_NUM_SEVERITIES = 5;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LOG_DFATAL is LOG_FATAL in debug mode, ERROR in normal mode
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_DFATAL = LOG_ERROR;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_DFATAL = LOG_FATAL;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A few definitions of macros that don't generate much code. These are used
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by LOG() and LOG_IF, etc. Since these are used all over our code, it's
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// better to have compact code for these operations.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_INFO(ClassName, ...) \
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_INFO , ##__VA_ARGS__)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_WARNING(ClassName, ...) \
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_WARNING , ##__VA_ARGS__)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_ERROR(ClassName, ...) \
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_ERROR , ##__VA_ARGS__)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_ERROR_REPORT(ClassName, ...) \
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, \
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     logging::LOG_ERROR_REPORT , ##__VA_ARGS__)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ...) \
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_FATAL , ##__VA_ARGS__)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_DFATAL(ClassName, ...) \
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_DFATAL , ##__VA_ARGS__)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_INFO \
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_INFO(LogMessage)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_WARNING \
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_WARNING(LogMessage)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_ERROR \
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ERROR(LogMessage)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_ERROR_REPORT \
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ERROR_REPORT(LogMessage)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_FATAL \
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_FATAL(LogMessage)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_DFATAL \
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_DFATAL(LogMessage)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to keep using this syntax, we define this macro to do the same thing
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as COMPACT_GOOGLE_LOG_ERROR, and also define ERROR the same way that
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the Windows SDK does for consistency.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ERROR 0
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_0(ClassName, ...) \
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ERROR(ClassName , ##__VA_ARGS__)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Needed for LOG_IS_ON(ERROR).
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_0 = LOG_ERROR;
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// As special cases, we can assume that LOG_IS_ON(ERROR_REPORT) and
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LOG_IS_ON(FATAL) always hold.  Also, LOG_IS_ON(DFATAL) always holds
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in debug mode.  In particular, CHECK()s will always fire if they
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fail.
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_IS_ON(severity) \
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ((::logging::LOG_ ## severity) >= ::logging::GetMinLogLevel())
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We can't do any caching tricks with VLOG_IS_ON() like the
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// google-glog version since it requires GCC extensions.  This means
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that using the v-logging functions in conjunction with --vmodule
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// may be slow.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG_IS_ON(verboselevel) \
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ((verboselevel) <= ::logging::GetVlogLevel(__FILE__))
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macro which avoids evaluating the arguments to a stream if
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the condition doesn't hold.
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LAZY_STREAM(stream, condition)                                  \
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use the preprocessor's merging operator, "##", so that, e.g.,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LOG(INFO) becomes the token COMPACT_GOOGLE_LOG_INFO.  There's some funny
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subtle difference between ostream member streaming functions (e.g.,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ostream::operator<<(int) and ostream non-member streaming functions
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (e.g., ::operator<<(ostream&, string&): it turns out that it's
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// impossible to stream something like a string directly to an unnamed
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ostream. We employ a neat hack by calling the stream() member
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function of LogMessage which seems to avoid the problem.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_STREAM(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG(severity) LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_IF(severity, condition) \
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYSLOG(severity) LOG(severity)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYSLOG_IF(severity, condition) LOG_IF(severity, condition)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The VLOG macros log with negative verbosities.
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG_STREAM(verbose_level) \
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::LogMessage(__FILE__, __LINE__, -verbose_level).stream()
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG(verbose_level) \
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(VLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level))
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG_IF(verbose_level, condition) \
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(VLOG_STREAM(verbose_level), \
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG_IS_ON(verbose_level) && (condition))
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined (OS_WIN)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VPLOG_STREAM(verbose_level) \
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::Win32ErrorLogMessage(__FILE__, __LINE__, -verbose_level, \
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::logging::GetLastSystemErrorCode()).stream()
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VPLOG_STREAM(verbose_level) \
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ErrnoLogMessage(__FILE__, __LINE__, -verbose_level, \
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::logging::GetLastSystemErrorCode()).stream()
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VPLOG(verbose_level) \
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(VPLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level))
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VPLOG_IF(verbose_level, condition) \
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(VPLOG_STREAM(verbose_level), \
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG_IS_ON(verbose_level) && (condition))
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(akalin): Add more VLOG variants, e.g. VPLOG.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_ASSERT(condition)  \
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYSLOG_ASSERT(condition) \
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_GETLASTERROR_STREAM(severity) \
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::logging::GetLastSystemErrorCode()).stream()
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_GETLASTERROR(severity) \
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity), LOG_IS_ON(severity))
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_GETLASTERROR_MODULE_STREAM(severity, module) \
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::logging::GetLastSystemErrorCode(), module).stream()
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_GETLASTERROR_MODULE(severity, module)                       \
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity, module),                \
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              LOG_IS_ON(severity))
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PLOG_STREAM is used by PLOG, which is the usual error logging macro
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for each platform.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PLOG_STREAM(severity) LOG_GETLASTERROR_STREAM(severity)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_ERRNO_STREAM(severity) \
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ ## severity(ErrnoLogMessage, \
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::logging::GetLastSystemErrorCode()).stream()
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_ERRNO(severity) \
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_ERRNO_STREAM(severity), LOG_IS_ON(severity))
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PLOG_STREAM is used by PLOG, which is the usual error logging macro
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for each platform.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PLOG_STREAM(severity) LOG_ERRNO_STREAM(severity)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PLOG(severity)                                          \
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity))
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PLOG_IF(severity, condition) \
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The actual stream used isn't important.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EAT_STREAM_PARAMETERS                                           \
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  true ? (void) 0 : ::logging::LogMessageVoidify() & LOG_STREAM(FATAL)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CHECK dies with a fatal error if condition is not true.  It is *not*
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// controlled by NDEBUG, so the check will be executed regardless of
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compilation mode.
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We make sure CHECK et al. always evaluates their arguments, as
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doing CHECK(FunctionWithSideEffect()) is a common idiom.
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OFFICIAL_BUILD) && defined(NDEBUG)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make all CHECK functions discard their log strings to reduce code
474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// bloat for official release builds.
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(akalin): This would be more valuable if there were some way to
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// remove BreakDebugger() from the backtrace, perhaps by turning it
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// into a macro (like __debugbreak() on Windows).
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK(condition)                                                \
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  !(condition) ? ::base::debug::BreakDebugger() : EAT_STREAM_PARAMETERS
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PCHECK(condition) CHECK(condition)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_OP(name, op, val1, val2) CHECK((val1) op (val2))
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK(condition)                       \
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  << "Check failed: " #condition ". "
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PCHECK(condition) \
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  << "Check failed: " #condition ". "
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macro for binary operators.
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Don't use this macro directly in your code, use CHECK_EQ et al below.
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(akalin): Rewrite this so that constructs like if (...)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CHECK_EQ(...) else { ... } work properly.
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_OP(name, op, val1, val2)                          \
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (std::string* _result =                                    \
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logging::Check##name##Impl((val1), (val2),                \
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 #val1 " " #op " " #val2))      \
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logging::LogMessage(__FILE__, __LINE__, _result).stream()
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Build the error message string.  This is separate from the "Impl"
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function template because it is not performance critical and so can
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be out of line, while the "Impl" code should be inline.  Caller
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// takes ownership of the returned string.
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class t1, class t2>
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostringstream ss;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ss << names << " (" << v1 << " vs. " << v2 << ")";
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string* msg = new std::string(ss.str());
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return msg;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC doesn't like complex extern templates and DLLs.
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(COMPILER_MSVC)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in logging.cc.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT std::string* MakeCheckOpString<int, int>(
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int&, const int&, const char* names);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString<unsigned long, unsigned long>(
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned long&, const unsigned long&, const char* names);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString<unsigned long, unsigned int>(
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned long&, const unsigned int&, const char* names);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString<unsigned int, unsigned long>(
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned int&, const unsigned long&, const char* names);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString<std::string, std::string>(
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string&, const std::string&, const char* name);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions for CHECK_OP macro.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The (int, int) specialization works around the issue that the compiler
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will not instantiate the template version of the function on values of
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unnamed enum type - see comment below.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEFINE_CHECK_OP_IMPL(name, op) \
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class t1, class t2> \
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const char* names) { \
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (v1 op v2) return NULL; \
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else return MakeCheckOpString(v1, v2, names); \
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } \
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (v1 op v2) return NULL; \
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else return MakeCheckOpString(v1, v2, names); \
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(EQ, ==)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(NE, !=)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(LE, <=)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(LT, < )
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(GE, >=)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(GT, > )
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef DEFINE_CHECK_OP_IMPL
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_EQ(val1, val2) CHECK_OP(EQ, ==, val1, val2)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_NE(val1, val2) CHECK_OP(NE, !=, val1, val2)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_LE(val1, val2) CHECK_OP(LE, <=, val1, val2)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_LT(val1, val2) CHECK_OP(LT, < , val1, val2)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(NDEBUG)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ENABLE_DLOG 0
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ENABLE_DLOG 1
575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DCHECK_IS_ON 0
579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else
580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DCHECK_IS_ON 1
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Definitions for DLOG et al.
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if ENABLE_DLOG
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_IS_ON(severity) LOG_IS_ON(severity)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_ASSERT(condition) LOG_ASSERT(condition)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DPLOG_IF(severity, condition) PLOG_IF(severity, condition)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVLOG_IF(verboselevel, condition) VLOG_IF(verboselevel, condition)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVPLOG_IF(verboselevel, condition) VPLOG_IF(verboselevel, condition)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  // ENABLE_DLOG
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If ENABLE_DLOG is off, we want to avoid emitting any references to
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |condition| (which may reference a variable defined only if NDEBUG
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not defined).  Contrast this with DCHECK et al., which has
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different behavior.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_IS_ON(severity) false
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_IF(severity, condition) EAT_STREAM_PARAMETERS
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_ASSERT(condition) EAT_STREAM_PARAMETERS
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DPLOG_IF(severity, condition) EAT_STREAM_PARAMETERS
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVPLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // ENABLE_DLOG
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DEBUG_MODE is for uses like
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   if (DEBUG_MODE) foo.CheckThatFoo();
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead of
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   #ifndef NDEBUG
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     foo.CheckThatFoo();
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   #endif
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We tie its state to ENABLE_DLOG.
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { DEBUG_MODE = ENABLE_DLOG };
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ENABLE_DLOG
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG(severity)                                          \
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity))
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_GETLASTERROR(severity) \
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity), DLOG_IS_ON(severity))
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_GETLASTERROR_MODULE(severity, module)                      \
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_GETLASTERROR_STREAM(severity, module),                \
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              DLOG_IS_ON(severity))
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_ERRNO(severity)                                    \
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_ERRNO_STREAM(severity), DLOG_IS_ON(severity))
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DPLOG(severity)                                         \
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(severity), DLOG_IS_ON(severity))
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVLOG(verboselevel) DVLOG_IF(verboselevel, VLOG_IS_ON(verboselevel))
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVPLOG(verboselevel) DVPLOG_IF(verboselevel, VLOG_IS_ON(verboselevel))
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Definitions for DCHECK et al.
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if DCHECK_IS_ON
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_FATAL(ClassName , ##__VA_ARGS__)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_FATAL
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_DCHECK = LOG_FATAL;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else  // DCHECK_IS_ON
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// These are just dummy values.
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_INFO(ClassName , ##__VA_ARGS__)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_INFO
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_DCHECK = LOG_INFO;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // DCHECK_IS_ON
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DCHECK et al. make sure to reference |condition| regardless of
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whether DCHECKs are enabled; this is so that we don't get unused
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// variable warnings if the only use of a variable is in a DCHECK.
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This behavior is different from DLOG_IF et al.
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DCHECK(condition)                                         \
668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON && !(condition))   \
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  << "Check failed: " #condition ". "
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DPCHECK(condition)                                        \
672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON && !(condition))  \
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  << "Check failed: " #condition ". "
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macro for binary operators.
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Don't use this macro directly in your code, use DCHECK_EQ et al below.
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_OP(name, op, val1, val2)                         \
678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (DCHECK_IS_ON)                                             \
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (std::string* _result =                                  \
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        logging::Check##name##Impl((val1), (val2),              \
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   #val1 " " #op " " #val2))    \
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logging::LogMessage(                                      \
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          __FILE__, __LINE__, ::logging::LOG_DCHECK,            \
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          _result).stream()
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Equality/Inequality checks - compare two values, and log a
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LOG_DCHECK message including the two values when the result is not
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as expected.  The values must have operator<<(ostream, ...)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// defined.
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You may append to the error message like so:
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DCHECK_NE(1, 2) << ": The world must be ending!";
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We are very careful to ensure that each argument is evaluated exactly
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once, and that anything which is legal to pass as a function argument is
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// legal here.  In particular, the arguments may be temporary expressions
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which will end up being destroyed at the end of the apparent statement,
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for example:
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DCHECK_EQ(string("abc")[1], 'b');
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WARNING: These may not compile correctly if one of the arguments is a pointer
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and the other is NULL. To work around this, simply static_cast NULL to the
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type of the desired pointer.
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_EQ(val1, val2) DCHECK_OP(EQ, ==, val1, val2)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_NE(val1, val2) DCHECK_OP(NE, !=, val1, val2)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_LE(val1, val2) DCHECK_OP(LE, <=, val1, val2)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_LT(val1, val2) DCHECK_OP(LT, < , val1, val2)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(NDEBUG) && defined(OS_CHROMEOS)
71368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define NOTREACHED() LOG(ERROR) << "NOTREACHED() hit in " << \
71468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    __FUNCTION__ << ". "
71568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTREACHED() DCHECK(false)
71768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redefine the standard assert to use our nice log files
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef assert
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define assert(x) DLOG_ASSERT(x)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class more or less represents a particular log message.  You
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// create an instance of LogMessage and then stream stuff to it.
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When you finish streaming to it, ~LogMessage is called and the
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// full message gets streamed to the appropriate destination.
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You shouldn't actually use LogMessage's constructor to log things,
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// though.  You should use the LOG() macro (and variants thereof)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// above.
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT LogMessage {
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(const char* file, int line, LogSeverity severity, int ctr);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Two special constructors that generate reduced amounts of code at
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // LOG call sites for common cases.
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used for LOG(INFO): Implied are:
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // severity = LOG_INFO, ctr = 0
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Using this constructor instead of the more complex constructor above
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // saves a couple of bytes per call site.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(const char* file, int line);
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used for LOG(severity) where severity != INFO.  Implied
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are: ctr = 0
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Using this constructor instead of the more complex constructor above
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // saves a couple of bytes per call site.
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(const char* file, int line, LogSeverity severity);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A special constructor used for check failures.  Takes ownership
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the given string.
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implied severity = LOG_FATAL
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(const char* file, int line, std::string* result);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A special constructor used for check failures, with the option to
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specify severity.  Takes ownership of the given string.
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(const char* file, int line, LogSeverity severity,
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             std::string* result);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~LogMessage();
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostream& stream() { return stream_; }
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init(const char* file, int line);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogSeverity severity_;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostringstream stream_;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t message_start_;  // Offset of the start of the message (past prefix
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // info).
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The file and line information passed in to the constructor.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* file_;
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int line_;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stores the current value of GetLastError in the constructor and restores
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it in the destructor by calling SetLastError.
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is useful since the LogMessage class uses a lot of Win32 calls
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that will lose the value of GLE and the code that called the log function
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will have lost the thread error value when the log call returns.
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class SaveLastError {
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SaveLastError();
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~SaveLastError();
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long get_error() const { return last_error_; }
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long last_error_;
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SaveLastError last_error_;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LogMessage);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A non-macro interface to the log facility; (useful
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when the logging level is not a compile-time constant).
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void LogAtLevel(int const log_level, std::string const &msg) {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(__FILE__, __LINE__, log_level).stream() << msg;
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is used to explicitly ignore values in the conditional
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// logging macros.  This avoids compiler warnings like "value computed
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not used" and "statement has no effect".
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LogMessageVoidify {
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessageVoidify() { }
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This has to be an operator with a precedence lower than << but
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // higher than ?:
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void operator&(std::ostream&) { }
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned long SystemErrorCode;
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int SystemErrorCode;
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alias for ::GetLastError() on Windows and errno on POSIX. Avoids having to
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pull in windows.h just for GetLastError() and DWORD.
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT SystemErrorCode GetLastSystemErrorCode();
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends a formatted system message of the GetLastError() type.
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT Win32ErrorLogMessage {
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Win32ErrorLogMessage(const char* file,
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       int line,
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LogSeverity severity,
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       SystemErrorCode err,
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const char* module);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Win32ErrorLogMessage(const char* file,
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       int line,
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LogSeverity severity,
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       SystemErrorCode err);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Appends the error message before destructing the encapsulated class.
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~Win32ErrorLogMessage();
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostream& stream() { return log_message_.stream(); }
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SystemErrorCode err_;
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Optional name of the module defining the error.
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* module_;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage log_message_;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Win32ErrorLogMessage);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends a formatted system message of the errno type
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT ErrnoLogMessage {
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ErrnoLogMessage(const char* file,
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int line,
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  LogSeverity severity,
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  SystemErrorCode err);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Appends the error message before destructing the encapsulated class.
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ErrnoLogMessage();
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostream& stream() { return log_message_.stream(); }
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SystemErrorCode err_;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage log_message_;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ErrnoLogMessage);
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Closes the log file explicitly if open.
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: Since the log file is opened as necessary by the action of logging
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       statements, there's no guarantee that it will stay closed
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       after this call.
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void CloseLogFile();
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Async signal safe logging mechanism.
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void RawLog(int level, const char* message);
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAW_LOG(level, message) logging::RawLog(logging::LOG_ ## level, message)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAW_CHECK(condition)                                                   \
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {                                                                         \
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(condition))                                                          \
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logging::RawLog(logging::LOG_FATAL, "Check failed: " #condition "\n");   \
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (0)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the default log file path.
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BASE_EXPORT std::wstring GetLogFileFullPath();
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace logging
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These functions are provided as a convenience for logging, which is where we
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// use streams (it is against Google style to use streams in other places). It
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is designed to allow you to emit non-ASCII Unicode strings to the log file,
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which is normally ASCII. It is relatively slow, so try not to use it for
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// common cases. Non-ASCII characters will be converted to UTF-8 by these
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operators.
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return out << wstr.c_str();
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The NOTIMPLEMENTED() macro annotates codepaths which have
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not been implemented yet.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The implementation of this macro is controlled by NOTIMPLEMENTED_POLICY:
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0 -- Do nothing (stripped by compiler)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   1 -- Warn at compile time
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   2 -- Fail at compile time
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   3 -- Fail at runtime (DCHECK)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   4 -- [default] LOG(ERROR) at runtime
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   5 -- LOG(ERROR) at runtime, only once per call-site
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NOTIMPLEMENTED_POLICY
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) && defined(OFFICIAL_BUILD)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED_POLICY 0
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Select default policy: LOG(ERROR)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED_POLICY 4
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(COMPILER_GCC)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Linux, with GCC, we can use __PRETTY_FUNCTION__ to get the demangled name
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the current function in the NOTIMPLEMENTED message.
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED_MSG "Not implemented reached in " << __PRETTY_FUNCTION__
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED_MSG "NOT IMPLEMENTED"
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NOTIMPLEMENTED_POLICY == 0
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() EAT_STREAM_PARAMETERS
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 1
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO, figure out how to generate a warning
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() COMPILE_ASSERT(false, NOT_IMPLEMENTED)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 2
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() COMPILE_ASSERT(false, NOT_IMPLEMENTED)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 3
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() NOTREACHED()
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 4
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() LOG(ERROR) << NOTIMPLEMENTED_MSG
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 5
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() do {\
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool logged_once = false;\
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  logged_once = true;\
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} while(0);\
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)EAT_STREAM_PARAMETERS
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_LOGGING_H_
961