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 19 namespace android { 20 namespace base { 21 22 // The list of severity levels used for logging. 23 // Note that negative verbosity levels are used. 24 typedef int LogSeverity; 25 const LogSeverity LOG_VERBOSE = -1; 26 const LogSeverity LOG_INFO = 0; 27 const LogSeverity LOG_WARNING = 1; 28 const LogSeverity LOG_ERROR = 2; 29 const LogSeverity LOG_FATAL = 3; 30 const 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 35 const LogSeverity LOG_DFATAL = LOG_ERROR; 36 #else 37 const LogSeverity LOG_DFATAL = LOG_FATAL; 38 #endif 39 40 // Returns the minimal log level. 41 LogSeverity 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. 192 bool 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. 196 bool 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 // 221 class LogString { 222 public: 223 LogString(const char* fmt, ...); 224 ~LogString(); string()225 const char* string() const { return mString; } 226 private: 227 char* mString; 228 }; 229 230 // Helper structure used to group the parameters of a LOG() or CHECK() 231 // statement. 232 struct LogParams { LogParamsLogParams233 LogParams() : file(NULL), lineno(-1), severity(-1) {} 234 LogParamsLogParams235 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. 250 class LogStream { 251 public: 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 string()279 const char* string() const { return mString ? mString : ""; } size()280 size_t size() const { return mSize; } params()281 const LogParams& params() const { return mParams; } 282 283 private: 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. 295 class LogStreamVoidify { 296 public: LogStreamVoidify()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). 311 class LogMessage { 312 public: 313 LogMessage(const char* file, int line, LogSeverity severity); 314 ~LogMessage(); 315 stream()316 LogStream& stream() const { return *mStream; } 317 protected: 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. 343 class ErrnoLogMessage { 344 public: 345 ErrnoLogMessage(const char* file, 346 int line, 347 LogSeverity severity, 348 int errnoCode); 349 ~ErrnoLogMessage(); 350 stream()351 LogStream& stream() const { return *mStream; } 352 private: 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 368 namespace 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. 372 class LogOutput { 373 public: LogOutput()374 LogOutput() {} ~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