0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Logger.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
29 #ifndef Common_Logger_h
30 #define Common_Logger_h
31 
32 #include "Error.h"
33 #include "String.h"
34 
35 #include <iostream>
36 #include <signal.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 
40 #include "FixedStream.h"
41 
42 namespace Hypertable {
43 
45 namespace Logger {
46 
52  namespace Priority {
53  enum {
54  EMERG = 0,
55  FATAL = 0,
56  ALERT = 1,
57  CRIT = 2,
58  ERROR = 3,
59  WARN = 4,
60  NOTICE = 5,
61  INFO = 6,
62  DEBUG = 7,
63  NOTSET = 8
64  };
65  } // namespace Priority
66 
70  class LogWriter {
71  public:
76  LogWriter(const String &name)
77  : m_show_line_numbers(true), m_test_mode(false), m_name(name),
78  m_priority(Priority::INFO), m_file(stdout) {
79  }
80 
83  void set_level(int level) {
84  m_priority = level;
85  }
86 
88  int get_level() const {
89  return m_priority;
90  }
91 
93  bool is_enabled(int level) const {
94  return level <= m_priority;
95  }
96 
100  void set_test_mode(int fd = -1) {
101  if (fd != -1)
102  m_file = fdopen(fd, "wt");
103  m_show_line_numbers = false;
104  m_test_mode = true;
105  }
106 
108  bool show_line_numbers() const {
109  return m_show_line_numbers;
110  }
111 
113  void flush() {
114  fflush(m_file);
115  }
116 
118  void debug(const char *format, ...);
119 
121  void debug(const String &message) {
122  log(Priority::DEBUG, message);
123  }
124 
126  void log(int priority, const char *format, ...);
127 
129  void log(int priority, const String &message) {
130  log_string(priority, message.c_str());
131  }
132 
133  private:
135  void log_string(int priority, const char *message);
136 
138  void log_varargs(int priority, const char *format, va_list ap);
139 
142 
145 
148 
151 
153  FILE *m_file;
154  };
155 
159  extern void initialize(const String &name);
160 
162  extern LogWriter *get();
163 
166 }} // namespace Hypertable::Logger
167 
168 
169 #define HT_LOG_BUFSZ 1024
170 
171 /* The HT_ABORT macro terminates the application and generates a core dump */
172 #ifdef HT_USE_ABORT
173 # define HT_ABORT abort()
174 #else
175 #define HT_ABORT raise(SIGABRT)
176 #endif
177 
178 // printf interface macro helper; do not use directly
179 #define HT_LOG(priority, msg) do { \
180  if (Logger::get()->is_enabled(priority)) { \
181  if (Logger::get()->show_line_numbers()) \
182  Logger::get()->log(priority, Hypertable::format( \
183  "(%s:%d) %s", __FILE__, __LINE__, msg)); \
184  else \
185  Logger::get()->log(priority, msg); \
186  } \
187 } while (0)
188 
189 #define HT_LOGF(priority, fmt, ...) do { \
190  if (Logger::get()->is_enabled(priority)) { \
191  if (Logger::get()->show_line_numbers()) \
192  Logger::get()->log(priority, Hypertable::format( \
193  "(%s:%d) " fmt, __FILE__, __LINE__, __VA_ARGS__)); \
194  else \
195  Logger::get()->log(priority, Hypertable::format( \
196  fmt, __VA_ARGS__)); \
197  } \
198 } while (0)
199 
200 // stream interface macro helpers
201 #define HT_LOG_BUF_SIZE 4096
202 
203 #define HT_OUT(priority) do { if (Logger::get()->is_enabled(priority)) { \
204  char logbuf[HT_LOG_BUF_SIZE]; \
205  int _priority_ = Logger::get()->get_level(); \
206  FixedOstream _out_(logbuf, sizeof(logbuf)); \
207  if (Logger::get()->show_line_numbers()) \
208  _out_ <<"("<< __FILE__ <<':'<< __LINE__ <<") "; \
209  _out_
210 
211 #define HT_OUT2(priority) do { if (Logger::get()->is_enabled(priority)) { \
212  char logbuf[HT_LOG_BUF_SIZE]; \
213  int _priority_ = priority; \
214  FixedOstream _out_(logbuf, sizeof(logbuf)); \
215  _out_ << __func__; \
216  if (Logger::get()->show_line_numbers()) \
217  _out_ << " ("<< __FILE__ <<':'<< __LINE__ <<")"; \
218  _out_ <<": "
219 
220 #define HT_END ""; Logger::get()->log(_priority_, _out_.str()); \
221  if (_priority_ == Logger::Priority::FATAL) HT_ABORT; \
222 } /* if enabled */ } while (0)
223 
224 #define HT_OUT_DISABLED do { if (0) {
225 
226 // helpers for printing a char pointer field
227 #define HT_DUMP_CSTR(_os_, _label_, _str_) do { \
228  if (!_str_) _os_ <<" " #_label_ "=[NULL]"; \
229  else _os_ <<" " #_label_ "='"<< (_str_) << "'"; \
230 } while (0)
231 
232 #define HT_DUMP_CSTR_FIELD(_os_, _obj_, _field_) \
233  HT_DUMP_CSTR(_os_, _field_, _obj_._field_)
234 
235 
236 // Logging macros interface starts here
237 #ifndef HT_DISABLE_LOG_ALL
238 
239 #ifndef HT_DISABLE_LOG_DEBUG
240 
241 #define HT_LOG_ENTER do { \
242  if (Logger::get()->is_enabled(Logger::Priority::DEBUG)) {\
243  if (Logger::get()->show_line_numbers()) \
244  Logger::get()->debug("(%s:%d) %s() ENTER", __FILE__, __LINE__, HT_FUNC);\
245  else \
246  Logger::get()->debug("%s() ENTER", HT_FUNC); \
247  } \
248 } while(0)
249 
250 #define HT_LOG_EXIT do { \
251  if (Logger::get()->is_enabled(Logger::Priority::DEBUG)) { \
252  if (Logger::get()->show_line_numbers()) \
253  Logger::get()->debug("(%s:%d) %s() EXIT", __FILE__, __LINE__, HT_FUNC); \
254  else \
255  Logger::get()->debug("%s() EXIT", HT_FUNC); \
256  } \
257 } while(0)
258 
259 #define HT_DEBUG(msg) HT_LOG(Logger::Priority::DEBUG, msg)
260 #define HT_DEBUGF(msg, ...) HT_LOGF(Logger::Priority::DEBUG, msg, __VA_ARGS__)
261 #define HT_DEBUG_OUT HT_OUT2(Logger::Priority::DEBUG)
262 #else
263 #define HT_LOG_ENTER
264 #define HT_LOG_EXIT
265 #define HT_DEBUG(msg)
266 #define HT_DEBUGF(msg, ...)
267 #define HT_DEBUG_OUT HT_OUT_DISABLED
268 #endif
269 
270 #ifndef HT_DISABLE_LOG_INFO
271 #define HT_INFO(msg) HT_LOG(Logger::Priority::INFO, msg)
272 #define HT_INFOF(msg, ...) HT_LOGF(Logger::Priority::INFO, msg, __VA_ARGS__)
273 #else
274 #define HT_INFO(msg)
275 #define HT_INFOF(msg, ...)
276 #endif
277 
278 #ifndef HT_DISABLE_LOG_NOTICE
279 #define HT_NOTICE(msg) HT_LOG(Logger::Priority::NOTICE, msg)
280 #define HT_NOTICEF(msg, ...) HT_LOGF(Logger::Priority::NOTICE, msg, __VA_ARGS__)
281 #define HT_NOTICE_OUT HT_OUT(Logger::Priority::NOTICE)
282 #else
283 #define HT_NOTICE(msg)
284 #define HT_NOTICEF(msg, ...)
285 #define HT_NOTICE_OUT HT_OUT_DISABLED
286 #endif
287 
288 #ifndef HT_DISABLE_LOG_WARN
289 #define HT_WARN(msg) HT_LOG(Logger::Priority::WARN, msg)
290 #define HT_WARNF(msg, ...) HT_LOGF(Logger::Priority::WARN, msg, __VA_ARGS__)
291 #define HT_WARN_OUT HT_OUT2(Logger::Priority::WARN)
292 #else
293 #define HT_WARN(msg)
294 #define HT_WARNF(msg, ...)
295 #define HT_WARN_OUT HT_OUT_DISABLED
296 #endif
297 
298 #ifndef HT_DISABLE_LOG_ERROR
299 #define HT_ERROR(msg) HT_LOG(Logger::Priority::ERROR, msg)
300 #define HT_ERRORF(msg, ...) HT_LOGF(Logger::Priority::ERROR, msg, __VA_ARGS__)
301 #define HT_ERROR_OUT HT_OUT2(Logger::Priority::ERROR)
302 #else
303 #define HT_ERROR(msg)
304 #define HT_ERRORF(msg, ...)
305 #define HT_ERROR_OUT HT_OUT_DISABLED
306 #endif
307 
308 #ifndef HT_DISABLE_LOG_CRIT
309 #define HT_CRIT(msg) HT_LOG(Logger::Priority::CRIT, msg)
310 #define HT_CRITF(msg, ...) HT_LOGF(Logger::Priority::CRIT, msg, __VA_ARGS__)
311 #define HT_CRIT_OUT HT_OUT2(Logger::Priority::CRIT)
312 #else
313 #define HT_CRIT(msg)
314 #define HT_CRITF(msg, ...)
315 #define HT_CRIT_OUT HT_OUT_DISABLED
316 #endif
317 
318 #ifndef HT_DISABLE_LOG_ALERT
319 #define HT_ALERT(msg) HT_LOG(Logger::Priority::ALERT, msg)
320 #define HT_ALERTF(msg, ...) HT_LOGF(Logger::Priority::ALERT, msg, __VA_ARGS__)
321 #define HT_ALERT_OUT HT_OUT2(Logger::Priority::ALERT)
322 #else
323 #define HT_ALERT(msg)
324 #define HT_ALERTF(msg, ...)
325 #define HT_ALERT_OUT HT_OUT_DISABLED
326 #endif
327 
328 #ifndef HT_DISABLE_LOG_EMERG
329 #define HT_EMERG(msg) HT_LOG(Logger::Priority::EMERG, msg)
330 #define HT_EMERGF(msg, ...) HT_LOGF(Logger::Priority::EMERG, msg, __VA_ARGS__)
331 #define HT_EMERG_OUT HT_OUT2(Logger::Priority::EMERG)
332 #else
333 #define HT_EMERG(msg)
334 #define HT_EMERGF(msg, ...)
335 #define HT_EMERG_OUT HT_OUT_DISABLED
336 #endif
337 
338 #ifndef HT_DISABLE_LOG_FATAL
339 #define HT_FATAL(msg) do { \
340  HT_LOG(Logger::Priority::FATAL, msg); \
341  HT_ABORT; \
342 } while (0)
343 #define HT_FATALF(msg, ...) do { \
344  HT_LOGF(Logger::Priority::FATAL, msg, __VA_ARGS__); \
345  HT_ABORT; \
346 } while (0)
347 #define HT_FATAL_OUT HT_OUT2(Logger::Priority::FATAL)
348 #else
349 #define HT_FATAL(msg)
350 #define HT_FATALF(msg, ...)
351 #define HT_FATAL_OUT HT_OUT_DISABLED
352 #endif
353 
354 #else // HT_DISABLE_LOGGING
355 
356 #define HT_DEBUG(msg)
357 #define HT_DEBUGF(msg, ...)
358 #define HT_INFO(msg)
359 #define HT_INFOF(msg, ...)
360 #define HT_NOTICE(msg)
361 #define HT_NOTICEF(msg, ...)
362 #define HT_WARN(msg)
363 #define HT_WARNF(msg, ...)
364 #define HT_ERROR(msg)
365 #define HT_ERRORF(msg, ...)
366 #define HT_CRIT(msg)
367 #define HT_CRITF(msg, ...)
368 #define HT_ALERT(msg)
369 #define HT_ALERTF(msg, ...)
370 #define HT_EMERG(msg)
371 #define HT_EMERGF(msg, ...)
372 #define HT_FATAL(msg)
373 #define HT_FATALF(msg, ...)
374 #define HT_LOG_ENTER
375 #define HT_LOG_EXIT
376 #define HT_DEBUG_OUT HT_OUT_DISABLED
377 #define HT_NOTICE_OUT HT_OUT_DISABLED
378 #define HT_WARN_OUT HT_OUT_DISABLED
379 #define HT_ERROR_OUT HT_OUT_DISABLED
380 #define HT_CRIT_OUT HT_OUT_DISABLED
381 #define HT_ALERT_OUT HT_OUT_DISABLED
382 #define HT_EMERG_OUT HT_OUT_DISABLED
383 #define HT_FATAL_OUT HT_OUT_DISABLED
384 
385 #endif // HT_DISABLE_LOGGING
386 
387 // Probably should be in its own file, but...
388 #define HT_EXPECT(_e_, _code_) do { if (_e_); else { \
389  if (_code_ == Error::FAILED_EXPECTATION) \
390  HT_FATAL("failed expectation: " #_e_); \
391  HT_THROW(_code_, "failed expectation: " #_e_); } \
392 } while (0)
393 
394 // A short cut for HT_EXPECT(expr, Error::FAILED_EXPECTATION)
395 // unlike assert, it cannot be turned off
396 #define HT_ASSERT(_e_) HT_EXPECT(_e_, Error::FAILED_EXPECTATION)
397 
398 #endif // Common_Logger_h
int get_level() const
Returns the message level.
Definition: Logger.h:88
void log_string(int priority, const char *message)
Appends a string message to the log.
Definition: Logger.cc:55
void initialize(const String &name)
Public initialization function - creates a singleton instance of LogWriter.
Definition: Logger.cc:45
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
Definition: String.cc:37
void debug(const char *format,...)
Prints a debug message with variable arguments (similar to printf)
Definition: Logger.cc:88
void log_varargs(int priority, const char *format, va_list ap)
Appends a string message with variable arguments to the log.
Definition: Logger.cc:82
String m_name
The name of the application.
Definition: Logger.h:147
int m_priority
The current priority (everything above is filtered)
Definition: Logger.h:150
void set_test_mode(int fd=-1)
The test mode disables line numbers and timestamps and can redirect the output to a separate file des...
Definition: Logger.h:100
Fixed size string buffers.
void flush()
Flushes the log file.
Definition: Logger.h:113
FILE * m_file
The output file handle.
Definition: Logger.h:153
The LogWriter class writes to stdout.
Definition: Logger.h:70
Hypertable definitions
void log(int priority, const char *format,...)
Prints a message with variable arguments.
Definition: Logger.cc:95
void debug(const String &message)
Prints a debug message.
Definition: Logger.h:121
void log(int priority, const String &message)
Prints a message.
Definition: Logger.h:129
bool is_enabled(int level) const
Returns true if a message with this level is not discarded.
Definition: Logger.h:93
bool m_show_line_numbers
True if line numbers are shown.
Definition: Logger.h:141
bool show_line_numbers() const
Returns true if line numbers are printed.
Definition: Logger.h:108
A String class based on std::string.
void set_level(int level)
Sets the message level; all messages with a higher level are discarded.
Definition: Logger.h:83
LogWriter(const String &name)
Constructor.
Definition: Logger.h:76
Error codes, Exception handling, error logging.
bool m_test_mode
True if this log is in test mode.
Definition: Logger.h:144