<commit_before>
#ifndef __EVENTRPC_LOGGER_H__
#define __EVENTRPC_LOGGER_H__

#include <sstream>
#include <iostream>
#include <string>
#include "base/base.h"
#include "base/noncopyable.h"
#include "util/singleton.h"

EVENTRPC_NAMESPACE_BEGIN

enum LogLevel {
  INFO = 0,
  WARN = 1,
  ERROR = 2,
  FATAL = 3,
  NUM_OF_LOG_LEVEL
};

#define COLOR_RED            "\033[0;31m"
#define COLOR_GREEN          "\033[0;32m"
#define COLOR_YELLOW         "\033[0;33m"
#define COLOR_BLUE           "\033[0;34m"
#define COLOR_PURPLE         "\033[0;35m"
#define COLOR_NONE           "\033[0m"
#define END_OF_COLOR         COLOR_NONE"\n"

extern const char *kLogColor[];
extern LogLevel kLogLevel;
extern void SetLogLevel(LogLevel log_level);

class Logger {
 public:
  Logger(const std::string &content, LogLevel log_level)
    : content_(content),
      log_level_(log_level) {
  }

  virtual ~Logger() {
  }

 private:
  DISALLOW_EVIL_CONSTRUCTOR(Logger);

 protected:
  const std::string &content_;
  LogLevel log_level_;
};

class StdoutLogger : public Logger {
 public:
  StdoutLogger(const std::string &content, LogLevel log_level)
    : Logger(content, log_level) {
  }

  virtual ~StdoutLogger() {
    std::cout << kLogColor[log_level_] << content_
      << END_OF_COLOR;
  }
};

#define STDOUT_LOG(log_level, content)                       \
  do{                                                           \
    if (log_level >= eventrpc::kLogLevel) {                   \
      std::ostringstream os;                                      \
      os << "[" << __FILE__ << ":" << __LINE__ << "]";       \
      os << content;                                                \
      StdoutLogger(os.str().c_str(), log_level);               \<commit_msg>add logger and logger unit test<commit_after>
#ifndef __EVENTRPC_LOGGER_H__
#define __EVENTRPC_LOGGER_H__

#include <sstream>
#include <iostream>
#include <string>
#include "base/base.h"
#include "base/noncopyable.h"
#include "util/singleton.h"

EVENTRPC_NAMESPACE_BEGIN

enum LogLevel {
  INFO = 0,
  WARN = 1,
  ERROR = 2,
  FATAL = 3,
  NUM_OF_LOG_LEVEL
};

#define COLOR_RED            "\033[0;31m"
#define COLOR_GREEN          "\033[0;32m"
#define COLOR_YELLOW         "\033[0;33m"
#define COLOR_BLUE           "\033[0;34m"
#define COLOR_PURPLE         "\033[0;35m"
#define COLOR_NONE           "\033[0m"
#define END_OF_COLOR         COLOR_NONE"\n"

extern const char *kLogColor[];
extern LogLevel kLogLevel;
extern void SetLogLevel(LogLevel log_level);

class Logger {
 public:
  Logger(const std::string &content, LogLevel log_level)
    : content_(content),
      log_level_(log_level) {
  }

  virtual ~Logger() {
  }

 private:
  DISALLOW_EVIL_CONSTRUCTOR(Logger);

 protected:
  const std::string &content_;
  LogLevel log_level_;
};

class StdoutLogger : public Logger {
 public:
  StdoutLogger(const std::string &content, LogLevel log_level)
    : Logger(content, log_level) {
  }

  virtual ~StdoutLogger() {
    std::cout << kLogColor[log_level_] << content_
      << END_OF_COLOR;
  }
};

#define CONSTRUCT_STRINGSTREAM(content) \
  std::ostringstream os;                                      \
  os << "[" << __FILE__ << ":" << __LINE__ << "]";       \
  os << content

#define STDOUT_LOG(log_level, content)                       \
  do{                                                           \
    if (log_level >= eventrpc::kLogLevel) {                   \
      CONSTRUCT_STRINGSTREAM(content);   \
      StdoutLogger(os.str().c_str(), log_level);               \
{'fraction_non_alphanumeric': 0.11947904869762174, 'fraction_numerical': 0.021517553793884484, 'mean_word_length': 2.355175688509022, 'pattern_counts': {'":': 2, '<': 45, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7460599', 'n_tokens_mistral': 1263, 'n_tokens_neox': 1193, 'n_words': 238}