logging.h revision ee3a239997afef1873d8c812225689a5f134be2e
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
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Very important: logging a message at the FATAL severity level causes
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the program to terminate (after the message is logged).
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// There is the special severity of DFATAL, which logs FATAL in debug mode,
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ERROR in normal mode.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace logging {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// TODO(avi): do we want to do a unification of character types here?
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef wchar_t PathChar;
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef char PathChar;
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Where to record logging output? A flat file and/or system debug log
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// via OutputDebugString.
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochenum LoggingDestination {
150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_NONE                = 0,
151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_TO_FILE             = 1 << 0,
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_TO_SYSTEM_DEBUG_LOG = 1 << 1,
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_TO_ALL = LOG_TO_FILE | LOG_TO_SYSTEM_DEBUG_LOG,
155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // On Windows, use a file next to the exe; on POSIX platforms, where
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // it may not even be possible to locate the executable on disk, use
158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // stderr.
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_DEFAULT = LOG_TO_FILE,
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#elif defined(OS_POSIX)
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LOG_DEFAULT = LOG_TO_SYSTEM_DEBUG_LOG,
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicates that the log file should be locked when being written to.
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Unless there is only one single-threaded process that is logging to
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// the log file, the file should be locked during writes to make each
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// log output atomic. Other writers will block.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All processes writing to the log file must have their locking set for it to
172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// work properly. Defaults to LOCK_LOG_FILE.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum LogLockingState { LOCK_LOG_FILE, DONT_LOCK_LOG_FILE };
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On startup, should we delete or append to an existing log file (if any)?
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defaults to APPEND_TO_OLD_LOG_FILE.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum OldFileDeletionState { DELETE_OLD_LOG_FILE, APPEND_TO_OLD_LOG_FILE };
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstruct BASE_EXPORT LoggingSettings {
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The defaults values are:
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  logging_dest: LOG_DEFAULT
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  log_file:     NULL
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  lock_log:     LOCK_LOG_FILE
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //  delete_old:   APPEND_TO_OLD_LOG_FILE
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LoggingSettings();
187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LoggingDestination logging_dest;
189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The three settings below have an effect only when LOG_TO_FILE is
191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // set in |logging_dest|.
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const PathChar* log_file;
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  LogLockingState lock_log;
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OldFileDeletionState delete_old;
195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Define different names for the BaseInitLoggingImpl() function depending on
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whether NDEBUG is defined or not so that we'll fail to link if someone tries
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to compile logging.cc with NDEBUG but includes logging.h without defining it,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or vice versa.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NDEBUG
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BaseInitLoggingImpl BaseInitLoggingImpl_built_with_NDEBUG
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BaseInitLoggingImpl BaseInitLoggingImpl_built_without_NDEBUG
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation of the InitLogging() method declared below.  We use a
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// more-specific name so we can #define it above without affecting other code
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that has named stuff "InitLogging".
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochBASE_EXPORT bool BaseInitLoggingImpl(const LoggingSettings& settings);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the log file name and other global logging state. Calling this function
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is recommended, and is normally done at the beginning of application init.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If you don't call it, all the flags will be initialized to their default
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values, and there is a race condition that may leak a critical section
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object if two threads try to do the first log at the same time.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See the definition of the enums above for descriptions and default values.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default log file is initialized to "debug.log" in the application
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directory. You probably don't want this, especially since the program
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directory may not be writable on an enduser's system.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function may be called a second time to re-direct logging (e.g after
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// loging in to a user partition), however it should never be called more than
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// twice.
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochinline bool InitLogging(const LoggingSettings& settings) {
227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return BaseInitLoggingImpl(settings);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the log level. Anything at or above this level will be written to the
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// log file/displayed to the user (if applicable). Anything below this level
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will be silently ignored. The log level defaults to 0 (everything is logged
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// up to level INFO) if this function is not called.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that log messages for VLOG(x) are logged at level -x, so setting
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the min log level to negative values enables verbose logging.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetMinLogLevel(int level);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the current log level.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT int GetMinLogLevel();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the VLOG default verbosity level.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT int GetVlogVerbosity();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the current vlog level for the given file (usually taken from
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// __FILE__).
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that |N| is the size *with* the null terminator.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT int GetVlogLevelHelper(const char* file_start, size_t N);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <size_t N>
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetVlogLevel(const char (&file)[N]) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetVlogLevelHelper(file, N);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the common items you want to be prepended to each log message.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// process and thread IDs default to off, the timestamp defaults to on.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If this function is not called, logging defaults to writing the timestamp
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// only.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetLogItems(bool enable_process_id, bool enable_thread_id,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             bool enable_timestamp, bool enable_tickcount);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets whether or not you'd like to see fatal debug messages popped up in
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a dialog box or not.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Dialogs are not shown by default.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetShowErrorDialogs(bool enable_dialogs);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the Log Assert Handler that will be used to notify of check failures.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default handler shows a dialog box and then terminate the process,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// however clients can use this function to override with their own handling
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (e.g. a silent one for Unit Tests)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef void (*LogAssertHandlerFunction)(const std::string& str);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetLogAssertHandler(LogAssertHandlerFunction handler);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the Log Message Handler that gets passed every log message before
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it's sent to other log destinations (if any).
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true to signal that it handled the message and the message
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should not be sent to other log destinations.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef bool (*LogMessageHandlerFunction)(int severity,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* file, int line, size_t message_start, const std::string& str);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void SetLogMessageHandler(LogMessageHandlerFunction handler);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT LogMessageHandlerFunction GetLogMessageHandler();
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int LogSeverity;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_VERBOSE = -1;  // This is level 1 verbosity
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: the log severities are used to index into the array of names,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// see log_severity_names.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_INFO = 0;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_WARNING = 1;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_ERROR = 2;
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const LogSeverity LOG_FATAL = 3;
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const LogSeverity LOG_NUM_SEVERITIES = 4;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LOG_DFATAL is LOG_FATAL in debug mode, ERROR in normal mode
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_DFATAL = LOG_ERROR;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_DFATAL = LOG_FATAL;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A few definitions of macros that don't generate much code. These are used
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// by LOG() and LOG_IF, etc. Since these are used all over our code, it's
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// better to have compact code for these operations.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_INFO(ClassName, ...) \
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_INFO , ##__VA_ARGS__)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_WARNING(ClassName, ...) \
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_WARNING , ##__VA_ARGS__)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_ERROR(ClassName, ...) \
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_ERROR , ##__VA_ARGS__)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_FATAL(ClassName, ...) \
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_FATAL , ##__VA_ARGS__)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_DFATAL(ClassName, ...) \
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ClassName(__FILE__, __LINE__, logging::LOG_DFATAL , ##__VA_ARGS__)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_INFO \
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_INFO(LogMessage)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_WARNING \
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_WARNING(LogMessage)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_ERROR \
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ERROR(LogMessage)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_FATAL \
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_FATAL(LogMessage)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_DFATAL \
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_DFATAL(LogMessage)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to keep using this syntax, we define this macro to do the same thing
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as COMPACT_GOOGLE_LOG_ERROR, and also define ERROR the same way that
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the Windows SDK does for consistency.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ERROR 0
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_0(ClassName, ...) \
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ERROR(ClassName , ##__VA_ARGS__)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Needed for LOG_IS_ON(ERROR).
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_0 = LOG_ERROR;
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// As special cases, we can assume that LOG_IS_ON(FATAL) always holds. Also,
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// LOG_IS_ON(DFATAL) always holds in debug mode. In particular, CHECK()s will
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// always fire if they fail.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_IS_ON(severity) \
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ((::logging::LOG_ ## severity) >= ::logging::GetMinLogLevel())
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We can't do any caching tricks with VLOG_IS_ON() like the
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// google-glog version since it requires GCC extensions.  This means
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that using the v-logging functions in conjunction with --vmodule
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// may be slow.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG_IS_ON(verboselevel) \
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ((verboselevel) <= ::logging::GetVlogLevel(__FILE__))
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macro which avoids evaluating the arguments to a stream if
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the condition doesn't hold.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LAZY_STREAM(stream, condition)                                  \
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use the preprocessor's merging operator, "##", so that, e.g.,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LOG(INFO) becomes the token COMPACT_GOOGLE_LOG_INFO.  There's some funny
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subtle difference between ostream member streaming functions (e.g.,
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ostream::operator<<(int) and ostream non-member streaming functions
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (e.g., ::operator<<(ostream&, string&): it turns out that it's
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// impossible to stream something like a string directly to an unnamed
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ostream. We employ a neat hack by calling the stream() member
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function of LogMessage which seems to avoid the problem.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_STREAM(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG(severity) LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_IF(severity, condition) \
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYSLOG(severity) LOG(severity)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYSLOG_IF(severity, condition) LOG_IF(severity, condition)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The VLOG macros log with negative verbosities.
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG_STREAM(verbose_level) \
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::LogMessage(__FILE__, __LINE__, -verbose_level).stream()
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG(verbose_level) \
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(VLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level))
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VLOG_IF(verbose_level, condition) \
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(VLOG_STREAM(verbose_level), \
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      VLOG_IS_ON(verbose_level) && (condition))
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined (OS_WIN)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VPLOG_STREAM(verbose_level) \
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::Win32ErrorLogMessage(__FILE__, __LINE__, -verbose_level, \
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::logging::GetLastSystemErrorCode()).stream()
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VPLOG_STREAM(verbose_level) \
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::ErrnoLogMessage(__FILE__, __LINE__, -verbose_level, \
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::logging::GetLastSystemErrorCode()).stream()
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VPLOG(verbose_level) \
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(VPLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level))
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VPLOG_IF(verbose_level, condition) \
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(VPLOG_STREAM(verbose_level), \
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG_IS_ON(verbose_level) && (condition))
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(akalin): Add more VLOG variants, e.g. VPLOG.
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOG_ASSERT(condition)  \
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SYSLOG_ASSERT(condition) \
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". "
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#define PLOG_STREAM(severity) \
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ ## severity(Win32ErrorLogMessage, \
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::logging::GetLastSystemErrorCode()).stream()
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
4140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#define PLOG_STREAM(severity) \
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_ ## severity(ErrnoLogMessage, \
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::logging::GetLastSystemErrorCode()).stream()
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PLOG(severity)                                          \
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity))
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PLOG_IF(severity, condition) \
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(severity), LOG_IS_ON(severity) && (condition))
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The actual stream used isn't important.
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EAT_STREAM_PARAMETERS                                           \
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  true ? (void) 0 : ::logging::LogMessageVoidify() & LOG_STREAM(FATAL)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CHECK dies with a fatal error if condition is not true.  It is *not*
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// controlled by NDEBUG, so the check will be executed regardless of
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// compilation mode.
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We make sure CHECK et al. always evaluates their arguments, as
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doing CHECK(FunctionWithSideEffect()) is a common idiom.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(OFFICIAL_BUILD) && defined(NDEBUG) && !defined(OS_ANDROID)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make all CHECK functions discard their log strings to reduce code
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// bloat for official release builds.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(akalin): This would be more valuable if there were some way to
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// remove BreakDebugger() from the backtrace, perhaps by turning it
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// into a macro (like __debugbreak() on Windows).
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK(condition)                                                \
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  !(condition) ? ::base::debug::BreakDebugger() : EAT_STREAM_PARAMETERS
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PCHECK(condition) CHECK(condition)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_OP(name, op, val1, val2) CHECK((val1) op (val2))
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK(condition)                       \
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_STREAM(FATAL), !(condition)) \
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  << "Check failed: " #condition ". "
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PCHECK(condition) \
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(FATAL), !(condition)) \
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  << "Check failed: " #condition ". "
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macro for binary operators.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Don't use this macro directly in your code, use CHECK_EQ et al below.
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(akalin): Rewrite this so that constructs like if (...)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CHECK_EQ(...) else { ... } work properly.
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_OP(name, op, val1, val2)                          \
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (std::string* _result =                                    \
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logging::Check##name##Impl((val1), (val2),                \
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 #val1 " " #op " " #val2))      \
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logging::LogMessage(__FILE__, __LINE__, _result).stream()
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Build the error message string.  This is separate from the "Impl"
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function template because it is not performance critical and so can
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be out of line, while the "Impl" code should be inline.  Caller
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// takes ownership of the returned string.
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class t1, class t2>
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostringstream ss;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ss << names << " (" << v1 << " vs. " << v2 << ")";
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string* msg = new std::string(ss.str());
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return msg;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC doesn't like complex extern templates and DLLs.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(COMPILER_MSVC)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Commonly used instantiations of MakeCheckOpString<>. Explicitly instantiated
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in logging.cc.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT std::string* MakeCheckOpString<int, int>(
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int&, const int&, const char* names);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString<unsigned long, unsigned long>(
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned long&, const unsigned long&, const char* names);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString<unsigned long, unsigned int>(
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned long&, const unsigned int&, const char* names);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString<unsigned int, unsigned long>(
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned int&, const unsigned long&, const char* names);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template BASE_EXPORT
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string* MakeCheckOpString<std::string, std::string>(
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string&, const std::string&, const char* name);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions for CHECK_OP macro.
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The (int, int) specialization works around the issue that the compiler
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will not instantiate the template version of the function on values of
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unnamed enum type - see comment below.
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEFINE_CHECK_OP_IMPL(name, op) \
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class t1, class t2> \
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const char* names) { \
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (v1 op v2) return NULL; \
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else return MakeCheckOpString(v1, v2, names); \
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } \
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (v1 op v2) return NULL; \
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else return MakeCheckOpString(v1, v2, names); \
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(EQ, ==)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(NE, !=)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(LE, <=)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(LT, < )
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(GE, >=)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_CHECK_OP_IMPL(GT, > )
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef DEFINE_CHECK_OP_IMPL
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_EQ(val1, val2) CHECK_OP(EQ, ==, val1, val2)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_NE(val1, val2) CHECK_OP(NE, !=, val1, val2)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_LE(val1, val2) CHECK_OP(LE, <=, val1, val2)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_LT(val1, val2) CHECK_OP(LT, < , val1, val2)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_GE(val1, val2) CHECK_OP(GE, >=, val1, val2)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHECK_GT(val1, val2) CHECK_OP(GT, > , val1, val2)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(NDEBUG)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ENABLE_DLOG 0
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ENABLE_DLOG 1
540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DCHECK_IS_ON 0
544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DCHECK_IS_ON 1
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Definitions for DLOG et al.
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if ENABLE_DLOG
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_IS_ON(severity) LOG_IS_ON(severity)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_ASSERT(condition) LOG_ASSERT(condition)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DPLOG_IF(severity, condition) PLOG_IF(severity, condition)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVLOG_IF(verboselevel, condition) VLOG_IF(verboselevel, condition)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVPLOG_IF(verboselevel, condition) VPLOG_IF(verboselevel, condition)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else  // ENABLE_DLOG
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If ENABLE_DLOG is off, we want to avoid emitting any references to
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |condition| (which may reference a variable defined only if NDEBUG
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not defined).  Contrast this with DCHECK et al., which has
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different behavior.
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_IS_ON(severity) false
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_IF(severity, condition) EAT_STREAM_PARAMETERS
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG_ASSERT(condition) EAT_STREAM_PARAMETERS
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DPLOG_IF(severity, condition) EAT_STREAM_PARAMETERS
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVPLOG_IF(verboselevel, condition) EAT_STREAM_PARAMETERS
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // ENABLE_DLOG
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DEBUG_MODE is for uses like
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   if (DEBUG_MODE) foo.CheckThatFoo();
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead of
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   #ifndef NDEBUG
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     foo.CheckThatFoo();
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   #endif
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We tie its state to ENABLE_DLOG.
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { DEBUG_MODE = ENABLE_DLOG };
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ENABLE_DLOG
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DLOG(severity)                                          \
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(LOG_STREAM(severity), DLOG_IS_ON(severity))
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DPLOG(severity)                                         \
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(severity), DLOG_IS_ON(severity))
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVLOG(verboselevel) DVLOG_IF(verboselevel, VLOG_IS_ON(verboselevel))
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DVPLOG(verboselevel) DVPLOG_IF(verboselevel, VLOG_IS_ON(verboselevel))
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Definitions for DCHECK et al.
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if DCHECK_IS_ON
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_FATAL(ClassName , ##__VA_ARGS__)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_FATAL
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_DCHECK = LOG_FATAL;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else  // DCHECK_IS_ON
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// These are just dummy values.
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_EX_DCHECK(ClassName, ...) \
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPACT_GOOGLE_LOG_EX_INFO(ClassName , ##__VA_ARGS__)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define COMPACT_GOOGLE_LOG_DCHECK COMPACT_GOOGLE_LOG_INFO
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LogSeverity LOG_DCHECK = LOG_INFO;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // DCHECK_IS_ON
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DCHECK et al. make sure to reference |condition| regardless of
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whether DCHECKs are enabled; this is so that we don't get unused
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// variable warnings if the only use of a variable is in a DCHECK.
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This behavior is different from DLOG_IF et al.
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DCHECK(condition)                                         \
622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON && !(condition))   \
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  << "Check failed: " #condition ". "
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define DPCHECK(condition)                                        \
626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  LAZY_STREAM(PLOG_STREAM(DCHECK), DCHECK_IS_ON && !(condition))  \
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  << "Check failed: " #condition ". "
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macro for binary operators.
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Don't use this macro directly in your code, use DCHECK_EQ et al below.
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_OP(name, op, val1, val2)                         \
632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (DCHECK_IS_ON)                                             \
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (std::string* _result =                                  \
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        logging::Check##name##Impl((val1), (val2),              \
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   #val1 " " #op " " #val2))    \
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logging::LogMessage(                                      \
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          __FILE__, __LINE__, ::logging::LOG_DCHECK,            \
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          _result).stream()
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Equality/Inequality checks - compare two values, and log a
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LOG_DCHECK message including the two values when the result is not
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// as expected.  The values must have operator<<(ostream, ...)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// defined.
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You may append to the error message like so:
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DCHECK_NE(1, 2) << ": The world must be ending!";
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We are very careful to ensure that each argument is evaluated exactly
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once, and that anything which is legal to pass as a function argument is
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// legal here.  In particular, the arguments may be temporary expressions
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which will end up being destroyed at the end of the apparent statement,
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for example:
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   DCHECK_EQ(string("abc")[1], 'b');
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WARNING: These may not compile correctly if one of the arguments is a pointer
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and the other is NULL. To work around this, simply static_cast NULL to the
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// type of the desired pointer.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_EQ(val1, val2) DCHECK_OP(EQ, ==, val1, val2)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_NE(val1, val2) DCHECK_OP(NE, !=, val1, val2)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_LE(val1, val2) DCHECK_OP(LE, <=, val1, val2)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_LT(val1, val2) DCHECK_OP(LT, < , val1, val2)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(NDEBUG) && defined(OS_CHROMEOS)
66768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#define NOTREACHED() LOG(ERROR) << "NOTREACHED() hit in " << \
66868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    __FUNCTION__ << ". "
66968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTREACHED() DCHECK(false)
67168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redefine the standard assert to use our nice log files
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef assert
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define assert(x) DLOG_ASSERT(x)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class more or less represents a particular log message.  You
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// create an instance of LogMessage and then stream stuff to it.
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When you finish streaming to it, ~LogMessage is called and the
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// full message gets streamed to the appropriate destination.
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You shouldn't actually use LogMessage's constructor to log things,
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// though.  You should use the LOG() macro (and variants thereof)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// above.
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT LogMessage {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
687f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Used for LOG(severity).
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(const char* file, int line, LogSeverity severity);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
690f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Used for CHECK_EQ(), etc. Takes ownership of the given string.
691f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Implied severity = LOG_FATAL.
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(const char* file, int line, std::string* result);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
694f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Used for DCHECK_EQ(), etc. Takes ownership of the given string.
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(const char* file, int line, LogSeverity severity,
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             std::string* result);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~LogMessage();
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostream& stream() { return stream_; }
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init(const char* file, int line);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogSeverity severity_;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostringstream stream_;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t message_start_;  // Offset of the start of the message (past prefix
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          // info).
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The file and line information passed in to the constructor.
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* file_;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int line_;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stores the current value of GetLastError in the constructor and restores
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it in the destructor by calling SetLastError.
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is useful since the LogMessage class uses a lot of Win32 calls
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that will lose the value of GLE and the code that called the log function
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will have lost the thread error value when the log call returns.
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class SaveLastError {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SaveLastError();
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~SaveLastError();
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long get_error() const { return last_error_; }
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long last_error_;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SaveLastError last_error_;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LogMessage);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A non-macro interface to the log facility; (useful
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when the logging level is not a compile-time constant).
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void LogAtLevel(int const log_level, std::string const &msg) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage(__FILE__, __LINE__, log_level).stream() << msg;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is used to explicitly ignore values in the conditional
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// logging macros.  This avoids compiler warnings like "value computed
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not used" and "statement has no effect".
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LogMessageVoidify {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessageVoidify() { }
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This has to be an operator with a precedence lower than << but
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // higher than ?:
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void operator&(std::ostream&) { }
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned long SystemErrorCode;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int SystemErrorCode;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alias for ::GetLastError() on Windows and errno on POSIX. Avoids having to
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pull in windows.h just for GetLastError() and DWORD.
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT SystemErrorCode GetLastSystemErrorCode();
7620529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochBASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends a formatted system message of the GetLastError() type.
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT Win32ErrorLogMessage {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Win32ErrorLogMessage(const char* file,
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       int line,
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       LogSeverity severity,
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       SystemErrorCode err);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Appends the error message before destructing the encapsulated class.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~Win32ErrorLogMessage();
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostream& stream() { return log_message_.stream(); }
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SystemErrorCode err_;
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage log_message_;
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Win32ErrorLogMessage);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends a formatted system message of the errno type
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT ErrnoLogMessage {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ErrnoLogMessage(const char* file,
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int line,
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  LogSeverity severity,
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  SystemErrorCode err);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Appends the error message before destructing the encapsulated class.
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ErrnoLogMessage();
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::ostream& stream() { return log_message_.stream(); }
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SystemErrorCode err_;
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LogMessage log_message_;
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ErrnoLogMessage);
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Closes the log file explicitly if open.
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NOTE: Since the log file is opened as necessary by the action of logging
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       statements, there's no guarantee that it will stay closed
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       after this call.
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void CloseLogFile();
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Async signal safe logging mechanism.
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void RawLog(int level, const char* message);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAW_LOG(level, message) logging::RawLog(logging::LOG_ ## level, message)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RAW_CHECK(condition)                                                   \
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {                                                                         \
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(condition))                                                          \
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logging::RawLog(logging::LOG_FATAL, "Check failed: " #condition "\n");   \
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (0)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the default log file path.
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BASE_EXPORT std::wstring GetLogFileFullPath();
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace logging
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
830116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Note that "The behavior of a C++ program is undefined if it adds declarations
831116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// or definitions to namespace std or to a namespace within namespace std unless
832116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// otherwise specified." --C++11[namespace.std]
833116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//
834116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// We've checked that this particular definition has the intended behavior on
835116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// our implementations, but it's prone to breaking in the future, and please
836116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// don't imitate this in your own definitions without checking with some
837116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// standard library experts.
838116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace std {
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These functions are provided as a convenience for logging, which is where we
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// use streams (it is against Google style to use streams in other places). It
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is designed to allow you to emit non-ASCII Unicode strings to the log file,
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which is normally ASCII. It is relatively slow, so try not to use it for
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// common cases. Non-ASCII characters will be converted to UTF-8 by these
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operators.
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT std::ostream& operator<<(std::ostream& out, const wchar_t* wstr);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return out << wstr.c_str();
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
849116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace std
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The NOTIMPLEMENTED() macro annotates codepaths which have
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not been implemented yet.
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The implementation of this macro is controlled by NOTIMPLEMENTED_POLICY:
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0 -- Do nothing (stripped by compiler)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   1 -- Warn at compile time
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   2 -- Fail at compile time
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   3 -- Fail at runtime (DCHECK)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   4 -- [default] LOG(ERROR) at runtime
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   5 -- LOG(ERROR) at runtime, only once per call-site
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NOTIMPLEMENTED_POLICY
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) && defined(OFFICIAL_BUILD)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED_POLICY 0
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
866ee3a239997afef1873d8c812225689a5f134be2eTorne (Richard Coles)// WebView: Hide NOTIMPLEMENTED entirely in Android release branch.
867ee3a239997afef1873d8c812225689a5f134be2eTorne (Richard Coles)#define NOTIMPLEMENTED_POLICY 0
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(COMPILER_GCC)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Linux, with GCC, we can use __PRETTY_FUNCTION__ to get the demangled name
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the current function in the NOTIMPLEMENTED message.
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED_MSG "Not implemented reached in " << __PRETTY_FUNCTION__
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED_MSG "NOT IMPLEMENTED"
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if NOTIMPLEMENTED_POLICY == 0
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() EAT_STREAM_PARAMETERS
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 1
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO, figure out how to generate a warning
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() COMPILE_ASSERT(false, NOT_IMPLEMENTED)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 2
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() COMPILE_ASSERT(false, NOT_IMPLEMENTED)
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 3
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() NOTREACHED()
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 4
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() LOG(ERROR) << NOTIMPLEMENTED_MSG
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif NOTIMPLEMENTED_POLICY == 5
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOTIMPLEMENTED() do {\
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool logged_once = false;\
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG_IF(ERROR, !logged_once) << NOTIMPLEMENTED_MSG;\
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  logged_once = true;\
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} while(0);\
8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)EAT_STREAM_PARAMETERS
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_LOGGING_H_
900