00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef TJLOG_H
00019 #define TJLOG_H
00020
00021 #ifndef TJUTILS_CONFIG_H
00022 #define TJUTILS_CONFIG_H
00023 #include <tjutils/config.h>
00024 #endif
00025
00026 #include <tjutils/tjutils.h>
00027 #include <tjutils/tjstream.h>
00028 #include <tjutils/tjhandler.h>
00029 #include <tjutils/tjlabel.h>
00030 #include <tjutils/tjstatic.h>
00031 #include <tjutils/tjstring.h>
00032 #include <tjutils/tjcstd.h>
00033
00039 #define MAX_COMPONENT_SIZE 10
00040 #define MAX_LOG_STRINGSIZE 25
00041
00048 enum logPriority { noLog=0, errorLog, warningLog, infoLog, significantDebug, normalDebug, verboseDebug, numof_log_priorities, ignoreArgument};
00049 static const char* logPriorityLabel[]={"noLog", "errorLog", "warningLog", "infoLog", "significantDebug", "normalDebug", "verboseDebug"};
00050
00051
00053
00057 struct LogMessage {
00058
00062 logPriority level;
00063
00067 STD_string comp;
00068
00072 STD_string obj;
00073
00077 STD_string func;
00078
00082 STD_string txt;
00083
00084
00090 STD_string str(unsigned int maxwidth=0, bool include_comp=true) const;
00091 };
00092
00094
00098 typedef void (*tracefunction)(const LogMessage& msg);
00099
00100
00104 void default_tracefunction(const LogMessage& msg);
00105
00107
00108
00109
00110 typedef logPriority (*log_component_fptr) (logPriority);
00111
00113
00117 class LogBase : public virtual StaticHandler<LogBase> {
00118
00119 public:
00120
00121 LogBase() {}
00122
00123 LogBase(const char* component, const char* object, const Labeled* labeledObject, const char* function)
00124 : compLabel(component), objLabel(object), namedObj(labeledObject), funcName(function) {}
00125
00129 static void set_log_level(const char* compname, logPriority level);
00130
00134 static void set_uniform_log_level(logPriority level);
00135
00136 #ifndef NO_CMDLINE
00137
00140 static bool set_log_levels(int argc, char *argv[], bool trigger_error=true);
00141 #endif
00142
00146 static STD_string get_usage();
00147
00148
00149 static bool register_component(const char*,log_component_fptr);
00150 static void unregister_component(const char*);
00151
00155 static const char* get_levels();
00156
00160 static void set_levels(const char* str);
00161
00165 static void set_log_output_function(tracefunction func);
00166
00167
00168
00169 static void init_static();
00170 static void destroy_static();
00171
00172
00173
00174 protected:
00175 friend class LogOneLine;
00176
00177
00178 const char* compLabel;
00179 const char* objLabel;
00180 const Labeled* namedObj;
00181 const char* funcName;
00182
00183
00184 void flush_oneline(const STD_string& txt, logPriority level);
00185
00186 #ifndef NO_CMDLINE
00187 static void parse_log_cmdline_options(int argc, char *argv[], const char* opt, logPriority base);
00188 #endif
00189
00190
00191
00192 struct Global : public Labeled {
00193 Global() : tracefunc(default_tracefunction), uniform_init_level(ignoreArgument) {}
00194 tracefunction tracefunc;
00195 STD_map<STD_string,log_component_fptr> components;
00196 STD_map<STD_string,logPriority> init_level;
00197 logPriority uniform_init_level;
00198 };
00199
00200 static SingletonHandler<Global,true> global;
00201
00202
00203 private:
00204 friend class DebugDialog;
00205
00206 };
00207
00208
00210
00211
00217 template<class C>
00218 class Log : public virtual LogBase {
00219
00220 public:
00221
00222
00230 Log(const char* objectLabel, const char* functionName, logPriority level=verboseDebug);
00231
00232
00240 Log(const Labeled* labeledObject, const char* functionName, logPriority level=verboseDebug);
00241
00242
00247 ~Log();
00248
00249
00250 static logPriority set_log_level(logPriority level);
00251 inline static logPriority get_log_level() {return logLevel;}
00252
00253
00254 private:
00255
00256 logPriority constrLevel;
00257
00258 void register_comp();
00259
00260 static logPriority logLevel;
00261 static bool registered;
00262
00263 };
00264
00266
00267
00268
00269 struct LogOneLine {
00270
00271 public:
00272 LogOneLine(LogBase& logobj, logPriority level) : log(logobj), lev(level) {}
00273
00274 ~LogOneLine() {log.flush_oneline(oss.str(),lev);}
00275
00276 STD_ostream& get_stream() {return oss;}
00277
00278 private:
00279 LogBase& log;
00280 logPriority lev;
00281 STD_ostringstream oss;
00282 };
00283
00285
00286
00287 #define RELEASE_LOG_LEVEL infoLog
00288
00289
00290 #ifdef ODIN_DEBUG
00291
00292 #define ODINLOG(logobj,level) \
00293 if ((level) > (logobj).get_log_level()) ; \
00294 else LogOneLine(logobj,level).get_stream()
00295
00296 #else
00297
00298 #define ODINLOG(logobj,level) \
00299 if ((level) > RELEASE_LOG_LEVEL) ; \
00300 else if ((level) > (logobj).get_log_level()) ; \
00301 else LogOneLine(logobj,level).get_stream()
00302
00303 #endif
00304
00305
00308 #endif