1 /* 2 * Copyright (C) 2018-2019 Codership Oy <info@codership.com> 3 * 4 * This file is part of wsrep-lib. 5 * 6 * Wsrep-lib is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * Wsrep-lib is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef WSREP_LOGGER_HPP 21 #define WSREP_LOGGER_HPP 22 23 #include "mutex.hpp" 24 #include "lock.hpp" 25 #include "atomic.hpp" 26 27 #include <iosfwd> 28 #include <sstream> 29 30 #define WSREP_LOG_DEBUG(debug_level_fn, debug_level, msg) \ 31 do { \ 32 if (debug_level_fn >= debug_level) wsrep::log_debug() << msg; \ 33 } while (0) 34 35 namespace wsrep 36 { 37 class log 38 { 39 public: 40 enum level 41 { 42 debug, 43 info, 44 warning, 45 error, 46 unknown 47 }; 48 49 enum debug_level 50 { 51 debug_level_server_state = 1, 52 debug_level_transaction, 53 debug_level_streaming, 54 debug_level_client_state 55 }; 56 57 /** 58 * Signature for user defined logger callback function. 59 * 60 * @param pfx optional internally defined prefix for the message 61 * @param msg message to log 62 */ 63 typedef void (*logger_fn_type)(level l, 64 const char* pfx, const char* msg); 65 to_c_string(enum level level)66 static const char* to_c_string(enum level level) 67 { 68 switch (level) 69 { 70 case debug: return "debug"; 71 case info: return "info"; 72 case warning: return "warning"; 73 case error: return "error"; 74 case unknown: break; 75 }; 76 return "unknown"; 77 } 78 log(enum wsrep::log::level level,const char * prefix="L:")79 log(enum wsrep::log::level level, const char* prefix = "L:") 80 : level_(level) 81 , prefix_(prefix) 82 , oss_() 83 { } 84 ~log()85 ~log() 86 { 87 if (logger_fn_) 88 { 89 logger_fn_(level_, prefix_, oss_.str().c_str()); 90 } 91 else 92 { 93 wsrep::unique_lock<wsrep::mutex> lock(mutex_); 94 os_ << prefix_ << oss_.str() << std::endl; 95 } 96 } 97 98 template <typename T> operator <<(const T & val)99 std::ostream& operator<<(const T& val) 100 { 101 return (oss_ << val); 102 } 103 104 /** 105 * Set user defined logger callback function. 106 */ 107 static void logger_fn(logger_fn_type); 108 109 /** 110 * Set debug log level from client 111 */ 112 static void debug_log_level(int debug_level); 113 114 /** 115 * Get current debug log level 116 */ 117 static int debug_log_level(); 118 119 private: 120 log(const log&); 121 log& operator=(const log&); 122 enum level level_; 123 const char* prefix_; 124 std::ostringstream oss_; 125 static wsrep::mutex& mutex_; 126 static std::ostream& os_; 127 static logger_fn_type logger_fn_; 128 static std::atomic_int debug_log_level_; 129 }; 130 131 class log_error : public log 132 { 133 public: log_error()134 log_error() 135 : log(error) { } 136 }; 137 138 class log_warning : public log 139 { 140 public: log_warning()141 log_warning() 142 : log(warning) { } 143 }; 144 145 class log_info : public log 146 { 147 public: log_info()148 log_info() 149 : log(info) { } 150 }; 151 152 class log_debug : public log 153 { 154 public: log_debug()155 log_debug() 156 : log(debug) { } 157 }; 158 } 159 160 #endif // WSREP_LOGGER_HPP 161