Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROMIUMOS_WIDE_PROFILING_MYBASE_BASE_LOGGING_H_
      6 #define CHROMIUMOS_WIDE_PROFILING_MYBASE_BASE_LOGGING_H_
      7 
      8 #include <errno.h>   // for errno
      9 #include <string.h>  // for strerror
     10 
     11 #include <iostream>
     12 #include <sstream>
     13 #include <string>
     14 
     15 #include "base/macros.h"
     16 
     17 // Emulate Chrome-like logging.
     18 
     19 // LogLevel is an enumeration that holds the log levels like libbase does.
     20 enum LogLevel {
     21   INFO,
     22   WARNING,
     23   ERROR,
     24   FATAL,
     25 };
     26 
     27 namespace logging {
     28 
     29 // Sets the log level. Anything at or above this level will be written to the
     30 // log file/displayed to the user (if applicable). Anything below this level
     31 // will be silently ignored. The log level defaults to 0 (everything is logged
     32 // up to level INFO) if this function is not called.
     33 // Note that log messages for VLOG(x) are logged at level -x, so setting
     34 // the min log level to negative values enables verbose logging.
     35 void SetMinLogLevel(int level);
     36 
     37 // Gets the current log level.
     38 int GetMinLogLevel();
     39 
     40 // Gets the VLOG verbosity level.
     41 int GetVlogVerbosity();
     42 
     43 // Generic logging class that emulates logging from libbase. Do not use this
     44 // class directly.
     45 class LogBase {
     46  public:
     47   virtual ~LogBase() {}
     48 
     49   template <class T>
     50   LogBase& operator<<(const T& x) {
     51     ss_ << x;
     52     return *this;
     53   }
     54 
     55  protected:
     56   LogBase(const std::string label, const char* file, int line) {
     57     ss_ << "[" << label << ":" << file << ":" << line << "] ";
     58   }
     59 
     60   // Accumulates the contents to be printed.
     61   std::ostringstream ss_;
     62 };
     63 
     64 // For general logging.
     65 class Log : public LogBase {
     66  public:
     67   Log(LogLevel level, const char* level_str, const char* file, int line)
     68       : LogBase(level_str, file, line) {
     69     level_ = level;
     70   }
     71 
     72   ~Log() {
     73     if (level_ >= GetMinLogLevel()) std::cerr << ss_.str() << std::endl;
     74     if (level_ >= FATAL) exit(EXIT_FAILURE);
     75   }
     76 
     77  protected:
     78   LogLevel level_;
     79 };
     80 
     81 // Like LOG but appends errno's string description to the logging.
     82 class PLog : public Log {
     83  public:
     84   PLog(LogLevel level, const char* level_str, const char* file, int line)
     85       : Log(level, level_str, file, line) {}
     86 
     87   ~PLog() {
     88     if (level_ >= GetMinLogLevel())
     89       std::cerr << ss_.str() << ": " << strerror(errnum_) << std::endl;
     90   }
     91 
     92  private:
     93   // Cached error value, in case errno changes during this object's lifetime.
     94   int errnum_;
     95 };
     96 
     97 // Like LOG but conditional upon the logging verbosity level.
     98 class VLog : public LogBase {
     99  public:
    100   VLog(int vlog_level, const char* file, int line)
    101       : LogBase(std::string("VLOG(") + std::to_string(vlog_level) + ")", file,
    102                 line),
    103         vlog_level_(vlog_level) {}
    104 
    105   ~VLog() {
    106     if (vlog_level_ <= GetVlogVerbosity()) std::cerr << ss_.str() << std::endl;
    107   }
    108 
    109  private:
    110   // Logging verbosity level. The logging will be printed if this value is less
    111   // than or equal to GetVlogVerbosity().
    112   int vlog_level_;
    113 };
    114 
    115 }  // namespace logging
    116 
    117 // These macros are for LOG() and related logging commands.
    118 #define LOG(level) logging::Log(level, #level, __FILE__, __LINE__)
    119 #define PLOG(level) logging::PLog(level, #level, __FILE__, __LINE__)
    120 #define VLOG(level) logging::VLog(level, __FILE__, __LINE__)
    121 
    122 // Some macros from libbase that we use.
    123 #define CHECK(x) \
    124   if (!(x)) LOG(FATAL) << #x
    125 #define CHECK_GT(x, y) \
    126   if (!(x > y)) LOG(FATAL) << #x << " > " << #y << "failed"
    127 #define CHECK_GE(x, y) \
    128   if (!(x >= y)) LOG(FATAL) << #x << " >= " << #y << "failed"
    129 #define CHECK_LE(x, y) \
    130   if (!(x <= y)) LOG(FATAL) << #x << " <= " << #y << "failed"
    131 #define CHECK_NE(x, y) \
    132   if (!(x != y)) LOG(FATAL) << #x << " != " << #y << "failed"
    133 #define CHECK_EQ(x, y) \
    134   if (!(x == y)) LOG(FATAL) << #x << " == " << #y << "failed"
    135 #define DLOG(x) LOG(x)
    136 #define DVLOG(x) VLOG(x)
    137 #define DCHECK(x) CHECK(x)
    138 
    139 #endif  // CHROMIUMOS_WIDE_PROFILING_MYBASE_BASE_LOGGING_H_
    140