GCS  0.2.3
gu_logger.hpp
1 /*
2  * Copyright (C) 2009 Codership Oy <info@codership.com>
3  *
4  * This code is based on an excellent article at Dr.Dobb's:
5  * http://www.ddj.com/cpp/201804215?pgno=1
6  *
7  * It looks ugly because it has to integrate with C logger -
8  * in order to produce identical output
9  */
10 
11 #ifndef __GU_LOGGER__
12 #define __GU_LOGGER__
13 
14 #include <sstream>
15 
16 extern "C" {
17 #include "gu_log.h"
18 #include "gu_conf.h"
19 }
20 
21 namespace gu
22 {
23  // some portability stuff
24 #ifdef _gu_log_h_
25  enum LogLevel { LOG_FATAL = GU_LOG_FATAL,
26  LOG_ERROR = GU_LOG_ERROR,
27  LOG_WARN = GU_LOG_WARN,
28  LOG_INFO = GU_LOG_INFO,
29  LOG_DEBUG = GU_LOG_DEBUG,
30  LOG_MAX };
31  typedef gu_log_cb_t LogCallback;
32 #else
33  enum LogLevel { LOG_FATAL,
34  LOG_ERROR,
35  LOG_WARN,
36  LOG_INFO,
37  LOG_DEBUG,
38  LOG_MAX };
39  typedef void (*LogCallback) (int, const char*);
40 #endif
41 
42  class Logger
43  {
44  private:
45 
46  Logger(const Logger&);
47  Logger& operator =(const Logger&);
48 
49  void prepare_default ();
50  const LogLevel level;
51 
52 #ifndef _gu_log_h_
53  static LogLevel max_level;
54  static bool do_timestamp;
55  static LogCallback logger;
56  static void default_logger (int, const char*);
57 #else
58 #define max_level gu_log_max_level
59 #define logger gu_log_cb
60 #define default_logger gu_log_cb_default
61 #endif
62 
63  protected:
64 
65  std::ostringstream os;
66 
67  public:
68 
69  Logger(LogLevel _level = LOG_INFO) :
70  level (_level),
71  os ()
72  {}
73 
74  virtual ~Logger() { logger (level, os.str().c_str()); }
75 
76  std::ostringstream& get(const char* file,
77  const char* func,
78  int line)
79  {
80  if (default_logger == logger)
81  {
82  prepare_default(); // prefix with timestamp and log level
83  }
84 
85  /* provide file:func():line info only when debug logging is on */
86  if (static_cast<int>(LOG_DEBUG) == static_cast<int>(max_level))
87  {
88  os << file << ':' << func << "():" << line << ": ";
89  }
90 
91  return os;
92  }
93 
94  static bool no_log (LogLevel lvl)
95  {
96  return (static_cast<int>(lvl) > static_cast<int>(max_level));
97  }
98 
99  static void set_debug_filter(const std::string&);
100 
101  static bool no_debug(const std::string&, const std::string&, const int);
102 
103 #ifndef _gu_log_h_
104  static void enable_tstamp (bool);
105  static void enable_debug (bool);
106  static void set_logger (LogCallback);
107 #endif
108  };
109 
110 
111 #define GU_LOG_CPP(level) \
112  if (gu::Logger::no_log(level) || \
113  (level == gu::LOG_DEBUG && \
114  gu::Logger::no_debug(__FILE__, __FUNCTION__, __LINE__))) {} \
115  else gu::Logger(level).get(__FILE__, __FUNCTION__, __LINE__)
116 
117 // USAGE: LOG(level) << item_1 << item_2 << ... << item_n;
118 
119 #define log_fatal GU_LOG_CPP(gu::LOG_FATAL)
120 #define log_error GU_LOG_CPP(gu::LOG_ERROR)
121 #define log_warn GU_LOG_CPP(gu::LOG_WARN)
122 #define log_info GU_LOG_CPP(gu::LOG_INFO)
123 #define log_debug GU_LOG_CPP(gu::LOG_DEBUG)
124 
125 }
126 
127 #endif // __GU_LOGGER__
Definition: gu_logger.hpp:42