10 #include <unordered_set>
11 #include <unordered_map>
14 #include "utils/string.h"
15 #include "utils/formatter.h"
16 #include "threads/mutex.h"
17 #include "threads/thread.h"
34 typedef std::chrono::time_point<std::chrono::system_clock> DateTime;
38 typedef std::shared_ptr<Handler> ptr;
41 void write_message(
Logger* logger,
43 const std::string& level,
44 const std::string& message);
47 virtual void do_write_message(
Logger* logger,
49 const std::string& level,
50 const std::string& message) = 0;
60 void do_write_message(
Logger* logger,
62 const std::string& level,
63 const std::string& message)
override;
73 void do_write_message(
Logger* logger,
75 const std::string& level,
76 const std::string& message);
77 std::string filename_;
78 std::ofstream stream_;
83 typedef std::shared_ptr<Logger> ptr;
87 Logger(
const std::string& name):
89 level_(LOG_LEVEL_DEBUG) {
93 void add_handler(Handler::ptr handler) {
95 handlers_.push_back(handler);
98 void verbose(
const std::string& text,
const std::string& file=
"None", int32_t line=-1) {
99 if(level_ < LOG_LEVEL_VERBOSE)
return;
101 write_message(
"VERBOSE",
"\x1b[97m" + text +
"\x1b[0m", file, line);
104 void debug(
const std::string& text,
const std::string& file=
"None", int32_t line=-1) {
105 if(level_ < LOG_LEVEL_DEBUG)
return;
107 write_message(
"DEBUG", text, file, line);
110 void info(
const std::string& text,
const std::string& file=
"None", int32_t line=-1) {
111 if(level_ < LOG_LEVEL_INFO)
return;
113 write_message(
"INFO",
"\x1b[36m" + text +
"\x1b[0m", file, line);
116 void warn(
const std::string& text,
const std::string& file=
"None", int32_t line=-1) {
117 if(level_ < LOG_LEVEL_WARN)
return;
119 write_message(
"WARN",
"\x1b[33m" + text +
"\x1b[0m", file, line);
122 void error(
const std::string& text,
const std::string& file=
"None", int32_t line=-1) {
123 if(level_ < LOG_LEVEL_ERROR)
return;
125 write_message(
"ERROR",
"\x1b[31m" + text +
"\x1b[0m", file, line);
128 void set_level(LogLevel level) {
132 LogLevel level()
const {
137 void write_message(
const std::string& level,
const std::string& text,
138 const std::string& file, int32_t line) {
141 s << thread::this_thread_id() <<
": ";
144 s << text <<
" (" << file <<
":" << line <<
")";
149 for(uint32_t i = 0; i < handlers_.size(); ++i) {
150 handlers_[i]->write_message(
this, std::chrono::system_clock::now(), level, s.str());
155 std::vector<Handler::ptr> handlers_;
160 Logger* get_logger(
const std::string& name);
162 void verbose(
const std::string& text,
const std::string& file=
"None", int32_t line=-1);
163 void debug(
const std::string& text,
const std::string& file=
"None", int32_t line=-1);
164 void info(
const std::string& text,
const std::string& file=
"None", int32_t line=-1);
165 void warn(
const std::string& text,
const std::string& file=
"None", int32_t line=-1);
166 void error(
const std::string& text,
const std::string& file=
"None", int32_t line=-1);
171 DebugScopedLog(
const std::string& text,
const std::string& file, uint32_t line):
174 debug(
smlt::Formatter(
"Enter: {0} ({1}, {2})").format(text, file, line));
189 #define S_VERBOSE(str, ...) \
190 smlt::verbose(_F(str).format(__VA_ARGS__), __FILE__, __LINE__)
192 #define S_DEBUG(str, ...) \
193 smlt::debug(_F(str).format(__VA_ARGS__), __FILE__, __LINE__)
195 #define S_INFO(str, ...) \
196 smlt::info(_F(str).format(__VA_ARGS__), __FILE__, __LINE__)
198 #define S_WARN(str, ...) \
199 smlt::warn(_F(str).format(__VA_ARGS__), __FILE__, __LINE__)
201 #define S_ERROR(str, ...) \
202 smlt::error(_F(str).format(__VA_ARGS__), __FILE__, __LINE__)
204 #define S_DEBUG_ONCE(str, ...) \
205 do { static char _done = 0; if(!_done++) smlt::debug(_F(str).format(__VA_ARGS__)); } while(0)
207 #define S_INFO_ONCE(str, ...) \
208 do { static char _done = 0; if(!_done++) smlt::info(_F(str).format(__VA_ARGS__)); } while(0)
210 #define S_WARN_ONCE(str, ...) \
211 do { static char _done = 0; if(!_done++) smlt::warn(_F(str).format(__VA_ARGS__)); } while(0)
213 #define S_ERROR_ONCE(str, ...) \
214 do { static char _done = 0; if(!_done++) smlt::error(_F(str).format(__VA_ARGS__)); } while(0)
218 #define S_VERBOSE(str, ...) \
219 smlt::verbose(_F(str).format(__VA_ARGS__))
221 #define S_DEBUG(str, ...) \
222 smlt::debug(_F(str).format(__VA_ARGS__))
224 #define S_INFO(str, ...) \
225 smlt::info(_F(str).format(__VA_ARGS__))
227 #define S_WARN(str, ...) \
228 smlt::warn(_F(str).format(__VA_ARGS__))
230 #define S_ERROR(str, ...) \
231 smlt::error(_F(str).format(__VA_ARGS__))
233 #define S_DEBUG_ONCE(str, ...) \
234 do { static char _done = 0; if(!_done++) smlt::debug(_F(str).format(__VA_ARGS__)); } while(0)
236 #define S_INFO_ONCE(str, ...) \
237 do { static char _done = 0; if(!_done++) smlt::info(_F(str).format(__VA_ARGS__)); } while(0)
239 #define S_WARN_ONCE(str, ...) \
240 do { static char _done = 0; if(!_done++) smlt::warn(_F(str).format(__VA_ARGS__)); } while(0)
242 #define S_ERROR_ONCE(str, ...) \
243 do { static char _done = 0; if(!_done++) smlt::error(_F(str).format(__VA_ARGS__)); } while(0)