Adaptagrams
cola_log.h
1 /*
2  * vim: ts=4 sw=4 et tw=0 wm=0
3  *
4  * libcola - A library providing force-directed network layout using the
5  * stress-majorization method subject to separation constraints.
6  *
7  * Copyright (C) 2006-2008 Monash University
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  * See the file LICENSE.LGPL distributed with the library.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18  *
19 */
20 
21 /*
22 Logging code from DJJ article: http://www.ddj.com/cpp/201804215.
23 
24 Title: Logging In C++
25 Author: Petru Marginean
26 Keywords: OCT07 C++
27 Description: Unpublished source code accompanying the article by Petru Marginean, in which he presents a C++ logging framework that is typesafe, thread-safe, and portable.
28  */
29 #ifndef __COLA_LOG_H__
30 #define __COLA_LOG_H__
31 
32 #include <sstream>
33 #include <string>
34 #include <cstdio>
35 #include <iomanip>
36 
37 namespace cola {
38 inline std::string NowTime();
39 
40 enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
41 
42 template <typename T>
43 class Log
44 {
45 public:
46  Log();
47  virtual ~Log();
48  std::ostringstream& Get(TLogLevel level = logINFO);
49 public:
50  static TLogLevel& ReportingLevel();
51  static std::string ToString(TLogLevel level);
52  static TLogLevel FromString(const std::string& level);
53 protected:
54  std::ostringstream os;
55 private:
56  Log(const Log&);
57  Log& operator =(const Log&);
58 };
59 
60 template <typename T>
61 Log<T>::Log()
62 {
63 }
64 
65 template <typename T>
66 std::ostringstream& Log<T>::Get(TLogLevel level)
67 {
68  os << "- " << NowTime();
69  os << " " << ToString(level) << ": ";
70  os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
71  return os;
72 }
73 
74 template <typename T>
75 Log<T>::~Log()
76 {
77  os << std::endl;
78  T::Output(os.str());
79 }
80 
81 template <typename T>
82 TLogLevel& Log<T>::ReportingLevel()
83 {
84  static TLogLevel reportingLevel = cola::logDEBUG4;
85  return reportingLevel;
86 }
87 
88 template <typename T>
89 std::string Log<T>::ToString(TLogLevel level)
90 {
91  static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"};
92  return buffer[level];
93 }
94 
95 template <typename T>
96 TLogLevel Log<T>::FromString(const std::string& level)
97 {
98  if (level == "DEBUG4")
99  return logDEBUG4;
100  if (level == "DEBUG3")
101  return logDEBUG3;
102  if (level == "DEBUG2")
103  return logDEBUG2;
104  if (level == "DEBUG1")
105  return logDEBUG1;
106  if (level == "DEBUG")
107  return logDEBUG;
108  if (level == "INFO")
109  return logINFO;
110  if (level == "WARNING")
111  return logWARNING;
112  if (level == "ERROR")
113  return logERROR;
114  Log<T>().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
115  return logINFO;
116 }
117 
118 class Output2FILE
119 {
120 public:
121  static FILE*& Stream();
122  static void Output(const std::string& msg);
123 };
124 
125 inline FILE*& Output2FILE::Stream()
126 {
127  static FILE* pStream = stderr;
128  return pStream;
129 }
130 
131 inline void Output2FILE::Output(const std::string& msg)
132 {
133  FILE* pStream = Stream();
134  if (!pStream)
135  return;
136  fprintf(pStream, "%s", msg.c_str());
137  fflush(pStream);
138 }
139 
140 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
141 # if defined (BUILDING_FILELOG_DLL)
142 # define FILELOG_DECLSPEC __declspec (dllexport)
143 # elif defined (USING_FILELOG_DLL)
144 # define FILELOG_DECLSPEC __declspec (dllimport)
145 # else
146 # define FILELOG_DECLSPEC
147 # endif // BUILDING_DBSIMPLE_DLL
148 #else
149 # define FILELOG_DECLSPEC
150 #endif // _WIN32
151 
152 class FILELOG_DECLSPEC FILELog : public Log<Output2FILE> {};
153 //typedef Log<Output2FILE> FILELog;
154 
155 #ifndef FILELOG_MAX_LEVEL
156 #define FILELOG_MAX_LEVEL cola::logDEBUG4
157 #endif
158 
159 #define FILE_LOG(level) \
160  if (level > FILELOG_MAX_LEVEL) ;\
161  else if (level > cola::FILELog::ReportingLevel() || !cola::Output2FILE::Stream()) ; \
162  else cola::FILELog().Get(level)
163 
164 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
165 
166 #include <windows.h>
167 
168 inline std::string NowTime()
169 {
170  const int MAX_LEN = 200;
171  char buffer[MAX_LEN];
172  if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0,
173  "HH':'mm':'ss", buffer, MAX_LEN) == 0)
174  return "Error in NowTime()";
175 
176  static DWORD first = GetTickCount();
177  std::stringstream result;
178  result << buffer << "." << std::setfill('0') << std::setw(3) << ((long)(GetTickCount() - first) % 1000);
179  return result.str();
180 }
181 
182 #else
183 
184 #include <sys/time.h>
185 
186 inline std::string NowTime()
187 {
188  char buffer[11];
189  time_t t;
190  time(&t);
191  tm r;
192  strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r));
193  struct timeval tv;
194  gettimeofday(&tv, 0);
195  std::stringstream result;
196  result << buffer << "." << std::setfill('0') << std::setw(3) << ((long)tv.tv_usec / 1000);
197  return result.str();
198 }
199 
200 #endif //WIN32
201 
202 } // namespace cola
203 
204 #endif //__COLA_LOG_H__
libcola: Force-directed network layout subject to separation constraints library. ...
Definition: box.cpp:25