57#include <snapdev/poison.h>
115pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER;
124bool g_log_locked =
false;
135bool g_log_recursive_initialized =
false;
150pthread_mutex_t g_log_recursive_mutex;
172 pthread_mutex_lock(&g_log_mutex);
173 g_log_callback = callback;
174 pthread_mutex_unlock(&g_log_mutex);
215 std::cerr <<
"fatal: could not create system mutex."
240 int err(pthread_mutex_lock(&g_log_mutex));
243 std::cerr <<
"fatal: the mutex lock in cppthread::logger::lock() generated error #"
246 pthread_mutex_unlock(&g_log_mutex);
250 if(!g_log_recursive_initialized)
252 g_log_recursive_initialized =
true;
254 pthread_mutexattr_t mattr;
255 err = pthread_mutexattr_init(&mattr);
258 std::cerr <<
"fatal: a mutex attribute structure could not be initialized, error #"
261 pthread_mutex_unlock(&g_log_mutex);
264 err = pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
267 std::cerr <<
"fatal: a mutex attribute structure type could not be setup, error #"
270 pthread_mutex_unlock(&g_log_mutex);
273 err = pthread_mutex_init(&g_log_recursive_mutex, &mattr);
276 std::cerr <<
"fatal: a mutex structure could not be initialized, error #"
279 pthread_mutex_unlock(&g_log_mutex);
282 err = pthread_mutexattr_destroy(&mattr);
285 std::cerr <<
"fatal: a mutex attribute structure could not be destroyed, error #"
288 pthread_mutex_unlock(&g_log_mutex);
292 err = pthread_mutex_unlock(&g_log_mutex);
295 std::cerr <<
"fatal: a mutex unlock generated error #"
305 err = pthread_mutex_lock(&g_log_recursive_mutex);
308 std::cerr <<
"fatal: a mutex lock generated error #"
319 err = pthread_mutex_unlock(&g_log_recursive_mutex);
322 std::cerr <<
"fatal: a mutex unlock generated error #"
350 std::cerr <<
"fatal: logger::unlock() called with g_log_locked == false"
355 g_log_locked =
false;
357 int err(pthread_mutex_unlock(&g_log_recursive_mutex));
360 std::cerr <<
"fatal: a mutex unlock generated error #"
363 pthread_mutex_unlock(&g_log_recursive_mutex);
409 if(level < log_level_t::debug
410 || level > log_level_t::fatal)
412 throw invalid_log_level(
413 "unknown log level ("
414 + std::to_string(
static_cast<int>(level))
419 if(
f_log.tellp() != 0)
422 throw invalid_log_level(
"log level specified when logger buffer is not empty.");
425 ++f_counters[
static_cast<int>(level)];
459 std::memset(f_counters, 0,
sizeof(f_counters));
485 if(level < log_level_t::debug
486 || level > log_level_t::fatal)
488 throw invalid_log_level(
489 "unknown log level ("
490 + std::to_string(
static_cast<int>(level))
494 return f_counters[
static_cast<int>(level)];
513 return f_counters[
static_cast<int>(log_level_t::error)]
514 + f_counters[
static_cast<int>(log_level_t::fatal)];
533 return f_counters[
static_cast<int>(log_level_t::warning)];
567 callback = g_log_callback;
570 f_log.str(std::string());
579 if(callback !=
nullptr)
581 callback(level, msg);
583 else if(level >= log_level_t::info)
589 msg =
to_string(level) +
": " + msg +
"\n";
614 case log_level_t::debug:
617 case log_level_t::info:
620 case log_level_t::warning:
623 case log_level_t::error:
626 case log_level_t::fatal:
629 case log_level_t::LOG_LEVEL_SIZE:
634 throw invalid_error(
"unknown log level ("
635 + std::to_string(
static_cast<int>(level))
std::uint32_t get_errors() const
Get the number of errors that occurred so far.
static void lock()
Lock the system so a log can be emitted properly.
void reset_counters()
Reset all the log message counters to zero.
std::uint32_t get_counter(log_level_t level) const
Get one of the level counters.
logger & end()
End the logger's message.
static void unlock()
Unlock the logger once we are done with it.
logger()
Initialize the logger.
logger & operator<<(log_level_t const &level)
Save the level at which to log this message.
std::stringstream f_log
The log message.
std::uint32_t get_warnings() const
Get the number of warnings that occurred so far.
log_level_t f_level
The level of this message.
Exceptions for the thread environment.
void create_system_mutex()
Function used to initialize the system mutex.
void set_log_callback(log_callback callback)
Set a callback function.
logger log
The logger object used to send logs out.
std::string to_string(log_level_t level)
Convert a log level to a string.
Declaration of the log class used to send error messages.
void(* log_callback)(log_level_t level, std::string const &message)
The log callback type definition.
log_level_t
The log level or severity.