1// Copyright 2014 The Android Open Source Project 2// 3// This software is licensed under the terms of the GNU General Public 4// License version 2, as published by the Free Software Foundation, and 5// may be copied, distributed, and modified under those terms. 6// 7// This program is distributed in the hope that it will be useful, 8// but WITHOUT ANY WARRANTY; without even the implied warranty of 9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10// GNU General Public License for more details. 11 12#ifndef ANDROID_BASE_LOG_H 13#define ANDROID_BASE_LOG_H 14 15#include <errno.h> 16#include <stdarg.h> 17#include <stddef.h> 18 19namespace android { 20namespace base { 21 22// The list of severity levels used for logging. 23// Note that negative verbosity levels are used. 24typedef int LogSeverity; 25const LogSeverity LOG_VERBOSE = -1; 26const LogSeverity LOG_INFO = 0; 27const LogSeverity LOG_WARNING = 1; 28const LogSeverity LOG_ERROR = 2; 29const LogSeverity LOG_FATAL = 3; 30const LogSeverity LOG_NUM_SEVERITIES = 4; 31 32// LOG_DFATAL will be LOG_ERROR in release builds, and LOG_FATAL in debug 33// ones. 34#ifdef NDEBUG 35const LogSeverity LOG_DFATAL = LOG_ERROR; 36#else 37const LogSeverity LOG_DFATAL = LOG_FATAL; 38#endif 39 40// Returns the minimal log level. 41LogSeverity getMinLogLevel(); 42 43// Helper macro used to test if logging for a given log level is 44// currently enabled. |severity| must be a log level without the LOG_ 45// prefix, as in: 46// 47// if (LOG_IS_ON(INFO)) { 48// ... do additionnal logging 49// } 50// 51#define LOG_IS_ON(severity) \ 52 ((::android::base::LOG_ ## severity) >= \ 53 ::android::base::getMinLogLevel()) 54 55// For performance reasons, it's important to avoid constructing a 56// LogMessage instance every time a LOG() or CHECK() statement is 57// encountered at runtime, i.e. these objects should only be constructed 58// when absolutely necessary, which means: 59// - For LOG() statements, when the corresponding log level is enabled. 60// - For CHECK(), when the tested expression doesn't hold. 61// 62// At the same time, we really want to use expressions like: 63// LOG(severity) << some_stuff << some_more_stuff; 64// 65// This means LOG(severity) should expand to something that can take 66// << operators on its right hand side. This is achieved with the 67// ternary '? :', as implemented by this helper macro. 68// 69// Unfortunately, a simple thing like: 70// 71// !(condition) ? (void)0 : (expr) 72// 73// will not work, because the compiler complains loudly with: 74// 75// error: second operand to the conditional operator is of type 'void', 76// but the third operand is neither a throw-expression nor of type 'void' 77#define LOG_LAZY_EVAL(condition, expr) \ 78 !(condition) ? (void)0 : ::android::base::LogStreamVoidify() & (expr) 79 80// Send a message to the log if |severity| is higher or equal to the current 81// logging severity level. This macro expands to an expression that acts as 82// an input stream for strings, ints and floating point values, as well as 83// LogString instances. Usage example: 84// 85// LOG(INFO) << "Starting flux capacitor"; 86// fluxCapacitor::start(); 87// LOG(INFO) << "Flux capacitor started"; 88// 89// Note that the macro implementation is optimized to avoid doing any work 90// if the severity level is disabled. 91// 92// It's possible to do conditional logging with LOG_IF() 93#define LOG(severity) \ 94 LOG_LAZY_EVAL(LOG_IS_ON(severity), \ 95 LOG_MESSAGE_STREAM_COMPACT(severity)) 96 97// A variant of LOG() that only performs logging if a specific condition 98// is encountered. Note that |condition| is only evaluated if |severity| 99// is high enough. Usage example: 100// 101// LOG(INFO) << "Starting fuel injector"; 102// fuelInjector::start(); 103// LOG(INFO) << "Fuel injection started"; 104// LOG_IF(INFO, fuelInjector::hasOptimalLevel()) 105// << "Fuel injection at optimal level"; 106// 107#define LOG_IF(severity, condition) \ 108 LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \ 109 LOG_MESSAGE_STREAM_COMPACT(severity)) 110 111 112// A variant of LOG() that also appends the string message corresponding 113// to the current value of 'errno' just before the macro is called. This 114// also preserves the value of 'errno' so it can be tested after the 115// macro call (i.e. any error during log output does not interfere). 116#define PLOG(severity) \ 117 LOG_LAZY_EVAL(LOG_IS_ON(severity), \ 118 PLOG_MESSAGE_STREAM_COMPACT(severity)) 119 120// A variant of LOG_IF() that also appends the string message corresponding 121// to the current value of 'errno' just before the macro is called. This 122// also preserves the value of 'errno' so it can be tested after the 123// macro call (i.e. any error during log output does not interfere). 124#define PLOG_IF(severity, condition) \ 125 LOG_LAZY_EVAL(LOG_IS_ON(severity) && (condition), \ 126 PLOG_MESSAGE_STREAM_COMPACT(severity)) 127 128// Evaluate |condition|, and if it fails, log a fatal message. 129// This is a better version of assert(), in the future, this will 130// also break directly into the debugger for debug builds. 131// 132// Usage is similar to LOG(FATAL), e.g.: 133// 134// CHECK(some_condition) << "Something really bad happened!"; 135// 136#define CHECK(condition) \ 137 LOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " 138 139 140// A variant of CHECK() that also appends the errno message string at 141// the end of the log message before exiting the process. 142#define PCHECK(condition) \ 143 PLOG_IF(FATAL, !(condition)) << "Check failed: " #condition ". " 144 145 146// Define ENABLE_DLOG to 1 here if DLOG() statements should be compiled 147// as normal LOG() ones in the final binary. If 0, the statements will not 148// be compiled. 149#ifndef ENABLE_DLOG 150# if defined(NDEBUG) 151# define ENABLE_DLOG 0 152# else 153# define ENABLE_DLOG 1 154# endif 155#endif 156 157// ENABLE_DCHECK controls how DCHECK() statements are compiled: 158// 0 - DCHECK() are not compiled in the binary at all. 159// 1 - DCHECK() are compiled, but are not performed at runtime, unless 160// the DCHECK level has been increased explicitely. 161// 2 - DCHECK() are always compiled as CHECK() in the final binary. 162#ifndef ENABLE_DCHECK 163# if defined(NDEBUG) 164# define ENABLE_DCHECK 1 165# else 166# define ENABLE_DCHECK 2 167# endif 168#endif 169 170// DLOG_IS_ON(severity) is used to indicate whether DLOG() should print 171// something for the current level. 172#if ENABLE_DLOG 173# define DLOG_IS_ON(severity) LOG_IS_ON(severity) 174#else 175// NOTE: The compile-time constant ensures that the DLOG() statements are 176// not compiled in the final binary. 177# define DLOG_IS_ON(severity) false 178#endif 179 180// DCHECK_IS_ON() is used to indicate whether DCHECK() should do anything. 181#if ENABLE_DCHECK == 0 182 // NOTE: Compile-time constant ensures the DCHECK() statements are 183 // note compiled in the final binary. 184# define DCHECK_IS_ON() false 185#elif ENABLE_DCHECK == 1 186# define DCHECK_IS_ON() ::android::base::dcheckIsEnabled() 187#else 188# define DCHECK_IS_ON() true 189#endif 190 191// A function that returns true iff DCHECK() should actually do any checking. 192bool dcheckIsEnabled(); 193 194// Change the DCHECK() level to either false or true. Should only be called 195// early, e.g. after parsing command-line arguments. Returns previous value. 196bool setDcheckLevel(bool enabled); 197 198// DLOG() is like LOG() for debug builds, and doesn't do anything for 199// release one. This is useful to add log messages that you don't want 200// to see in the final binaries, but are useful during testing. 201#define DLOG(severity) LOG_IF(severity, DLOG_IS_ON()) 202 203// DLOG_IF() is like DLOG() for debug builds, and doesn't do anything for 204// release one. See DLOG() comments. 205#define DLOG_IF(severity, condition) \ 206 LOG_IF(severity, DLOG_IS_ON() && (condition)) 207 208// DCHECK(condition) is used to perform CHECK() in debug builds, or if 209// the program called setDcheckLevel(true) previously. Note that it is 210// also possible to completely remove them from the final binary by 211// using the compiler flag -DENABLE_DCHECK=0 212#define DCHECK(condition) \ 213 LOG_IF(FATAL, DCHECK_IS_ON() && !(condition)) \ 214 << "Check failed: " #condition ". " 215 216// Convenience class used hold a formatted string for logging reasons. 217// Usage example: 218// 219// LOG(INFO) << LogString("There are %d items in this set", count); 220// 221class LogString { 222public: 223 LogString(const char* fmt, ...); 224 ~LogString(); 225 const char* string() const { return mString; } 226private: 227 char* mString; 228}; 229 230// Helper structure used to group the parameters of a LOG() or CHECK() 231// statement. 232struct LogParams { 233 LogParams() : file(NULL), lineno(-1), severity(-1) {} 234 235 LogParams(const char* a_file, int a_lineno, LogSeverity a_severity) 236 : file(a_file), lineno(a_lineno), severity(a_severity) {} 237 238 const char* file; 239 int lineno; 240 LogSeverity severity; 241}; 242 243// Helper class used to implement an input stream similar to std::istream 244// where it's possible to inject strings, integers, floats and LogString 245// instances with the << operator. 246// 247// This also takes a source file, line number and severity to avoid 248// storing these in the stack of the functions were LOG() and CHECK() 249// statements are called. 250class LogStream { 251public: 252 LogStream(const char* file, int lineno, LogSeverity severity); 253 ~LogStream(); 254 255 inline LogStream& operator<<(const char* str) { 256 append(str); 257 return *this; 258 } 259 260 inline LogStream& operator<<(const LogString& str) { 261 append(str.string()); 262 return *this; 263 } 264 265 // Note: this prints the pointer value (address). 266 LogStream& operator<<(const void* v); 267 268 LogStream& operator<<(char ch); 269 LogStream& operator<<(int v); 270 LogStream& operator<<(unsigned v); 271 LogStream& operator<<(long v); 272 LogStream& operator<<(unsigned long v); 273 //LogStream& operator<<(size_t v); 274 LogStream& operator<<(long long v); 275 LogStream& operator<<(unsigned long long v); 276 LogStream& operator<<(float v); 277 LogStream& operator<<(double v); 278 279 const char* string() const { return mString ? mString : ""; } 280 size_t size() const { return mSize; } 281 const LogParams& params() const { return mParams; } 282 283private: 284 void append(const char* str); 285 void append(const char* str, size_t len); 286 287 LogParams mParams; 288 char* mString; 289 size_t mSize; 290 size_t mCapacity; 291}; 292 293// Helper class used to avoid compiler errors, see LOG_LAZY_EVAL for 294// more information. 295class LogStreamVoidify { 296 public: 297 LogStreamVoidify() { } 298 // This has to be an operator with a precedence lower than << but 299 // higher than ?: 300 void operator&(LogStream&) { } 301}; 302 303// This represents an log message. At creation time, provide the name of 304// the current file, the source line number and a severity. 305// You can them stream stuff into it with <<. For example: 306// 307// LogMessage(__FILE__, __LINE__, LOG_INFO) << "Hello World!\n"; 308// 309// When destroyed, the message sends the final output to the appropriate 310// log (e.g. stderr by default). 311class LogMessage { 312public: 313 LogMessage(const char* file, int line, LogSeverity severity); 314 ~LogMessage(); 315 316 LogStream& stream() const { return *mStream; } 317protected: 318 // Avoid that each LOG() statement 319 LogStream* mStream; 320}; 321 322// Helper macros to avoid too much typing. This creates a new LogMessage 323// instance with the appropriate file source path, file source line and 324// severity. 325#define LOG_MESSAGE_COMPACT(severity) \ 326 ::android::base::LogMessage( \ 327 __FILE__, \ 328 __LINE__, \ 329 ::android::base::LOG_ ## severity) 330 331#define LOG_MESSAGE_STREAM_COMPACT(severity) \ 332 LOG_MESSAGE_COMPACT(severity).stream() 333 334 335// A variant of LogMessage that saves the errno value on creation, 336// then restores it on destruction, as well as append a strerror() 337// error message to the log before sending it for output. Used by 338// the PLOG() implementation(s). 339// 340// This cannot be a sub-class of LogMessage because the destructor needs 341// to restore the saved errno message after sending the message to the 342// LogOutput and deleting the stream. 343class ErrnoLogMessage { 344public: 345 ErrnoLogMessage(const char* file, 346 int line, 347 LogSeverity severity, 348 int errnoCode); 349 ~ErrnoLogMessage(); 350 351 LogStream& stream() const { return *mStream; } 352private: 353 LogStream* mStream; 354 int mErrno; 355}; 356 357// Helper macros to avoid too much typing. 358#define PLOG_MESSAGE_COMPACT(severity) \ 359 ::android::base::ErrnoLogMessage( \ 360 __FILE__, \ 361 __LINE__, \ 362 ::android::base::LOG_ ## severity, \ 363 errno) 364 365#define PLOG_MESSAGE_STREAM_COMPACT(severity) \ 366 PLOG_MESSAGE_COMPACT(severity).stream() 367 368namespace testing { 369 370// Abstract interface to the output where the log messages are sent. 371// IMPORTANT: Only use this for unit testing the log facility. 372class LogOutput { 373public: 374 LogOutput() {} 375 virtual ~LogOutput() {} 376 377 // Send a full log message to the output. Not zero terminated, and 378 // Does not have a trailing \n which can be added by the implementation 379 // when writing the message to a file. 380 // Note: if |severity| is LOG_FATAL, this should also terminate the 381 // process. 382 virtual void logMessage(const LogParams& params, 383 const char* message, 384 size_t message_len) = 0; 385 386 // Set a new log output, and return pointer to the previous 387 // implementation, which will be NULL for the default one. 388 // |newOutput| is either NULL (which means the default), or a 389 // custom instance of LogOutput. 390 static LogOutput* setNewOutput(LogOutput* newOutput); 391}; 392 393} // namespace testing 394 395} // namespace base 396} // namespace android 397 398#endif // ANDROID_BASE_LOG_H 399