ifw  0.0.1-dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 __LOG_H__
14 #define __LOG_H__
15 
16 #include <sstream>
17 #include <string>
18 #include <stdio.h>
19 #include <sys/time.h>
20 
21 namespace scxml4cpp {
22 
23 /*
24  * Supported Log Levels.
25  */
26 const int LOG_LEVEL_ERROR = 0;
27 const int LOG_LEVEL_WARNING = 1;
28 const int LOG_LEVEL_INFO = 2;
29 const int LOG_LEVEL_DEBUG = 3;
30 const int LOG_LEVEL_DEBUG1 = 4;
31 const int LOG_LEVEL_DEBUG2 = 5;
32 const int LOG_LEVEL_DEBUG3 = 6;
33 const int LOG_LEVEL_DEBUG4 = 7;
34 const int LOG_LEVEL_TRACE = 8;
36 
37 inline std::string LogNowTime();
38 
39 /*
40  * Log class.
41  * typename T is the output policy: stderr, stdout, Output2File, etc.
42  */
43 template <typename T> class Log
44 {
45  public:
46  Log() {}
47 
51  virtual ~Log() {
52  os << std::endl;
53  T::Output(os.str());
54  }
55 
60  inline std::ostringstream& Get(const int level = LOG_LEVEL_INFO) {
61  os << LogNowTime();
62  os << " " << ToString(level) << " ";
63  return os;
64  }
65 
69  inline static int& ReportingLevel() {
70  static int reportingLevel = LOG_LEVEL_INFO;
71  return reportingLevel;
72  }
73 
77  inline static std::string ToString(const int level) {
78  static const char* const buffer[] = {
79  "ERROR",
80  "WARNING",
81  "INFO",
82  "DEBUG",
83  "DEBUG1",
84  "DEBUG2",
85  "DEBUG3",
86  "DEBUG4",
87  "TRACE"
88  };
89  return (level >= LOG_LEVEL_ERROR && level <= LOG_MAX_LEVEL) ? buffer[level] : "INFO";
90  }
91 
95  inline static int FromString(const std::string& level) {
96  if (level == "TRACE")
97  return LOG_LEVEL_TRACE;
98  if (level == "DEBUG4")
99  return LOG_LEVEL_DEBUG4;
100  if (level == "DEBUG3")
101  return LOG_LEVEL_DEBUG3;
102  if (level == "DEBUG2")
103  return LOG_LEVEL_DEBUG2;
104  if (level == "DEBUG1")
105  return LOG_LEVEL_DEBUG1;
106  if (level == "DEBUG")
107  return LOG_LEVEL_DEBUG;
108  if (level == "INFO")
109  return LOG_LEVEL_INFO;
110  if (level == "WARNING")
111  return LOG_LEVEL_WARNING;
112  if (level == "ERROR")
113  return LOG_LEVEL_ERROR;
114  Log<T>().Get(LOG_LEVEL_WARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
115  return LOG_LEVEL_INFO;
116  }
117 
118  protected:
119  std::ostringstream os;
120 
121  private:
122  Log(const Log&);
123  Log& operator =(const Log&);
124 };
125 
130 {
131  public:
132  inline static FILE*& Stream() {
133  static FILE* pStream = stderr;
134  return pStream;
135  }
136 
137  static void Output(const std::string& msg) {
138  FILE* pStream = Stream();
139  if (!pStream) return;
140 
141  fprintf(pStream, "%s", msg.c_str());
142  fflush(pStream);
143  }
144 };
145 
149 inline void LogSetLevel(const std::string& levelName) {
151 }
152 
158 inline std::string LogNowTime()
159 {
160  char buffer[64];
161  time_t t;
162  time(&t);
163  tm r = {0};
164  strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", localtime_r(&t, &r));
165  struct timeval tv;
166  gettimeofday(&tv, 0);
167  char result[100] = {0};
168  sprintf(result, "%s.%06ld", buffer, (long)tv.tv_usec / 1000);
169  return result;
170 }
171 
172 } // namespace scxml4cpp
173 
177 #define SCXML4CPP_LOG(level) \
178  if (level > scxml4cpp::LOG_MAX_LEVEL) ; \
179  else if (level > scxml4cpp::Log<scxml4cpp::Output2FILE>::ReportingLevel() || !scxml4cpp::Output2FILE::Stream()) ; \
180  else scxml4cpp::Log<scxml4cpp::Output2FILE>().Get(level) << "scxml4cpp " << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
181 
182 #define SCXML4CPP_LOG_TRACE() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_TRACE)
183 #define SCXML4CPP_LOG_DEBUG() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG)
184 #define SCXML4CPP_LOG_DEBUG1() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG1)
185 #define SCXML4CPP_LOG_DEBUG2() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG2)
186 #define SCXML4CPP_LOG_DEBUG3() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG3)
187 #define SCXML4CPP_LOG_DEBUG4() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_DEBUG4)
188 #define SCXML4CPP_LOG_INFO() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_INFO)
189 #define SCXML4CPP_LOG_WARNING() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_WARNING)
190 #define SCXML4CPP_LOG_ERROR() SCXML4CPP_LOG(scxml4cpp::LOG_LEVEL_ERROR)
191 
192 
193 #endif //__LOG_H__
const int LOG_LEVEL_WARNING
Definition: Log.h:27
void LogSetLevel(const std::string &levelName)
Definition: Log.h:149
std::ostringstream os
Definition: Log.h:119
static int FromString(const std::string &level)
Definition: Log.h:95
static std::string ToString(const int level)
Definition: Log.h:77
const int LOG_LEVEL_DEBUG2
Definition: Log.h:31
const int LOG_LEVEL_DEBUG1
Definition: Log.h:30
virtual ~Log()
Definition: Log.h:51
static int & ReportingLevel()
Definition: Log.h:69
optional string msg
Definition: topics.proto:7
const int LOG_LEVEL_DEBUG4
Definition: Log.h:33
Definition: Log.h:129
static void Output(const std::string &msg)
Definition: Log.h:137
static FILE *& Stream()
Definition: Log.h:132
const int LOG_LEVEL_TRACE
Definition: Log.h:34
Definition: Log.h:43
const int LOG_LEVEL_INFO
Definition: Log.h:28
const int LOG_LEVEL_DEBUG
Definition: Log.h:29
std::ostringstream & Get(const int level=LOG_LEVEL_INFO)
Definition: Log.h:60
std::string LogNowTime()
Definition: Log.h:158
const int LOG_LEVEL_ERROR
Definition: Log.h:26
Log()
Definition: Log.h:46
const int LOG_MAX_LEVEL
Definition: Log.h:35
const int LOG_LEVEL_DEBUG3
Definition: Log.h:32