Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
LogFacility.hh
1 #ifndef __LOGFACILITY_H__
2 #define __LOGFACILITY_H__
3 
4 #ifdef WIN32
5 # pragma once
6 #endif // WIN32
7 
8 #include <bias_config.h>
9 #include <Base/Common/FileHandling.hh>
10 #include <Base/Debug/TimeMeasure.hh>
11 #include <iostream>
12 #include <fstream>
13 #include <string>
14 
15 /*************************************************
16 @class LogFacility
17 
18 
19 @brief general class to handle logging in BIAS. Classes that want to
20 use logging have to be derived from LogFacility, set the Loglevel and
21 all logging will be send to the given stream (file/stdout...)
22 
23 The idea of LogFacility is, to set up a third stream (in addision to
24 cout and cerr) using a LogLevel-mechanism to control
25 verbosity. Appications and high-level libs can write information into
26 this stream depending on one global log-level. This stream ist sent
27 to cerr by default, but it can be redirected into a file or to any
28 rdbuf available.
29 
30 In Contrast to BIAS::Debug is also works for non-debug builds (#undef
31 BIAS_DEBUG). Lowlevel-lib (like here in BIAS and in MIP) should not
32 use this channel to discuss problems with the user.
33 
34 The LogLevel is an enum (therefor an int) with the following order:
35 BIAS_LOG_NONE < BIAS_LOG_FATAL < BIAS_LOG_WARNING < BIAS_LOG_INFO <
36 BIAS_LOG_DEBUG. Increasing the current LogLevel results in more
37 verbose reporting.
38 
39 To send a message the usage of one of the magic macros is
40 recommened. The generic macro is BIASLOG(x,y) with two parameters: x
41 is the log level and y is the message. Programmers should think
42 carefully which information belongs to which level. Time-critical code
43 sections should only use BIAS_LOG_DEBUG, while BIAS_LOG_NONE should
44 not be used in BIASLOG(). For convenience and to save space in the
45 code line the following abbreviations are available:
46 
47 BLF(x) : BIASLOG(BIAS_LOG_FATAL,x)
48 BLW(x) : BIASLOG(BIAS_LOG_WARNING,x)
49 BLI(x) : BIASLOG(BIAS_LOG_INFO,x)
50 BLD(x) : BIASLOG(BIAS_LOG_DEBUG,x)
51 
52 The flag bCodeInfo_ controls if file names and line numbers are shown.
53 
54 @author ischiller evers
55 @date 11/05
56 
57 *************************************************/
58 
59 #ifdef WIN32
60 # pragma warning (disable: 4127)
61 #endif
62 
63 //call BIASLOG(BIAS_LOG_LEVEL,"output")
64 #define BIASLOG(x,y){\
65  std::ostream _cods_(std::cout.rdbuf()); \
66  BIAS::LogFacility::Instance()->GetLogStream(_cods_); \
67  if(x<=BIAS::LogFacility::Instance()->GetLogLevel() && _cods_.good()) { \
68  if(BIAS::LogFacility::Instance()->GetShowCodeInfo()){ \
69  std::string file = BIAS::FileHandling::Filename(__FILE__);\
70  std::string time = BIAS::TimeMeasure::GetCurrentTimeAsString();\
71  std::string date = BIAS::TimeMeasure::GetDateAsString();\
72  _cods_<<date<<", "<<time<<": "<<file<<", "<< __LINE__ << " : ";\
73  }\
74  _cods_<<y<<std::endl<<std::flush; \
75  }\
76  if( BIAS::LogFacility::Instance()->GetAbortOnFatal() && x==BIAS::BIAS_LOG_FATAL){ \
77  _cods_<<"Aborting in "<<__FILE__<<", "<<__LINE__<<std::endl<<std::flush;\
78  abort();}\
79 }
80 
81 //if no logging level is given, always log to stream
82 #define BIASLOGALWAYS(y){\
83  std::ostream _cods_(std::cout.rdbuf()); \
84  this->GetLogStream(_cods_); \
85  if(x<=this->dLogLevel_ && _cods_.good()) { \
86  _cods_<<y<<std::endl; _cods_.flush();\
87  }\
88 }
89 
90 
91 
92 // for Kevin:
93 //#define PLAIN_COUT_LOGGING
94 
95 
96 #ifndef PLAIN_COUT_LOGGING
97 # define BLD(y) BIASLOG(BIAS::BIAS_LOG_DEBUG, y)
98 # define BLI(y) BIASLOG(BIAS::BIAS_LOG_INFO, y)
99 # define BLW(y) BIASLOG(BIAS::BIAS_LOG_WARNING, y)
100 # define BLF(y) BIASLOG(BIAS::BIAS_LOG_FATAL, y)
101 #else
102 # define BLD(y) cout<< y<<endl;
103 # define BLI(y) cout<< y<<endl;
104 # define BLW(y) cout<< y<<endl;
105 # define BLF(y) cout<< y<<endl;
106 #endif
107 
108 
109 namespace BIAS{
110 
111 
118  };
119 
120  class BIASDebug_EXPORT LogFacility
121  {
122  public:
123 
124  static LogFacility * Instance(){
125  if (pInstance_== NULL)
126  pInstance_ = new LogFacility;
127  return pInstance_;
128  };
129 
130  static void SetInstance(LogFacility *other);
131 
132  /// avoid memory leaks by explicit delete on instance JW
133  static void DeleteInstance();
134 
135  bool OpenLogFile(const std::string &sFileName){
136  if(zLogFileStream_.is_open())
137  zLogFileStream_.close();
138 
139  // zLogStream_.clear();
140 
141  zLogFileStream_.open(sFileName.c_str(), std::ios_base::out | std::ios_base::trunc);
142  if (zLogFileStream_)
143  zLogStream_.rdbuf(zLogFileStream_.rdbuf());
144  return true;
145  };
146 
147  bool SetLogLevel(BIAS_LOG_LEVEL dLogLevel){
148  dLogLevel_ = dLogLevel;
149  return true;
150  };
151 
153  return dLogLevel_;
154  };
155 
156  bool SetLogStream(std::ostream zStream){
157  if (zLogFileStream_.is_open())
158  zLogFileStream_.close();
159  zLogStream_.rdbuf(zStream.rdbuf());
160  return true;
161  };
162 
163  inline bool GetLogStream(std::ostream &zStream){
164  zStream.rdbuf(zLogStream_.rdbuf());
165  return true;
166  };
167 
168  inline std::ostream & GetLogStream(){
169 
170  return zLogStream_;
171  };
172 
173  bool ResetStream(){
174  if(zLogFileStream_.is_open())
175  zLogFileStream_.close();
176  zLogStream_.rdbuf(std::cerr.rdbuf());
177  return true;
178  };
179 
180  inline void PrintLogLevel(){
181  zLogStream_<<"current log level is ";
182  switch (dLogLevel_)
183  {
184  case BIAS_LOG_NONE: zLogStream_<<"BIAS_LOG_NONE"<<std::endl; break;
185  case BIAS_LOG_FATAL: zLogStream_<<"BIAS_LOG_FATAL"<<std::endl; break;
186  case BIAS_LOG_WARNING: zLogStream_<<"BIAS_LOG_WARNING"<<std::endl; break;
187  case BIAS_LOG_INFO: zLogStream_<<"BIAS_LOG_INFO"<<std::endl; break;
188  case BIAS_LOG_DEBUG: zLogStream_<<"BIAS_LOG_DEBUG"<<std::endl; break;
189  }
190  };
191 
192  inline void SetShowCodeInfo(bool b) {
193  bCodeInfo_ = b;
194  };
195  inline bool GetShowCodeInfo(){
196  return bCodeInfo_;
197  };
198 
199  inline void SetAbortOnFatal(bool b) {
200  bAbortOnFatal_ = b;
201  };
202  inline bool GetAbortOnFatal(){
203  return bAbortOnFatal_;
204  };
205 
206  protected:
207  /// no one can inherit from me
208  LogFacility(void);
209 
210  /// no one can copy me
211  LogFacility(const LogFacility &l);
212  LogFacility &operator=(const LogFacility &l);
213 
215  {
216  if (zLogFileStream_.is_open()) {
217  zLogFileStream_.close();
218  zLogStream_.rdbuf(std::cerr.rdbuf());
219  }
220  };
221 
222 
223  //the Stream to write logging to
224  std::ostream zLogStream_;
225  //the int holding the LogLevel
227 
228  std::ofstream zLogFileStream_;
231 
233 
234  };
235 }// end namespace
236 #endif
237 
bool OpenLogFile(const std::string &sFileName)
Definition: LogFacility.hh:135
BIAS_LOG_LEVEL
Definition: LogFacility.hh:112
void SetShowCodeInfo(bool b)
Definition: LogFacility.hh:192
bool SetLogStream(std::ostream zStream)
Definition: LogFacility.hh:156
static LogFacility * Instance()
Definition: LogFacility.hh:124
bool SetLogLevel(BIAS_LOG_LEVEL dLogLevel)
Definition: LogFacility.hh:147
static LogFacility * pInstance_
Definition: LogFacility.hh:232
void SetAbortOnFatal(bool b)
Definition: LogFacility.hh:199
BIAS_LOG_LEVEL dLogLevel_
Definition: LogFacility.hh:226
std::ostream & GetLogStream()
Definition: LogFacility.hh:168
BIAS_LOG_LEVEL GetLogLevel()
Definition: LogFacility.hh:152
bool GetLogStream(std::ostream &zStream)
Definition: LogFacility.hh:163
std::ofstream zLogFileStream_
Definition: LogFacility.hh:228