0

I have a log, which using like:

LOG(INFO) << "string";

defined like this:

#define LOG(status) LOG_##status.stream()
#define LOG_ERROR LOG_INFO
#define LOG_INFO LogMessage(__FILE__, __FUNCTION__, __LINE__, "I")
#define LOG_DEBUG LogMessage(__FILE__, __FUNCTION__, __LINE__, "D")
#define LOG_WARNING LogMessage(__FILE__, __FUNCTION__, __LINE__, "W")
#define LOG_FATAL LogMessageFatal(__FILE__, __FUNCTION__, __LINE__)
#define VLOG(level)                                                            \
  VLogMessage(__FILE__, __FUNCTION__, __LINE__, level).stream()

#define CHECK(x)                                                               \
  if (!(x))                                                                    \
  LogMessageFatal(__FILE__, __FUNCTION__, __LINE__).stream()                   \
      << "Check failed: " #x << ": " // NOLINT(*)

#define CHECK_EQ(x, y) _CHECK_BINARY(x, ==, y)
#define CHECK_NE(x, y) _CHECK_BINARY(x, !=, y)
#define CHECK_LT(x, y) _CHECK_BINARY(x, <, y)
#define CHECK_LE(x, y) _CHECK_BINARY(x, <=, y)
#define CHECK_GT(x, y) _CHECK_BINARY(x, >, y)
#define CHECK_GE(x, y) _CHECK_BINARY(x, >=, y)
#define _CHECK_BINARY(x, cmp, y) CHECK(x cmp y) << x << "!" #cmp << y << " "

using namespace std;
inline void gen_log(std::ostream &log_stream_, const char *file,
                    const char *func, int lineno, const char *level,
                    const int kMaxLen = 20) {
  const int len = strlen(file);
  std::string time_str;
  struct tm tm_time; // Time of creation of LogMessage
  time_t timestamp = time(NULL);
  localtime_r(&timestamp, &tm_time);
  struct timeval tv;
  gettimeofday(&tv, NULL);

  log_stream_ << level << ' ' << 1 + tm_time.tm_mon << '/' << tm_time.tm_mday
              << ' ' << tm_time.tm_hour << ':' << tm_time.tm_min << ':'
              << std::setw(2) << tm_time.tm_sec << '.' << std::setw(3)
              << tv.tv_usec / 1000 << " ";

  if (len > kMaxLen) {
    log_stream_ << "..." << file + len - kMaxLen << " " << func << ":" << lineno
                << "] ";
  } else {
    log_stream_ << file << " " << func << ":" << lineno << "] ";
  }
}

class LogMessage {
public:
  LogMessage(const char *file, const char *func, int lineno,
             const char *level = "I") {

    if (*level == 'I') {
#if LOG_LEVEL <= 1
      gen_log(log_stream_, file, func, lineno, level);
#else
      log_stream_ = std::stringstream(nullptr);
#endif
    } else if (*level == 'D') {
#if LOG_LEVEL <= 2
      gen_log(log_stream_, file, func, lineno, level);
#else
      log_stream_ = std::stringstream(nullptr);
#endif
    } else if (*level == 'W') {
#if LOG_LEVEL <= 3
      gen_log(log_stream_, file, func, lineno, level);
#else
      log_stream_ = std::stringstream(nullptr);
#endif
    }
  }
  ~LogMessage() {
    log_stream_ << '\n';
    fprintf(stderr, "%s", log_stream_.str().c_str());
  }
  std::ostream &stream() { return log_stream_; }

protected:
  std::stringstream log_stream_;
  LogMessage(const LogMessage &) = delete;
  void operator=(const LogMessage &) = delete;
};

Now, I want control all LOG not print out (all).

how should I do it?

IMO, I need send an empty stream, but the content after << how to make it being ignored?

Nicholas Jela
  • 2,540
  • 7
  • 24
  • 40
  • Write a custom `std::stringbuf`-derived class that ignores all data written to it, and then assign an instance of that class to your `log_stream_` object. – Remy Lebeau Jun 16 '22 at 15:43
  • I'm not sure where LOG_LEVEL is set, but it looks to me if you set it to 4 or higher then nothing will be logged. – Ferruccio Jun 16 '22 at 15:50
  • Maybe the [null output stream](https://stackoverflow.com/a/11826666/4641116)? – Eljay Jun 16 '22 at 16:09
  • @RemyLebeau Hi can u write a answer for me? IDE claims log_stream_ is none assignable – Nicholas Jela Jun 17 '22 at 02:20
  • @NicholasJela to assign a custom `streambuf` to a `stringstream`, you have to use the stream's [`rdbuf()`](https://en.cppreference.com/w/cpp/io/basic_ios/rdbuf) method. – Remy Lebeau Jun 17 '22 at 02:36

0 Answers0