|
00001 00049 #ifndef EZLOGGER_HPP_HEADER_GRD_ 00050 #define EZLOGGER_HPP_HEADER_GRD_ 00051 00060 #include <iostream> 00061 #include <sstream> 00062 #include <string> 00063 #include <stdio.h> 00064 00065 #include "ezlogger_misc.hpp" 00066 00067 namespace axter 00068 { 00077 struct levels : public ext_data 00078 { 00079 levels(verbosity verbosity_level, severity severity_level, 00080 const char* pretty_function = NULL, const char* facility = NULL, 00081 const char* tag = NULL, int code = 0) 00082 :ext_data(severity_level, pretty_function, facility, tag, code), 00083 m_verbosity_level(verbosity_level){} 00084 verbosity m_verbosity_level; 00085 }; 00086 00087 template<class EZLOGGER_OUTPUT_POLICY = ezlogger_output_policy, 00088 class EZLOGGER_FORMAT_POLICY = ezlogger_format_policy, 00089 class EZLOGGER_VERBOSITY_LEVEL_POLICY = ezlogger_verbosity_level_policy> 00090 class ezlogger : public EZLOGGER_OUTPUT_POLICY, public EZLOGGER_FORMAT_POLICY, public EZLOGGER_VERBOSITY_LEVEL_POLICY 00091 { 00092 public: 00093 inline ezlogger(const char*filename, int lineno, const char*functionname, 00094 verbosity verbosity_level = log_default_verbosity_level, 00095 bool isstreamoutput = false, std::ostream* alternate_output = NULL) 00096 :m_src_file_name(filename), m_src_line_num(lineno), 00097 m_src_function_name(functionname), m_verbosity_level(verbosity_level), 00098 m_levels_format_usage(no_severity), m_alternate_output(alternate_output) 00099 { 00100 common_constructor_imp(isstreamoutput); 00101 } 00102 00103 inline ezlogger(const char*filename, int lineno, const char*functionname, 00104 levels levels_data, bool isstreamoutput = false, std::ostream* alternate_output = NULL) 00105 :m_src_file_name(filename), m_src_line_num(lineno), 00106 m_src_function_name(functionname), m_verbosity_level(levels_data.m_verbosity_level), 00107 m_levels_format_usage(levels_data), m_alternate_output(alternate_output) 00108 { 00109 common_constructor_imp(isstreamoutput); 00110 } 00111 00112 template<typename T> inline ezlogger& operator<<(T& Data) { 00113 if (m_verbosity_level <= get_verbosity_level_tolerance()) 00114 { 00115 if (m_alternate_output) 00116 (*m_alternate_output) << Data; 00117 else 00118 get_log_stream() << Data; 00119 } 00120 return *this; 00121 } 00122 inline ezlogger& operator<<(std::ostream& (*func)(std::ostream&)) 00123 { 00124 if (m_verbosity_level <= get_verbosity_level_tolerance()) 00125 { 00126 if (m_alternate_output) 00127 (*m_alternate_output) << func; 00128 else 00129 get_log_stream() << func; 00130 } 00131 return *this; 00132 } 00133 00134 template<class T> void operator()(const T&Data) const{ 00135 if (m_verbosity_level <= get_verbosity_level_tolerance()) 00136 log_out(m_src_file_name, m_src_line_num, m_src_function_name, m_levels_format_usage, true, Data); 00137 } 00138 template<class T1, class T2> 00139 void operator()(const T1 &Data1, const T2 &Data2) const{ 00140 if (m_verbosity_level <= get_verbosity_level_tolerance()) 00141 log_out(m_src_file_name, m_src_line_num, m_src_function_name, m_levels_format_usage, true, Data1, Data2); 00142 } 00143 template<class T1, class T2, class T3> 00144 void operator()(const T1 &Data1, const T2 &Data2, const T3 &Data3) const{ 00145 if (m_verbosity_level <= get_verbosity_level_tolerance()) 00146 log_out(m_src_file_name, m_src_line_num, m_src_function_name, m_levels_format_usage, true, Data1, Data2, Data3); 00147 } 00148 #ifndef EZLOGGER_EXCLUDE_CPRINT_METHOD 00149 void cprint(const char * format, ...) 00150 { 00151 if (m_verbosity_level <= get_verbosity_level_tolerance()) 00152 { 00153 char Data[4096]; 00154 va_list v; 00155 va_start(v,format); 00156 _vsnprintf(Data, sizeof(Data), format,v); 00157 va_end(v); 00158 log_out(m_src_file_name, m_src_line_num, m_src_function_name, m_levels_format_usage, true, Data); 00159 } 00160 } 00161 #endif //EZLOGGER_EXCLUDE_CPRINT_METHOD 00162 template<class T1> 00163 void prg_main_arg(int argc, T1 argv) 00164 { 00165 if (m_verbosity_level <= get_verbosity_level_tolerance()) 00166 { 00167 std::string Data = "main() arg(s) {"; 00168 for (int i = 0;i < argc;++i) {Data += " arg#" + to_str(i) + " = '" + to_str(argv[i]) + "' ";} 00169 Data += "}"; 00170 std::string PrgCallSig = " Program Call Signature --->> " + to_str(argv[0]); 00171 for (int ii = 1;ii < argc;++ii) {PrgCallSig += " \"" + to_str(argv[ii]) + "\"";} 00172 00173 log_out(m_src_file_name, m_src_line_num, m_src_function_name, m_levels_format_usage, true, Data + PrgCallSig); 00174 } 00175 } 00176 void display_stack() 00177 { 00178 if (m_verbosity_level <= get_verbosity_level_tolerance()) 00179 { 00180 display_stack_main(m_src_line_num); 00181 } 00182 } 00183 bool log_if_fails_verification(bool eval, const char* evaluation) 00184 { 00185 if (!eval && m_verbosity_level <= get_verbosity_level_tolerance()) 00186 get_log_stream() << get_log_prefix_format(m_src_file_name, m_src_line_num, m_src_function_name, m_levels_format_usage) << 00187 "Failed verification: '" << evaluation << "'" << std::endl; 00188 return eval; 00189 } 00190 00191 00192 static const std::string to_str(const wchar_t *Data) 00193 { 00194 if (!Data) return std::string("Error: Bad pointer"); 00195 const int SizeDest = (int)wcslen(Data); 00196 char *AnsiStr = new char[SizeDest+1]; 00197 wcstombs(AnsiStr, Data, SizeDest); 00198 AnsiStr[SizeDest] = 0; 00199 std::stringstream ss; 00200 ss << AnsiStr; 00201 delete [] AnsiStr; 00202 return ss.str(); 00203 } 00204 static const std::string to_str(wchar_t *Data) 00205 { 00206 if (!Data) return std::string("Error: Bad pointer"); 00207 const int SizeDest = (int)wcslen(Data); 00208 char *AnsiStr = new char[SizeDest+1]; 00209 wcstombs(AnsiStr, Data, SizeDest); 00210 AnsiStr[SizeDest] = 0; 00211 std::stringstream ss; 00212 ss << AnsiStr; 00213 delete [] AnsiStr; 00214 return ss.str(); 00215 } 00216 static const std::string to_str(const std::wstring &Data){return to_str(Data.c_str());} 00217 template<class T> 00218 static const std::string to_str(const T &Data) 00219 { 00220 std::stringstream ss; 00221 ss << Data; 00222 return ss.str(); 00223 } 00224 static const std::string to_str(){return std::string();} 00225 protected: 00226 const char* m_src_file_name; 00227 int m_src_line_num; 00228 const char* m_src_function_name; 00229 verbosity m_verbosity_level; 00230 ext_data m_levels_format_usage; 00231 std::ostream* m_alternate_output; 00232 inline void common_constructor_imp(bool isstreamoutput) 00233 { 00234 if (isstreamoutput && m_verbosity_level <= get_verbosity_level_tolerance()) 00235 { 00236 if (m_alternate_output) 00237 (*m_alternate_output) << get_log_prefix_format(m_src_file_name, m_src_line_num, m_src_function_name, m_levels_format_usage); 00238 else 00239 get_log_stream() << get_log_prefix_format(m_src_file_name, m_src_line_num, m_src_function_name, m_levels_format_usage); 00240 } 00241 } 00242 00243 template<class T> 00244 static void log_out(const char*FileName, int LineNo, const char*FunctionName, 00245 ext_data levels_format_usage_data, bool endline, const T &Data) 00246 { 00247 get_log_stream() << get_log_prefix_format(FileName, LineNo, FunctionName, levels_format_usage_data) << to_str(Data); 00248 if (endline) get_log_stream() << std::endl; 00249 } 00250 template<class T1, class T2> 00251 static void log_out(const char*FileName, int LineNo, const char*FunctionName, 00252 ext_data levels_format_usage_data, bool endline, const T1 &Data1, const T2 &Data2) 00253 { 00254 get_log_stream() << get_log_prefix_format(FileName, LineNo, FunctionName, levels_format_usage_data) << to_str(Data1) << ", " << to_str(Data2); 00255 if (endline) get_log_stream() << std::endl; 00256 } 00257 template<class T1, class T2, class T3> 00258 static void log_out(const char*FileName, int LineNo, const char*FunctionName, 00259 ext_data levels_format_usage_data, bool endline, const T1 &Data1, const T2 &Data2, const T3 &Data3) 00260 { 00261 get_log_stream() << get_log_prefix_format(FileName, LineNo, FunctionName, levels_format_usage_data) << to_str(Data1) << ", " << to_str(Data2) << ", " << to_str(Data3); 00262 if (endline) get_log_stream() << std::endl; 00263 } 00264 }; 00265 00266 class ezfunction_tracker : public ezlogger<> 00267 { 00268 public: 00269 inline ezfunction_tracker(const char*filename, int lineno, const char*functionname, 00270 verbosity verbosity_level = log_default_verbosity_level, 00271 bool isstreamoutput = false, std::ostream* alternate_output = NULL) 00272 :ezlogger<>(filename, lineno, functionname, verbosity_level, isstreamoutput, alternate_output) 00273 { 00274 operator()("Entering function ", m_src_function_name); 00275 add_to_stack(m_src_function_name); 00276 } 00277 inline ~ezfunction_tracker() 00278 { 00279 operator()("Exiting function ", m_src_function_name); 00280 pop_stack(); 00281 } 00282 private: 00283 ezfunction_tracker(const ezfunction_tracker&); 00284 ezfunction_tracker& operator=(const ezfunction_tracker&); 00285 }; 00286 } 00287 00321 #endif //EZLOGGER_HPP_HEADER_GRD_