ODIN
tjlog.h
1 /***************************************************************************
2  tjlog.h - description
3  -------------------
4  begin : Fri Aug 2 2002
5  copyright : (C) 2000-2021 by Thies H. Jochimsen
6  email : thies@jochimsen.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifndef TJLOG_H
19 #define TJLOG_H
20 
21 #ifndef TJUTILS_CONFIG_H
22 #define TJUTILS_CONFIG_H
23 #include <tjutils/config.h>
24 #endif
25 
26 #include <tjutils/tjutils.h>
27 #include <tjutils/tjstream.h>
28 #include <tjutils/tjhandler.h>
29 #include <tjutils/tjlabel.h>
30 #include <tjutils/tjstatic.h>
31 #include <tjutils/tjstring.h>
32 #include <tjutils/tjcstd.h>
33 
39 #define MAX_COMPONENT_SIZE 10
40 #define MAX_LOG_STRINGSIZE 25
41 
48 enum logPriority { noLog=0, errorLog, warningLog, infoLog, significantDebug, normalDebug, verboseDebug, numof_log_priorities, ignoreArgument};
49 static const char* logPriorityLabel[]={"noLog", "errorLog", "warningLog", "infoLog", "significantDebug", "normalDebug", "verboseDebug"};
50 AVOID_CC_WARNING(logPriorityLabel)
51 
52 
57 struct LogMessage {
58 
63 
67  STD_string comp;
68 
72  STD_string obj;
73 
77  STD_string func;
78 
82  STD_string txt;
83 
84 
90  STD_string str(unsigned int maxwidth=0, bool include_comp=true) const;
91 };
92 
94 
98 typedef void (*tracefunction)(const LogMessage& msg);
99 
100 
105 
107 
108 
109 // function pointer to get/set log levels in global map of logLevels
110 typedef logPriority (*log_component_fptr) (logPriority);
111 
113 
117 class LogBase : public virtual StaticHandler<LogBase> {
118 
119  public:
120 
121  LogBase() {} // for LogBaseoc
122 
123  LogBase(const char* component, const char* object, const Labeled* labeledObject, const char* function)
124  : compLabel(component), objLabel(object), namedObj(labeledObject), funcName(function) {}
125 
129  static void set_log_level(const char* compname, logPriority level);
130 
134  static void set_uniform_log_level(logPriority level);
135 
136 #ifndef NO_CMDLINE
140  static bool set_log_levels(int argc, char *argv[], bool trigger_error=true);
141 #endif
142 
146  static STD_string get_usage();
147 
148  // Functions to used by Log-component types
149  static bool register_component(const char*,log_component_fptr);
150  static void unregister_component(const char*);
151 
155  static const char* get_levels();
156 
160  static void set_levels(const char* str);
161 
166 
167 
168  // functions to initialize/delete static members by the StaticHandler template class
169  static void init_static();
170  static void destroy_static();
171 
172 
173 
174  protected:
175  friend class LogOneLine;
176 
177  // Cache only plain pointers for efficiency
178  const char* compLabel;
179  const char* objLabel; // Cache either the string
180  const Labeled* namedObj; // or the object to retrieve the label from
181  const char* funcName;
182 
183 
184  void flush_oneline(const STD_string& txt, logPriority level);
185 
186 #ifndef NO_CMDLINE
187  static void parse_log_cmdline_options(int argc, char *argv[], const char* opt, logPriority base);
188 #endif
189 
190 
191  // global (singleton) data
192  struct Global : public Labeled {
193  Global() : tracefunc(default_tracefunction), uniform_init_level(ignoreArgument) {}
194  tracefunction tracefunc;
195  STD_map<STD_string,log_component_fptr> components;
196  STD_map<STD_string,logPriority> init_level;
197  logPriority uniform_init_level;
198  };
199 
200  static SingletonHandler<Global,true> global; // Thread-safe singleton for global data
201 
202 
203  private:
204  friend class DebugDialog;
205 
206 };
207 
208 
210 
211 
217 template<class C>
218 class Log : public virtual LogBase {
219 
220  public:
221 
222 
230  Log(const char* objectLabel, const char* functionName, logPriority level=verboseDebug);
231 
232 
240  Log(const Labeled* labeledObject, const char* functionName, logPriority level=verboseDebug);
241 
242 
247  ~Log();
248 
249 
250  static logPriority set_log_level(logPriority level); // to be called via log_component_fptr function pointer
251  inline static logPriority get_log_level() {return logLevel;} // to be used by LogOneLine
252 
253 
254  private:
255 
256  logPriority constrLevel;
257 
258  void register_comp();
259 
260  static logPriority logLevel;
261  static bool registered; // call register_component only in 1st constructor
262 
263 };
264 
266 
267 // Temporary object to log one line via ostringstream
268 // This ingenious technique was presented by Petru Marginean in Dr.Dobb's under the title 'Logging in C++'
269 struct LogOneLine {
270 
271  public:
272  LogOneLine(LogBase& logobj, logPriority level) : log(logobj), lev(level) {}
273 
274  ~LogOneLine() {log.flush_oneline(oss.str(),lev);}
275 
276  STD_ostream& get_stream() {return oss;}
277 
278  private:
279  LogBase& log;
280  logPriority lev;
281  STD_ostringstream oss;
282 };
283 
285 
286 // Min level which is included in release compilation
287 #define RELEASE_LOG_LEVEL infoLog
288 
289 
290 #ifdef ODIN_DEBUG
291 
292 #define ODINLOG(logobj,level) \
293 if ((level) > (logobj).get_log_level()) ; \
294 else LogOneLine(logobj,level).get_stream()
295 
296 #else
297 
298 #define ODINLOG(logobj,level) \
299 if ((level) > RELEASE_LOG_LEVEL) ; \
300 else if ((level) > (logobj).get_log_level()) ; \
301  else LogOneLine(logobj,level).get_stream()
302 
303 #endif
304 
305 
308 #endif
Definition: tjlog.h:117
static void set_log_output_function(tracefunction func)
static bool set_log_levels(int argc, char *argv[], bool trigger_error=true)
static void set_levels(const char *str)
static void set_uniform_log_level(logPriority level)
static STD_string get_usage()
static const char * get_levels()
static void set_log_level(const char *compname, logPriority level)
Definition: tjlog.h:218
~Log()
Definition: tjlog_code.h:42
Log(const char *objectLabel, const char *functionName, logPriority level=verboseDebug)
Definition: tjlog_code.h:26
void(* tracefunction)(const LogMessage &msg)
Definition: tjlog.h:98
void default_tracefunction(const LogMessage &msg)
logPriority
Definition: tjlog.h:48
STD_string obj
Definition: tjlog.h:72
logPriority level
Definition: tjlog.h:62
STD_string txt
Definition: tjlog.h:82
STD_string comp
Definition: tjlog.h:67
STD_string str(unsigned int maxwidth=0, bool include_comp=true) const
STD_string func
Definition: tjlog.h:77