BayesOpt
log.hpp
Go to the documentation of this file.
1 
4 /*
5 -------------------------------------------------------------------------
6  This file is part of BayesOpt, an efficient C++ library for
7  Bayesian optimization.
8 
9  Copyright (C) 2011-2015 Ruben Martinez-Cantin <rmcantin@unizar.es>
10 
11  BayesOpt is free software: you can redistribute it and/or modify it
12  under the terms of the GNU Affero General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  BayesOpt is distributed in the hope that it will be useful, but
17  WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU Affero General Public License for more details.
20 
21  You should have received a copy of the GNU Affero General Public License
22  along with BayesOpt. If not, see <http://www.gnu.org/licenses/>.
23 ------------------------------------------------------------------------
24 */
25 /*
26  Original file obtained from:
27  Logging In C++
28  By Petru Marginean, September 05, 2007
29  http://www.drdobbs.com/cpp/logging-in-c/201804215
30 
31  Configure:
32  FILELog::ReportingLevel() = logDEBUG3;
33  FILE* log_fd = fopen( "mylogfile.txt", "w" );
34  Output2FILE::Stream() = log_fd;
35 
36  Usage:
37  FILE_LOG(logWARNING) << "Ops, variable x should be " << expectedX << "; is " << realX;
38 */
39 
40 #ifndef __LOG_HPP__
41 #define __LOG_HPP__
42 
43 #include <sstream>
44 #include <string>
45 #include <cstdio>
46 
47 
48 inline std::string NowTime();
49 
50 enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG,
51  logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
52 
53 template <typename T>
54 class Log
55 {
56 public:
57  Log();
58  virtual ~Log();
59  std::ostringstream& Get(TLogLevel level = logINFO);
60 public:
61  static TLogLevel& ReportingLevel();
62  static std::string ToString(TLogLevel level);
63  static TLogLevel FromString(const std::string& level);
64 protected:
65  std::ostringstream os;
66 private:
67  Log(const Log&);
68  Log& operator =(const Log&);
69 };
70 
71 template <typename T>
73 {
74 }
75 
76 template <typename T>
77 std::ostringstream& Log<T>::Get(TLogLevel level)
78 {
79  os << "- " << NowTime();
80  os << " " << ToString(level) << ": ";
81  os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
82  return os;
83 }
84 
85 template <typename T>
87 {
88  os << std::endl;
89  T::Output(os.str());
90 }
91 
92 template <typename T>
93 TLogLevel& Log<T>::ReportingLevel()
94 {
95  static TLogLevel reportingLevel = logDEBUG4;
96  return reportingLevel;
97 }
98 
99 template <typename T>
100 std::string Log<T>::ToString(TLogLevel level)
101 {
102  static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"};
103  return buffer[level];
104 }
105 
106 template <typename T>
107 TLogLevel Log<T>::FromString(const std::string& level)
108 {
109  if (level == "DEBUG4")
110  return logDEBUG4;
111  if (level == "DEBUG3")
112  return logDEBUG3;
113  if (level == "DEBUG2")
114  return logDEBUG2;
115  if (level == "DEBUG1")
116  return logDEBUG1;
117  if (level == "DEBUG")
118  return logDEBUG;
119  if (level == "INFO")
120  return logINFO;
121  if (level == "WARNING")
122  return logWARNING;
123  if (level == "ERROR")
124  return logERROR;
125  Log<T>().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
126  return logINFO;
127 }
128 
130 {
131 public:
132  static FILE*& Stream();
133  static void Output(const std::string& msg);
134 };
135 
136 inline FILE*& Output2FILE::Stream()
137 {
138  static FILE* pStream = stdout;
139  return pStream;
140 }
141 
142 inline void Output2FILE::Output(const std::string& msg)
143 {
144  FILE* pStream = Stream();
145  if (!pStream)
146  return;
147  fprintf(pStream, "%s", msg.c_str());
148  fflush(pStream);
149 }
150 
151 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
152 # if defined (BUILDING_FILELOG_DLL)
153 # define FILELOG_DECLSPEC __declspec (dllexport)
154 # elif defined (USING_FILELOG_DLL)
155 # define FILELOG_DECLSPEC __declspec (dllimport)
156 # else
157 # define FILELOG_DECLSPEC
158 # endif // BUILDING_DBSIMPLE_DLL
159 #else
160 # define FILELOG_DECLSPEC
161 #endif // _WIN32
162 
163 class FILELOG_DECLSPEC FILELog : public Log<Output2FILE> {};
164 //typedef Log<Output2FILE> FILELog;
165 
166 #ifndef FILELOG_MAX_LEVEL
167 #define FILELOG_MAX_LEVEL logDEBUG4
168 #endif
169 
170 #define FILE_LOG(level) \
171  if (level > FILELOG_MAX_LEVEL) ;\
172  else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream()) ; \
173  else FILELog().Get(level)
174 
175 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
176 
177 #ifndef NOMINMAX
178 # define NOMINMAX
179 #endif
180 #include <windows.h>
181 
182 inline std::string NowTime()
183 {
184  const int MAX_LEN = 200;
185  char buffer[MAX_LEN];
186  if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0,
187  "HH':'mm':'ss", buffer, MAX_LEN) == 0)
188  return "Error in NowTime()";
189 
190  char result[100] = {0};
191  static DWORD first = GetTickCount();
192  std::sprintf(result, "%s.%03ld", buffer, (long)(GetTickCount() - first) % 1000);
193  return result;
194 }
195 
196 #else
197 
198 #include <sys/time.h>
199 
200 inline std::string NowTime()
201 {
202  struct timeval tv;
203  gettimeofday(&tv, 0);
204  char buffer[11];
205  tm r = {0};
206  strftime(buffer, sizeof(buffer), "%X", localtime_r(&tv.tv_sec, &r));
207  char result[100] = {0};
208  std::sprintf(result, "%s.%06ld", buffer, (long)tv.tv_usec);
209  return result;
210 
211  // char buffer[11];
212  // time_t t;
213  // time(&t);
214  // tm r = {0};
215  // strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r));
216  // struct timeval tv;
217  // gettimeofday(&tv, 0);
218  // char result[100] = {0};
219  // std::sprintf(result, "%s.%03ld", buffer, (long)tv.tv_usec / 1000);
220  // return result;
221 }
222 
223 #endif //WIN32
224 
225 #endif //__LOG_H__
Definition: log.hpp:54
Definition: log.hpp:163