44 Level level = LOGGER_INFO;
52 virtual void flush() {}
54 inline void debug(
char* message) { debug(std::string_view(message)); }
55 inline void debug(
const char* message) { debug(std::string_view(message)); }
56 inline void debug(std::string& message) { debug(std::string_view(message)); }
57 inline void debug(
const std::string& message) { debug(std::string_view(message)); }
59 void debug(
const std::string_view& str)
61 if (level > LOGGER_DEBUG)
return;
63 std::scoped_lock<std::mutex> lock(_mutex);
64 debug_implementation(str);
67 template<
typename... Args>
68 void debug(Args&&... args)
70 if (level > LOGGER_DEBUG)
return;
72 std::scoped_lock<std::mutex> lock(_mutex);
75 (_stream << ... << args);
77 debug_implementation(_stream.str());
80 inline void info(
char* message) { info(std::string_view(message)); }
81 inline void info(
const char* message) { info(std::string_view(message)); }
82 inline void info(std::string& message) { info(std::string_view(message)); }
83 inline void info(
const std::string& message) { info(std::string_view(message)); }
85 void info(
const std::string_view& str)
87 if (level > LOGGER_INFO)
return;
89 std::scoped_lock<std::mutex> lock(_mutex);
90 info_implementation(str);
93 template<
typename... Args>
94 void info(Args&&... args)
96 if (level > LOGGER_INFO)
return;
98 std::scoped_lock<std::mutex> lock(_mutex);
101 (_stream << ... << args);
103 info_implementation(_stream.str());
106 inline void warn(
char* message) { warn(std::string_view(message)); }
107 inline void warn(
const char* message) { warn(std::string_view(message)); }
108 inline void warn(std::string& message) { warn(std::string_view(message)); }
109 inline void warn(
const std::string& message) { warn(std::string_view(message)); }
111 void warn(
const std::string_view& str)
113 if (level > LOGGER_WARN)
return;
115 std::scoped_lock<std::mutex> lock(_mutex);
116 warn_implementation(str);
119 template<
typename... Args>
120 void warn(Args&&... args)
122 if (level > LOGGER_WARN)
return;
124 std::scoped_lock<std::mutex> lock(_mutex);
127 (_stream << ... << args);
129 warn_implementation(_stream.str());
132 inline void error(
char* message) { error(std::string_view(message)); }
133 inline void error(
const char* message) { error(std::string_view(message)); }
134 inline void error(std::string& message) { error(std::string_view(message)); }
135 inline void error(
const std::string& message) { error(std::string_view(message)); }
137 void error(
const std::string_view& str)
139 if (level > LOGGER_DEBUG)
return;
141 std::scoped_lock<std::mutex> lock(_mutex);
142 error_implementation(str);
145 template<
typename... Args>
146 void error(Args&&... args)
148 if (level > LOGGER_ERROR)
return;
150 std::scoped_lock<std::mutex> lock(_mutex);
153 (_stream << ... << args);
155 error_implementation(_stream.str());
158 inline void fatal(
char* message) { fatal(std::string_view(message)); }
159 inline void fatal(
const char* message) { fatal(std::string_view(message)); }
160 inline void fatal(std::string& message) { fatal(std::string_view(message)); }
161 inline void fatal(
const std::string& message) { fatal(std::string_view(message)); }
163 void fatal(
const std::string_view& str)
165 if (level > LOGGER_DEBUG)
return;
167 std::scoped_lock<std::mutex> lock(_mutex);
168 fatal_implementation(str);
171 template<
typename... Args>
172 void fatal(Args&&... args)
174 if (level > LOGGER_ERROR)
return;
176 std::scoped_lock<std::mutex> lock(_mutex);
179 (_stream << ... << args);
181 fatal_implementation(_stream.str());
184 using PrintToStreamFunction = std::function<void(std::ostream&)>;
202 inline void log(Level msg_level,
char* message) {
log(msg_level, std::string_view(message)); }
203 inline void log(Level msg_level,
const char* message) { log(msg_level, std::string_view(message)); }
204 inline void log(Level msg_level, std::string& message) { log(msg_level, std::string_view(message)); }
205 inline void log(Level msg_level,
const std::string& message) { log(msg_level, std::string_view(message)); }
207 void log(Level msg_level,
const std::string_view& message);
210 template<
typename... Args>
211 void log(Level msg_level, Args... args)
213 if (level > msg_level)
return;
215 std::scoped_lock<std::mutex> lock(_mutex);
218 (_stream << ... << args);
222 case (LOGGER_DEBUG): debug_implementation(_stream.str());
break;
223 case (LOGGER_INFO): info_implementation(_stream.str());
break;
224 case (LOGGER_WARN): warn_implementation(_stream.str());
break;
225 case (LOGGER_ERROR): error_implementation(_stream.str());
break;
226 case (LOGGER_FATAL): fatal_implementation(_stream.str());
break;
232 void log_stream(Level msg_level, PrintToStreamFunction print);
238 std::ostringstream _stream;
240 std::unique_ptr<std::streambuf> _override_cout;
241 std::unique_ptr<std::streambuf> _override_cerr;
242 std::streambuf* _original_cout =
nullptr;
243 std::streambuf* _original_cerr =
nullptr;
245 virtual void debug_implementation(
const std::string_view& message) = 0;
246 virtual void info_implementation(
const std::string_view& message) = 0;
247 virtual void warn_implementation(
const std::string_view& message) = 0;
248 virtual void error_implementation(
const std::string_view& message) = 0;
249 virtual void fatal_implementation(
const std::string_view& message) = 0;
367 std::string debugPrefix =
"debug: ";
368 std::string infoPrefix =
"info: ";
369 std::string warnPrefix =
"Warning: ";
370 std::string errorPrefix =
"ERROR: ";
371 std::string fatalPrefix =
"FATAL: ";
373 void flush()
override;
376 void print_id(FILE* out, std::thread::id
id);
378 void debug_implementation(
const std::string_view& message)
override;
379 void info_implementation(
const std::string_view& message)
override;
380 void warn_implementation(
const std::string_view& message)
override;
381 void error_implementation(
const std::string_view& message)
override;
382 void fatal_implementation(
const std::string_view& message)
override;
384 std::map<std::thread::id, std::string> _threadPrefixes;