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