/* * Copyright (C) 2018-2019 Codership Oy * * This file is part of wsrep-lib. * * Wsrep-lib is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * Wsrep-lib is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with wsrep-lib. If not, see . */ #ifndef WSREP_LOGGER_HPP #define WSREP_LOGGER_HPP #include "mutex.hpp" #include "lock.hpp" #include "atomic.hpp" #include #include #define WSREP_LOG_DEBUG(debug_level_fn, debug_level, msg) \ do { \ if (debug_level_fn >= debug_level) wsrep::log_debug() << msg; \ } while (0) namespace wsrep { class log { public: enum level { debug, info, warning, error, unknown }; enum debug_level { debug_level_server_state = 1, debug_level_transaction, debug_level_streaming, debug_level_client_state }; /** * Signature for user defined logger callback function. * * @param pfx optional internally defined prefix for the message * @param msg message to log */ typedef void (*logger_fn_type)(level l, const char* pfx, const char* msg); static const char* to_c_string(enum level level) { switch (level) { case debug: return "debug"; case info: return "info"; case warning: return "warning"; case error: return "error"; case unknown: break; }; return "unknown"; } log(enum wsrep::log::level level, const char* prefix = "L:") : level_(level) , prefix_(prefix) , oss_() { } ~log() { if (logger_fn_) { // Prolong the lifetime of the string so it doesn't get // destroyed right after evaluating c_str() and before // completing the logger function call. const std::string& tmp = oss_.str(); logger_fn_(level_, prefix_, tmp.c_str()); } else { wsrep::unique_lock lock(mutex_); os_ << prefix_ << oss_.str() << std::endl; } } template std::ostream& operator<<(const T& val) { return (oss_ << val); } /** * Set user defined logger callback function. */ static void logger_fn(logger_fn_type); /** * Set debug log level from client */ static void debug_log_level(int debug_level); /** * Get current debug log level */ static int debug_log_level(); private: log(const log&); log& operator=(const log&); enum level level_; const char* prefix_; std::ostringstream oss_; static wsrep::mutex& mutex_; static std::ostream& os_; static logger_fn_type logger_fn_; static std::atomic_int debug_log_level_; }; class log_error : public log { public: log_error() : log(error) { } }; class log_warning : public log { public: log_warning() : log(warning) { } }; class log_info : public log { public: log_info() : log(info) { } }; class log_debug : public log { public: log_debug() : log(debug) { } }; } #endif // WSREP_LOGGER_HPP