| OLD | NEW |
| (Empty) |
| 1 // Copyright 2006-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 #ifndef OMAHA_COMMON_LOGGING_LOGGING_H__ | |
| 17 #define OMAHA_COMMON_LOGGING_LOGGING_H__ | |
| 18 | |
| 19 #include <string> | |
| 20 #include <cstring> | |
| 21 #include <strstream> | |
| 22 #include <tchar.h> | |
| 23 | |
| 24 #include "base/basictypes.h" | |
| 25 #include "base/scoped_ptr.h" | |
| 26 | |
| 27 // This file provides logging facility for Windows client apps. | |
| 28 // | |
| 29 // Optional message capabilities | |
| 30 // ----------------------------- | |
| 31 // Assertion failed messages and fatal errors are displayed in a dialog box | |
| 32 // before the application exits. However, running this UI creates a message | |
| 33 // loop, which causes application messages to be processed and potentially | |
| 34 // dispatched to existing application windows. Since the application is in a | |
| 35 // bad state when this assertion dialog is displayed, these messages may not | |
| 36 // get processed and hang the dialog, or the application might go crazy. | |
| 37 // | |
| 38 // Therefore, it can be beneficial to display the error dialog in a separate | |
| 39 // process from the main application. When the logging system needs to display | |
| 40 // a fatal error dialog box, it will look for a program called | |
| 41 // "DebugMessage.exe" in the same directory as the application executable. It | |
| 42 // will run this application with the message as the command line, and will | |
| 43 // not include the name of the application as is traditional for easier | |
| 44 // parsing. | |
| 45 // | |
| 46 // The code for DebugMessage.exe is only one line. In WinMain, do: | |
| 47 // MessageBox(NULL, GetCommandLineW(), L"Fatal Error", 0); | |
| 48 // | |
| 49 // If DebugMessage.exe is not found, the logging code will use a normal | |
| 50 // MessageBox, potentially causing the problems discussed above. | |
| 51 | |
| 52 | |
| 53 // Instructions | |
| 54 // ------------ | |
| 55 // | |
| 56 // Make a bunch of macros for logging. The way to log things is to stream | |
| 57 // things to LOG(<a particular severity level>). E.g., | |
| 58 // | |
| 59 // LOG(INFO) << "Found " << num_cookies << " cookies"; | |
| 60 // | |
| 61 // You can also do conditional logging: | |
| 62 // | |
| 63 // LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; | |
| 64 // | |
| 65 // The above will cause log messages to be output on the 1st, 11th, 21st, ... | |
| 66 // times it is executed. Note that the special COUNTER value is used to | |
| 67 // identify which repetition is happening. | |
| 68 // | |
| 69 // The CHECK(condition) macro is active in both debug and release builds and | |
| 70 // effectively performs a LOG(FATAL) which terminates the process and | |
| 71 // generates a crashdump unless a debugger is attached. | |
| 72 // | |
| 73 // There are also "debug mode" logging macros like the ones above: | |
| 74 // | |
| 75 // DLOG(INFO) << "Found cookies"; | |
| 76 // | |
| 77 // DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; | |
| 78 // | |
| 79 // All "debug mode" logging is compiled away to nothing for non-debug mode | |
| 80 // compiles. LOG_IF and development flags also work well together | |
| 81 // because the code can be compiled away sometimes. | |
| 82 // | |
| 83 // We also have | |
| 84 // | |
| 85 // LOG_ASSERT(assertion); | |
| 86 // DLOG_ASSERT(assertion); | |
| 87 // | |
| 88 // which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; | |
| 89 // | |
| 90 // We also override the standard 'assert' to use 'DLOG_ASSERT'. | |
| 91 // | |
| 92 // The supported severity levels for macros that allow you to specify one | |
| 93 // are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. | |
| 94 // | |
| 95 // There is also the special severity of DFATAL, which logs FATAL in | |
| 96 // debug mode, ERROR in normal mode. | |
| 97 // | |
| 98 // Very important: logging a message at the FATAL severity level causes | |
| 99 // the program to terminate (after the message is logged). | |
| 100 | |
| 101 namespace logging { | |
| 102 | |
| 103 // Where to record logging output? A flat file and/or system debug log via | |
| 104 // OutputDebugString. Defaults to LOG_ONLY_TO_FILE. | |
| 105 enum LoggingDestination { LOG_ONLY_TO_FILE, | |
| 106 LOG_ONLY_TO_SYSTEM_DEBUG_LOG, | |
| 107 LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG }; | |
| 108 | |
| 109 // Indicates that the log file should be locked when being written to. | |
| 110 // Often, there is no locking, which is fine for a single threaded program. | |
| 111 // If logging is being done from multiple threads or there can be more than | |
| 112 // one process doing the logging, the file should be locked during writes to | |
| 113 // make each log outut atomic. Other writers will block. | |
| 114 // | |
| 115 // All processes writing to the log file must have their locking set for it to | |
| 116 // work properly. Defaults to DONT_LOCK_LOG_FILE. | |
| 117 enum LogLockingState { LOCK_LOG_FILE, DONT_LOCK_LOG_FILE }; | |
| 118 | |
| 119 // On startup, should we delete or append to an existing log file (if any)? | |
| 120 // Defaults to APPEND_TO_OLD_LOG_FILE. | |
| 121 enum OldFileDeletionState { DELETE_OLD_LOG_FILE, APPEND_TO_OLD_LOG_FILE }; | |
| 122 | |
| 123 // Sets the log file name and other global logging state. Calling this function | |
| 124 // is recommended, and is normally done at the beginning of application init. | |
| 125 // If you don't call it, all the flags will be initialized to their default | |
| 126 // values, and there is a race condition that may leak a critical section | |
| 127 // object if two threads try to do the first log at the same time. | |
| 128 // See the definition of the enums above for descriptions and default values. | |
| 129 // | |
| 130 // The default log file is initialized to "debug.log" in the application | |
| 131 // directory. You probably don't want this, especially since the program | |
| 132 // directory may not be writable on an enduser's system. | |
| 133 void InitLogging(const TCHAR* log_file, LoggingDestination logging_dest, | |
| 134 LogLockingState lock_log, OldFileDeletionState delete_old); | |
| 135 | |
| 136 // Sets the log level. Anything at or above this level will be written to the | |
| 137 // log file/displayed to the user (if applicable). Anything below this level | |
| 138 // will be silently ignored. The log level defaults to 0 (everything is logged) | |
| 139 // if this function is not called. | |
| 140 void SetMinLogLevel(int level); | |
| 141 | |
| 142 // Sets the common items you want to be prepended to each log message. | |
| 143 // process and thread IDs default to off, the timestamp defaults to on. | |
| 144 // If this function is not called, logging defaults to writing the timestamp | |
| 145 // only. | |
| 146 void SetLogItems(bool enable_process_id, bool enable_thread_id, | |
| 147 bool enable_timestamp, bool enable_tickcount); | |
| 148 | |
| 149 // Sets the Log Assert Handler that will be used to notify of check failures. | |
| 150 // The default handler shows a dialog box, however clients can use this | |
| 151 // function to override with their own handling (e.g. a silent one for Unit | |
| 152 // Tests) | |
| 153 typedef void (*LogAssertHandlerFunction)(const std::string& str); | |
| 154 void SetLogAssertHandler(LogAssertHandlerFunction handler); | |
| 155 | |
| 156 typedef int LogSeverity; | |
| 157 const LogSeverity LOG_INFO = 0; | |
| 158 const LogSeverity LOG_WARNING = 1; | |
| 159 const LogSeverity LOG_ERROR = 2; | |
| 160 const LogSeverity LOG_FATAL = 3; | |
| 161 const LogSeverity LOG_NUM_SEVERITIES = 4; | |
| 162 | |
| 163 // LOG_DFATAL_LEVEL is LOG_FATAL in debug mode, ERROR in normal mode | |
| 164 #ifdef NDEBUG | |
| 165 const LogSeverity LOG_DFATAL_LEVEL = LOG_ERROR; | |
| 166 #else | |
| 167 const LogSeverity LOG_DFATAL_LEVEL = LOG_FATAL; | |
| 168 #endif | |
| 169 | |
| 170 // A few definitions of macros that don't generate much code. These are used | |
| 171 // by LOG() and LOG_IF, etc. Since these are used all over our code, it's | |
| 172 // better to have compact code for these operations. | |
| 173 #define COMPACT_GOOGLE_LOG_INFO \ | |
| 174 logging::LogMessage(__FILE__, __LINE__) | |
| 175 #define COMPACT_GOOGLE_LOG_WARNING \ | |
| 176 logging::LogMessage(__FILE__, __LINE__, logging::LOG_WARNING) | |
| 177 #define COMPACT_GOOGLE_LOG_ERROR \ | |
| 178 logging::LogMessage(__FILE__, __LINE__, logging::LOG_ERROR) | |
| 179 #define COMPACT_GOOGLE_LOG_FATAL \ | |
| 180 logging::LogMessage(__FILE__, __LINE__, logging::LOG_FATAL) | |
| 181 #define COMPACT_GOOGLE_LOG_DFATAL \ | |
| 182 logging::LogMessage(__FILE__, __LINE__, logging::LOG_DFATAL_LEVEL) | |
| 183 | |
| 184 // wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets | |
| 185 // substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us | |
| 186 // to keep using this syntax, we define this macro to do the same thing | |
| 187 // as COMPACT_GOOGLE_LOG_ERROR, and also define ERROR the same way that | |
| 188 // the Windows SDK does for consistency. | |
| 189 #define ERROR 0 | |
| 190 #define COMPACT_GOOGLE_LOG_0 \ | |
| 191 logging::LogMessage(__FILE__, __LINE__, logging::LOG_ERROR) | |
| 192 | |
| 193 // We use the preprocessor's merging operator, "##", so that, e.g., | |
| 194 // LOG(INFO) becomes the token COMPACT_GOOGLE_LOG_INFO. There's some funny | |
| 195 // subtle difference between ostream member streaming functions (e.g., | |
| 196 // ostream::operator<<(int) and ostream non-member streaming functions | |
| 197 // (e.g., ::operator<<(ostream&, string&): it turns out that it's | |
| 198 // impossible to stream something like a string directly to an unnamed | |
| 199 // ostream. We employ a neat hack by calling the stream() member | |
| 200 // function of LogMessage which seems to avoid the problem. | |
| 201 | |
| 202 #define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() | |
| 203 #define SYSLOG(severity) LOG(severity) | |
| 204 | |
| 205 #define LOG_IF(severity, condition) \ | |
| 206 !(condition) ? (void) 0 : logging::LogMessageVoidify() & LOG(severity) | |
| 207 #define SYSLOG_IF(severity, condition) LOG_IF(severity, condition) | |
| 208 | |
| 209 #define LOG_ASSERT(condition) \ | |
| 210 LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " | |
| 211 #define SYSLOG_ASSERT(condition) \ | |
| 212 SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition ". " | |
| 213 | |
| 214 // CHECK dies with a fatal error if condition is not true. It is *not* | |
| 215 // controlled by NDEBUG, so the check will be executed regardless of | |
| 216 // compilation mode. | |
| 217 #define CHECK(condition) \ | |
| 218 LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " | |
| 219 | |
| 220 // A container for a string pointer which can be evaluated to a bool - | |
| 221 // true iff the pointer is NULL. | |
| 222 struct CheckOpString { | |
| 223 CheckOpString(std::string* str) : str_(str) { } | |
| 224 // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), | |
| 225 // so there's no point in cleaning up str_. | |
| 226 operator bool() const { return str_ != NULL; } | |
| 227 std::string* str_; | |
| 228 }; | |
| 229 | |
| 230 // Build the error message string. This is separate from the "Impl" | |
| 231 // function template because it is not performance critical and so can | |
| 232 // be out of line, while the "Impl" code should be inline. | |
| 233 template<class t1, class t2> | |
| 234 std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { | |
| 235 std::ostrstream ss; | |
| 236 ss << names << " (" << v1 << " vs. " << v2 << ")"; | |
| 237 return new std::string(ss.str(), ss.pcount()); | |
| 238 } | |
| 239 | |
| 240 extern std::string* MakeCheckOpStringIntInt(int v1, int v2, const char* names); | |
| 241 | |
| 242 template<int, int> | |
| 243 std::string* MakeCheckOpString(const int& v1, const int& v2, const char* names)
{ | |
| 244 return MakeCheckOpStringIntInt(v1, v2, names); | |
| 245 } | |
| 246 | |
| 247 // Plus some debug-logging macros that get compiled to nothing for production | |
| 248 // | |
| 249 // DEBUG_MODE is for uses like | |
| 250 // if (DEBUG_MODE) foo.CheckThatFoo(); | |
| 251 // instead of | |
| 252 // #ifndef NDEBUG | |
| 253 // foo.CheckThatFoo(); | |
| 254 // #endif | |
| 255 | |
| 256 #ifndef NDEBUG | |
| 257 | |
| 258 #define DLOG(severity) LOG(severity) | |
| 259 #define DLOG_IF(severity, condition) LOG_IF(severity, condition) | |
| 260 #define DLOG_ASSERT(condition) LOG_ASSERT(condition) | |
| 261 | |
| 262 // debug-only checking. not executed in NDEBUG mode. | |
| 263 enum { DEBUG_MODE = 1 }; | |
| 264 #define DCHECK(condition) \ | |
| 265 LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " | |
| 266 | |
| 267 // Helper functions for DCHECK_OP macro. | |
| 268 // The (int, int) specialization works around the issue that the compiler | |
| 269 // will not instantiate the template version of the function on values of | |
| 270 // unnamed enum type - see comment below. | |
| 271 #define DEFINE_DCHECK_OP_IMPL(name, op) \ | |
| 272 template <class t1, class t2> \ | |
| 273 inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ | |
| 274 const char* names) { \ | |
| 275 if (v1 op v2) return NULL; \ | |
| 276 else return MakeCheckOpString(v1, v2, names); \ | |
| 277 } \ | |
| 278 inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ | |
| 279 if (v1 op v2) return NULL; \ | |
| 280 else return MakeCheckOpString(v1, v2, names); \ | |
| 281 } | |
| 282 DEFINE_DCHECK_OP_IMPL(EQ, ==) | |
| 283 DEFINE_DCHECK_OP_IMPL(NE, !=) | |
| 284 DEFINE_DCHECK_OP_IMPL(LE, <=) | |
| 285 DEFINE_DCHECK_OP_IMPL(LT, < ) | |
| 286 DEFINE_DCHECK_OP_IMPL(GE, >=) | |
| 287 DEFINE_DCHECK_OP_IMPL(GT, > ) | |
| 288 #undef DEFINE_DCHECK_OP_IMPL | |
| 289 | |
| 290 // Helper macro for binary operators. | |
| 291 // Don't use this macro directly in your code, use CHECK_EQ et al below. | |
| 292 #define DCHECK_OP(name, op, val1, val2) \ | |
| 293 while (logging::CheckOpString _result = \ | |
| 294 logging::Check##name##Impl((val1), (val2), #val1 " " #op " " #val2)) \ | |
| 295 logging::LogMessage(__FILE__, __LINE__, _result).stream() | |
| 296 | |
| 297 // Equality/Inequality checks - compare two values, and log a LOG_FATAL message | |
| 298 // including the two values when the result is not as expected. The values | |
| 299 // must have operator<<(ostream, ...) defined. | |
| 300 // | |
| 301 // You may append to the error message like so: | |
| 302 // CHECK_NE(1, 2) << ": The world must be ending!"; | |
| 303 // | |
| 304 // We are very careful to ensure that each argument is evaluated exactly | |
| 305 // once, and that anything which is legal to pass as a function argument is | |
| 306 // legal here. In particular, the arguments may be temporary expressions | |
| 307 // which will end up being destroyed at the end of the apparent statement, | |
| 308 // for example: | |
| 309 // CHECK_EQ(string("abc")[1], 'b'); | |
| 310 // | |
| 311 // WARNING: These don't compile correctly if one of the arguments is a pointer | |
| 312 // and the other is NULL. To work around this, simply static_cast NULL to the | |
| 313 // type of the desired pointer. | |
| 314 | |
| 315 #define DCHECK_EQ(val1, val2) DCHECK_OP(EQ, ==, val1, val2) | |
| 316 #define DCHECK_NE(val1, val2) DCHECK_OP(NE, !=, val1, val2) | |
| 317 #define DCHECK_LE(val1, val2) DCHECK_OP(LE, <=, val1, val2) | |
| 318 #define DCHECK_LT(val1, val2) DCHECK_OP(LT, < , val1, val2) | |
| 319 #define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2) | |
| 320 #define DCHECK_GT(val1, val2) DCHECK_OP(GT, > , val1, val2) | |
| 321 | |
| 322 // Helper functions for string comparisons. | |
| 323 // To avoid bloat, the definitions are in logging.cc. | |
| 324 #define DECLARE_DCHECK_STROP_IMPL(func, expected) \ | |
| 325 std::string* Check##func##expected##Impl(const char* s1, \ | |
| 326 const char* s2, \ | |
| 327 const char* names); | |
| 328 DECLARE_DCHECK_STROP_IMPL(strcmp, true) | |
| 329 DECLARE_DCHECK_STROP_IMPL(strcmp, false) | |
| 330 DECLARE_DCHECK_STROP_IMPL(_stricmp, true) | |
| 331 DECLARE_DCHECK_STROP_IMPL(_stricmp, false) | |
| 332 #undef DECLARE_DCHECK_STROP_IMPL | |
| 333 | |
| 334 // Helper macro for string comparisons. | |
| 335 // Don't use this macro directly in your code, use CHECK_STREQ et al below. | |
| 336 #define DCHECK_STROP(func, op, expected, s1, s2) \ | |
| 337 while (CheckOpString _result = \ | |
| 338 logging::Check##func##expected##Impl((s1), (s2), \ | |
| 339 #s1 " " #op " " #s2)) \ | |
| 340 LOG(FATAL) << *_result.str_ | |
| 341 | |
| 342 // String (char*) equality/inequality checks. | |
| 343 // CASE versions are case-insensitive. | |
| 344 // | |
| 345 // Note that "s1" and "s2" may be temporary strings which are destroyed | |
| 346 // by the compiler at the end of the current "full expression" | |
| 347 // (e.g. DCHECK_STREQ(Foo().c_str(), Bar().c_str())). | |
| 348 | |
| 349 #define DCHECK_STREQ(s1, s2) DCHECK_STROP(strcmp, ==, true, s1, s2) | |
| 350 #define DCHECK_STRNE(s1, s2) DCHECK_STROP(strcmp, !=, false, s1, s2) | |
| 351 #define DCHECK_STRCASEEQ(s1, s2) DCHECK_STROP(_stricmp, ==, true, s1, s2) | |
| 352 #define DCHECK_STRCASENE(s1, s2) DCHECK_STROP(_stricmp, !=, false, s1, s2) | |
| 353 | |
| 354 #define DCHECK_INDEX(I,A) DCHECK(I < (sizeof(A)/sizeof(A[0]))) | |
| 355 #define DCHECK_BOUND(B,A) DCHECK(B <= (sizeof(A)/sizeof(A[0]))) | |
| 356 | |
| 357 #else // NDEBUG | |
| 358 | |
| 359 #define DLOG(severity) \ | |
| 360 true ? (void) 0 : logging::LogMessageVoidify() & LOG(severity) | |
| 361 | |
| 362 #define DLOG_IF(severity, condition) \ | |
| 363 true ? (void) 0 : logging::LogMessageVoidify() & LOG(severity) | |
| 364 | |
| 365 #define DLOG_ASSERT(condition) \ | |
| 366 true ? (void) 0 : LOG_ASSERT(condition) | |
| 367 | |
| 368 enum { DEBUG_MODE = 0 }; | |
| 369 | |
| 370 // This macro can be followed by a sequence of stream parameters in | |
| 371 // non-debug mode. The DCHECK and friends macros use this so that | |
| 372 // the expanded expression DCHECK(foo) << "asdf" is still syntactically | |
| 373 // valid, even though the expression will get optimized away. | |
| 374 #define NDEBUG_EAT_STREAM_PARAMETERS \ | |
| 375 logging::LogMessage(__FILE__, __LINE__).stream() | |
| 376 | |
| 377 #define DCHECK(condition) \ | |
| 378 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 379 | |
| 380 #define DCHECK_EQ(val1, val2) \ | |
| 381 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 382 | |
| 383 #define DCHECK_NE(val1, val2) \ | |
| 384 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 385 | |
| 386 #define DCHECK_LE(val1, val2) \ | |
| 387 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 388 | |
| 389 #define DCHECK_LT(val1, val2) \ | |
| 390 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 391 | |
| 392 #define DCHECK_GE(val1, val2) \ | |
| 393 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 394 | |
| 395 #define DCHECK_GT(val1, val2) \ | |
| 396 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 397 | |
| 398 #define DCHECK_STREQ(str1, str2) \ | |
| 399 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 400 | |
| 401 #define DCHECK_STRCASEEQ(str1, str2) \ | |
| 402 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 403 | |
| 404 #define DCHECK_STRNE(str1, str2) \ | |
| 405 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 406 | |
| 407 #define DCHECK_STRCASENE(str1, str2) \ | |
| 408 while (false) NDEBUG_EAT_STREAM_PARAMETERS | |
| 409 | |
| 410 #endif // NDEBUG | |
| 411 | |
| 412 #define NOTREACHED() DCHECK(false) | |
| 413 | |
| 414 // Redefine the standard assert to use our nice log files | |
| 415 #undef assert | |
| 416 #define assert(x) DLOG_ASSERT(x) | |
| 417 | |
| 418 // This class more or less represents a particular log message. You | |
| 419 // create an instance of LogMessage and then stream stuff to it. | |
| 420 // When you finish streaming to it, ~LogMessage is called and the | |
| 421 // full message gets streamed to the appropriate destination. | |
| 422 // | |
| 423 // You shouldn't actually use LogMessage's constructor to log things, | |
| 424 // though. You should use the LOG() macro (and variants thereof) | |
| 425 // above. | |
| 426 class LogMessage { | |
| 427 public: | |
| 428 LogMessage(const char* file, int line, LogSeverity severity, int ctr); | |
| 429 | |
| 430 // Two special constructors that generate reduced amounts of code at | |
| 431 // LOG call sites for common cases. | |
| 432 // | |
| 433 // Used for LOG(INFO): Implied are: | |
| 434 // severity = LOG_INFO, ctr = 0 | |
| 435 // | |
| 436 // Using this constructor instead of the more complex constructor above | |
| 437 // saves a couple of bytes per call site. | |
| 438 LogMessage(const char* file, int line); | |
| 439 | |
| 440 // Used for LOG(severity) where severity != INFO. Implied | |
| 441 // are: ctr = 0 | |
| 442 // | |
| 443 // Using this constructor instead of the more complex constructor above | |
| 444 // saves a couple of bytes per call site. | |
| 445 LogMessage(const char* file, int line, LogSeverity severity); | |
| 446 | |
| 447 // A special constructor used for check failures. | |
| 448 // Implied severity = LOG_FATAL | |
| 449 LogMessage(const char* file, int line, const CheckOpString& result); | |
| 450 | |
| 451 ~LogMessage(); | |
| 452 | |
| 453 std::ostream& stream() { return stream_; } | |
| 454 | |
| 455 private: | |
| 456 void Init(const char* file, int line); | |
| 457 | |
| 458 LogSeverity severity_; | |
| 459 std::ostrstream stream_; | |
| 460 | |
| 461 DISALLOW_EVIL_CONSTRUCTORS(LogMessage); | |
| 462 }; | |
| 463 | |
| 464 // A non-macro interface to the log facility; (useful | |
| 465 // when the logging level is not a compile-time constant). | |
| 466 inline void LogAtLevel(int const log_level, std::string const &msg) { | |
| 467 LogMessage(__FILE__, __LINE__, log_level).stream() << msg; | |
| 468 } | |
| 469 | |
| 470 // This class is used to explicitly ignore values in the conditional | |
| 471 // logging macros. This avoids compiler warnings like "value computed | |
| 472 // is not used" and "statement has no effect". | |
| 473 class LogMessageVoidify { | |
| 474 public: | |
| 475 LogMessageVoidify() { } | |
| 476 // This has to be an operator with a precedence lower than << but | |
| 477 // higher than ?: | |
| 478 void operator&(std::ostream&) { } | |
| 479 }; | |
| 480 | |
| 481 // Closes the log file explicitly if open. | |
| 482 // NOTE: Since the log file is opened as necessary by the action of logging | |
| 483 // statements, there's no guarantee that it will stay closed | |
| 484 // after this call. | |
| 485 void CloseLogFile(); | |
| 486 | |
| 487 } // namespace Logging | |
| 488 | |
| 489 // These functions are provided as a convenience for logging, which is where we | |
| 490 // use streams (it is against Google style to use streams in other places). It | |
| 491 // is designed to allow you to emit non-ASCII Unicode strings to the log file, | |
| 492 // which is normally ASCII. It is relatively slow, so try not to use it for | |
| 493 // common cases. Non-ASCII characters will be converted to UTF-8 by these operat
ors. | |
| 494 std::ostream& operator<<(std::ostream& out, const wchar_t* wstr); | |
| 495 inline std::ostream& operator<<(std::ostream& out, const std::wstring& wstr) { | |
| 496 return out << wstr.c_str(); | |
| 497 } | |
| 498 | |
| 499 #endif // OMAHA_COMMON_LOGGING_LOGGING_H__ | |
| OLD | NEW |