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