rad  3.0.0
Log.h
Go to the documentation of this file.
1 /*
2  * Logging facility described by Petru Marginean at:
3  * http://www.drdobbs.com/cpp/logging-in-c/201804215
4  *
5  * Code adapted from
6  * ftp://ftp.drdobbs.com/sourcecode/ddj/2007/0710.zip
7  */
8 
9 /*
10  * $Id: Log.h 1139 2016-07-20 14:57:28Z landolfa $
11  */
12 
13 #ifndef SCXML4CPP_LOG_H
14 #define SCXML4CPP_LOG_H
15 
16 #include <log4cplus/logger.h>
17 #include <log4cplus/loggingmacros.h>
18 #include <log4cplus/configurator.h>
19 #include <log4cplus/version.h>
20 #if LOG4CPLUS_VERSION >= LOG4CPLUS_MAKE_VERSION(2,0,0)
21 #include <log4cplus/initializer.h>
22 #endif
23 #include <string>
24 
25 #ifdef NDEBUG
26 #define SCXML4CPP_LOG_TRACE()
27 #else
28 #define SCXML4CPP_LOG_TRACE() LOG4CPLUS_TRACE(scxml4cpp::GetLogger(), __FILE__ << " " << __FUNCTION__ << " " << __LINE__)
29 #endif
30 
31 #define SCXML4CPP_LOG_INFO(msg) LOG4CPLUS_INFO(scxml4cpp::GetLogger(), msg)
32 #define SCXML4CPP_LOG_DEBUG(msg) LOG4CPLUS_DEBUG(scxml4cpp::GetLogger(), msg)
33 #define SCXML4CPP_LOG_WARNING(msg) LOG4CPLUS_WARN(scxml4cpp::GetLogger(), msg)
34 #define SCXML4CPP_LOG_ERROR(msg) LOG4CPLUS_ERROR(scxml4cpp::GetLogger(), msg)
35 #define SCXML4CPP_LOG_FATAL(msg) LOG4CPLUS_FATAL(scxml4cpp::GetLogger(), msg)
36 
37 
38 namespace scxml4cpp {
39 
40 const std::string LOGGER_NAME = "scxml4cpp";
41 
42 void LogSetLevel(const std::string& levelName);
43 log4cplus::Logger& GetLogger();
44 
46 public:
47  inline LogInitializer() {
48 #if LOG4CPLUS_VERSION < LOG4CPLUS_MAKE_VERSION(2,0,0)
49  log4cplus::initialize();
50 #endif
51  log4cplus::BasicConfigurator().configure();
52  GetLogger().setLogLevel(log4cplus::INFO_LOG_LEVEL);
53  }
54 
55  inline ~LogInitializer() {
56 #if LOG4CPLUS_VERSION < LOG4CPLUS_MAKE_VERSION(2,0,0)
57  log4cplus::Logger::shutdown();
58 #endif
59  }
60 
61  LogInitializer(const LogInitializer&) = delete;
63 
64 private:
65 #if LOG4CPLUS_VERSION >= LOG4CPLUS_MAKE_VERSION(2,0,0)
66  log4cplus::Initializer mInitializer;
67 #endif
68 };
69 
70 } // namespace scxml4cpp
71 
72 
73 /*
74  * Obsolete logging.
75  */
76 #if 0
77 #include <sstream>
78 #include <string>
79 #include <stdio.h>
80 #include <sys/time.h>
81 
82 namespace scxml4cpp {
83 /*
84  * Supported Log Levels.
85  */
86 const int LOG_LEVEL_ERROR = 0;
87 const int LOG_LEVEL_WARNING = 1;
88 const int LOG_LEVEL_INFO = 2;
89 const int LOG_LEVEL_DEBUG = 3;
90 const int LOG_LEVEL_DEBUG1 = 4;
91 const int LOG_LEVEL_DEBUG2 = 5;
92 const int LOG_LEVEL_DEBUG3 = 6;
93 const int LOG_LEVEL_DEBUG4 = 7;
94 const int LOG_LEVEL_TRACE = 8;
95 const int LOG_MAX_LEVEL = LOG_LEVEL_TRACE;
96 
97 inline std::string LogNowTime();
98 
99 /*
100  * Log class.
101  * typename T is the output policy: stderr, stdout, Output2File, etc.
102  */
103 template <typename T> class Log
104 {
105  public:
106  Log() {}
107 
111  virtual ~Log() {
112  os << std::endl;
113  T::Output(os.str());
114  }
115 
120  inline std::ostringstream& Get(const int level = LOG_LEVEL_INFO) {
121  os << LogNowTime();
122  os << " " << ToString(level) << " ";
123  return os;
124  }
125 
129  inline static int& ReportingLevel() {
130  static int reportingLevel = LOG_LEVEL_INFO;
131  return reportingLevel;
132  }
133 
137  inline static std::string ToString(const int level) {
138  static const char* const buffer[] = {
139  "ERROR",
140  "WARNING",
141  "INFO",
142  "DEBUG",
143  "DEBUG1",
144  "DEBUG2",
145  "DEBUG3",
146  "DEBUG4",
147  "TRACE"
148  };
149  return (level >= LOG_LEVEL_ERROR && level <= LOG_MAX_LEVEL) ? buffer[level] : "INFO";
150  }
151 
155  inline static int FromString(const std::string& level) {
156  if (level == "TRACE")
157  return LOG_LEVEL_TRACE;
158  if (level == "DEBUG4")
159  return LOG_LEVEL_DEBUG4;
160  if (level == "DEBUG3")
161  return LOG_LEVEL_DEBUG3;
162  if (level == "DEBUG2")
163  return LOG_LEVEL_DEBUG2;
164  if (level == "DEBUG1")
165  return LOG_LEVEL_DEBUG1;
166  if (level == "DEBUG")
167  return LOG_LEVEL_DEBUG;
168  if (level == "INFO")
169  return LOG_LEVEL_INFO;
170  if (level == "WARNING")
171  return LOG_LEVEL_WARNING;
172  if (level == "ERROR")
173  return LOG_LEVEL_ERROR;
174  Log<T>().Get(LOG_LEVEL_WARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
175  return LOG_LEVEL_INFO;
176  }
177 
178  protected:
179  std::ostringstream os;
180 
181  private:
182  Log(const Log&);
183  Log& operator =(const Log&);
184 };
185 
189 class Output2FILE
190 {
191  public:
192  inline static FILE*& Stream() {
193  static FILE* pStream = stderr;
194  return pStream;
195  }
196 
197  static void Output(const std::string& msg) {
198  FILE* pStream = Stream();
199  if (!pStream) return;
200 
201  fprintf(pStream, "%s", msg.c_str());
202  fflush(pStream);
203  }
204 };
205 
209 inline void LogSetLevel(const std::string& levelName) {
210  Log<scxml4cpp::Output2FILE>::ReportingLevel() = Log<scxml4cpp::Output2FILE>::FromString(levelName);
211 }
212 
218 inline std::string LogNowTime()
219 {
220  char buffer[64];
221  time_t t;
222  time(&t);
223  tm r = {0};
224  strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", localtime_r(&t, &r));
225  struct timeval tv;
226  gettimeofday(&tv, 0);
227  char result[100] = {0};
228  sprintf(result, "%s.%06ld", buffer, (long)tv.tv_usec / 1000);
229  return result;
230 }
231 
232 } // namespace scxml4cpp
233 
237 #define SCXML4CPP_LOG(level) \
238  if (level > scxml4cpp::LOG_MAX_LEVEL) ; \
239  else if (level > scxml4cpp::Log<scxml4cpp::Output2FILE>::ReportingLevel() || !scxml4cpp::Output2FILE::Stream()) ; \
240  else scxml4cpp::Log<scxml4cpp::Output2FILE>().Get(level) << "scxml4cpp " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
241 
242 #define SCXML4CPP_LOG_TRACE() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_TRACE)
243 #define SCXML4CPP_LOG_DEBUG() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG)
244 #define SCXML4CPP_LOG_DEBUG1() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG1)
245 #define SCXML4CPP_LOG_DEBUG2() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG2)
246 #define SCXML4CPP_LOG_DEBUG3() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG3)
247 #define SCXML4CPP_LOG_DEBUG4() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG4)
248 #define SCXML4CPP_LOG_INFO() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_INFO)
249 #define SCXML4CPP_LOG_WARNING() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_WARNING)
250 #define SCXML4CPP_LOG_ERROR() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_ERROR)
251 #endif
252 
253 #endif //SCXML4CPP_LOG_H
scxml4cpp::LogInitializer::operator=
LogInitializer & operator=(const LogInitializer &)=delete
hellorad.level
level
Definition: hellorad.py:30
scxml4cpp
Definition: Action.h:36
rad::LOG_LEVEL_DEBUG1
@ LOG_LEVEL_DEBUG1
Definition: logger.hpp:161
rad::LOG_LEVEL_DEBUG2
@ LOG_LEVEL_DEBUG2
Definition: logger.hpp:162
scxml4cpp::LogInitializer::~LogInitializer
~LogInitializer()
Definition: Log.h:55
rad::LOG_LEVEL_DEBUG
@ LOG_LEVEL_DEBUG
Definition: logger.hpp:160
rad::LOG_LEVEL_TRACE
@ LOG_LEVEL_TRACE
Definition: logger.hpp:165
rad::LOG_LEVEL_DEBUG3
@ LOG_LEVEL_DEBUG3
Definition: logger.hpp:163
rad::LOG_LEVEL_WARNING
@ LOG_LEVEL_WARNING
Definition: logger.hpp:154
scxml4cpp::LogInitializer::LogInitializer
LogInitializer(const LogInitializer &)=delete
rad::LOG_LEVEL_DEBUG4
@ LOG_LEVEL_DEBUG4
Definition: logger.hpp:164
scxml4cpp::LogInitializer::LogInitializer
LogInitializer()
Definition: Log.h:47
scxml4cpp::LogSetLevel
void LogSetLevel(const std::string &levelName)
Definition: Log.cpp:33
rad::LOG_MAX_LEVEL
const int LOG_MAX_LEVEL
Definition: logger.hpp:168
rad::LOG_LEVEL_ERROR
@ LOG_LEVEL_ERROR
Definition: logger.hpp:153
scxml4cpp::GetLogger
log4cplus::Logger & GetLogger()
Definition: Log.cpp:41
rad::LOG_LEVEL_INFO
@ LOG_LEVEL_INFO
Definition: logger.hpp:159
scxml4cpp::LogInitializer
Definition: Log.h:45
scxml4cpp::LOGGER_NAME
const std::string LOGGER_NAME
Definition: Log.h:40