Crow  0.3
A C++ microframework for the web
logging.h
1 #pragma once
2 
3 #include <string>
4 #include <cstdio>
5 #include <cstdlib>
6 #include <ctime>
7 #include <iostream>
8 #include <sstream>
9 
10 #include "crow/settings.h"
11 
12 namespace crow
13 {
14  enum class LogLevel
15  {
16 #ifndef ERROR
17 #ifndef DEBUG
18  DEBUG = 0,
19  INFO,
20  WARNING,
21  ERROR,
22  CRITICAL,
23 #endif
24 #endif
25 
26  Debug = 0,
27  Info,
28  Warning,
29  Error,
30  Critical,
31  };
32 
33  class ILogHandler {
34  public:
35  virtual void log(std::string message, LogLevel level) = 0;
36  };
37 
38  class CerrLogHandler : public ILogHandler {
39  public:
40  void log(std::string message, LogLevel /*level*/) override {
41  std::cerr << message;
42  }
43  };
44 
45  class logger {
46 
47  private:
48  //
49  static std::string timestamp()
50  {
51  char date[32];
52  time_t t = time(0);
53 
54  tm my_tm;
55 
56 #if defined(_MSC_VER) || defined(__MINGW32__)
57  gmtime_s(&my_tm, &t);
58 #else
59  gmtime_r(&t, &my_tm);
60 #endif
61 
62  size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &my_tm);
63  return std::string(date, date+sz);
64  }
65 
66  public:
67 
68 
69  logger(std::string prefix, LogLevel level) : level_(level) {
70  #ifdef CROW_ENABLE_LOGGING
71  stringstream_ << "(" << timestamp() << ") [" << prefix << "] ";
72  #endif
73 
74  }
75  ~logger() {
76  #ifdef CROW_ENABLE_LOGGING
77  if(level_ >= get_current_log_level()) {
78  stringstream_ << std::endl;
79  get_handler_ref()->log(stringstream_.str(), level_);
80  }
81  #endif
82  }
83 
84  //
85  template <typename T>
86  logger& operator<<(T const &value) {
87 
88  #ifdef CROW_ENABLE_LOGGING
89  if(level_ >= get_current_log_level()) {
90  stringstream_ << value;
91  }
92  #endif
93  return *this;
94  }
95 
96  //
97  static void setLogLevel(LogLevel level) {
98  get_log_level_ref() = level;
99  }
100 
101  static void setHandler(ILogHandler* handler) {
102  get_handler_ref() = handler;
103  }
104 
105  static LogLevel get_current_log_level() {
106  return get_log_level_ref();
107  }
108 
109  private:
110  //
111  static LogLevel& get_log_level_ref()
112  {
113  static LogLevel current_level = static_cast<LogLevel>(CROW_LOG_LEVEL);
114  return current_level;
115  }
116  static ILogHandler*& get_handler_ref()
117  {
118  static CerrLogHandler default_handler;
119  static ILogHandler* current_handler = &default_handler;
120  return current_handler;
121  }
122 
123  //
124  std::ostringstream stringstream_;
125  LogLevel level_;
126  };
127 }
128 
129 #define CROW_LOG_CRITICAL \
130  if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
131  crow::logger("CRITICAL", crow::LogLevel::Critical)
132 #define CROW_LOG_ERROR \
133  if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
134  crow::logger("ERROR ", crow::LogLevel::Error)
135 #define CROW_LOG_WARNING \
136  if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
137  crow::logger("WARNING ", crow::LogLevel::Warning)
138 #define CROW_LOG_INFO \
139  if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
140  crow::logger("INFO ", crow::LogLevel::Info)
141 #define CROW_LOG_DEBUG \
142  if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
143  crow::logger("DEBUG ", crow::LogLevel::Debug)
144 
crow::CerrLogHandler
Definition: logging.h:38
crow::ILogHandler
Definition: logging.h:33
crow::logger
Definition: logging.h:45