Home | History | Annotate | Download | only in base
      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();
    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 {
    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.
    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 
    279     const char* string() const { return mString ? mString : ""; }
    280     size_t size() const { return mSize; }
    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:
    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 
    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 
    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:
    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