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_