pion  5.0.6
logger.hpp
1 // ---------------------------------------------------------------------
2 // pion: a Boost C++ framework for building lightweight HTTP interfaces
3 // ---------------------------------------------------------------------
4 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
8 //
9 
10 #ifndef __PION_LOGGER_HEADER__
11 #define __PION_LOGGER_HEADER__
12 
13 #include <pion/config.hpp>
14 
15 
16 #if defined(PION_USE_LOG4CXX)
17 
18  // unfortunately, the current version of log4cxx has many problems that
19  // produce very annoying warnings
20 
21  // log4cxx headers
22  #include <log4cxx/logger.h>
23  #include <log4cxx/logmanager.h>
24 #ifdef _MSC_VER
25  #pragma warning(push)
26  #pragma warning(disable: 4231) // nonstandard extension used : 'extern' before template explicit instantiation
27 #endif
28  #include <log4cxx/basicconfigurator.h>
29  #include <log4cxx/propertyconfigurator.h>
30 #ifdef _MSC_VER
31  #pragma warning(pop)
32 #endif
33 
34  #if defined _MSC_VER
35  #if defined _DEBUG
36  #pragma comment(lib, "log4cxxd")
37  #else
38  #pragma comment(lib, "log4cxx")
39  #endif
40  #pragma comment(lib, "odbc32")
41  #endif
42 
43  namespace pion {
44  typedef log4cxx::LoggerPtr logger;
45  typedef log4cxx::AppenderSkeleton log_appender;
46  typedef log_appender * log_appender_ptr;
47  }
48 
49  #define PION_HAS_LOG_APPENDER 1
50  #define PION_LOG_CONFIG_BASIC log4cxx::BasicConfigurator::configure();
51  #define PION_LOG_CONFIG(FILE) log4cxx::PropertyConfigurator::configure(FILE);
52  #define PION_GET_LOGGER(NAME) log4cxx::Logger::get_logger(NAME)
53  #define PION_SHUTDOWN_LOGGER log4cxx::LogManager::shutdown();
54 
55  #define PION_LOG_SETLEVEL_DEBUG(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::DEBUG_INT));
56  #define PION_LOG_SETLEVEL_INFO(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::INFO_INT));
57  #define PION_LOG_SETLEVEL_WARN(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::WARN_INT));
58  #define PION_LOG_SETLEVEL_ERROR(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::ERROR_INT));
59  #define PION_LOG_SETLEVEL_FATAL(LOG) LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::FATAL_INT));
60  #define PION_LOG_SETLEVEL_UP(LOG) LOG->setLevel(LOG->getLevel()->toInt()+1);
61  #define PION_LOG_SETLEVEL_DOWN(LOG) LOG->setLevel(LOG->getLevel()->toInt()-1);
62 
63  #define PION_LOG_DEBUG LOG4CXX_DEBUG
64  #define PION_LOG_INFO LOG4CXX_INFO
65  #define PION_LOG_WARN LOG4CXX_WARN
66  #define PION_LOG_ERROR LOG4CXX_ERROR
67  #define PION_LOG_FATAL LOG4CXX_FATAL
68 
69 #elif defined(PION_USE_LOG4CPLUS)
70 
71 
72  // log4cplus headers
73  #include <log4cplus/logger.h>
74  #include <log4cplus/configurator.h>
75  #include <log4cplus/appender.h>
76  #include <log4cplus/spi/loggingevent.h>
77  #include <log4cplus/loglevel.h>
78  #include <log4cplus/loggingmacros.h>
79 
80  #include <boost/circular_buffer.hpp>
81  #include <boost/thread/mutex.hpp>
82 
83  #if defined(_MSC_VER) && !defined(PION_CMAKE_BUILD)
84  #if defined _DEBUG
85  #if defined PION_STATIC_LINKING
86  #pragma comment(lib, "log4cplusSD")
87  #else
88  #pragma comment(lib, "log4cplusD")
89  #endif
90  #else
91  #if defined PION_STATIC_LINKING
92  #pragma comment(lib, "log4cplusS")
93  #else
94  #pragma comment(lib, "log4cplus")
95  #endif
96  #endif
97  #endif
98 
99  namespace pion {
100  typedef log4cplus::Logger logger;
101  typedef log4cplus::Appender log_appender;
102  typedef log4cplus::SharedAppenderPtr log_appender_ptr;
103 
107  class circular_buffer_appender : public log4cplus::Appender
108  {
109  public:
110  typedef boost::circular_buffer<log4cplus::spi::InternalLoggingEvent> LogEventBuffer;
111 
112  // default constructor and destructor
113  circular_buffer_appender(void) : m_log_events(1000) {};
114  virtual ~circular_buffer_appender() { destructorImpl(); }
115 
117  const LogEventBuffer& getLogIterator() const {
118  return m_log_events;
119  }
120 
121  public:
122  // member functions inherited from the Appender interface class
123  virtual void close() {}
124  protected:
125  virtual void append(const log4cplus::spi::InternalLoggingEvent& event) {
126  boost::mutex::scoped_lock log_lock(m_log_mutex);
127  m_log_events.push_back(*event.clone());
128  }
129 
130  private:
132  LogEventBuffer m_log_events;
133 
135  boost::mutex m_log_mutex;
136  };
137  }
138 
139  #define PION_HAS_LOG_APPENDER 1
140  #define PION_LOG_CONFIG_BASIC log4cplus::BasicConfigurator::doConfigure();
141  #define PION_LOG_CONFIG(FILE) log4cplus::PropertyConfigurator::doConfigure(FILE);
142  #define PION_GET_LOGGER(NAME) log4cplus::Logger::getInstance(NAME)
143  #define PION_SHUTDOWN_LOGGER log4cplus::Logger::shutdown();
144 
145  #define PION_LOG_SETLEVEL_DEBUG(LOG) LOG.setLogLevel(log4cplus::DEBUG_LOG_LEVEL);
146  #define PION_LOG_SETLEVEL_INFO(LOG) LOG.setLogLevel(log4cplus::INFO_LOG_LEVEL);
147  #define PION_LOG_SETLEVEL_WARN(LOG) LOG.setLogLevel(log4cplus::WARN_LOG_LEVEL);
148  #define PION_LOG_SETLEVEL_ERROR(LOG) LOG.setLogLevel(log4cplus::ERROR_LOG_LEVEL);
149  #define PION_LOG_SETLEVEL_FATAL(LOG) LOG.setLogLevel(log4cplus::FATAL_LOG_LEVEL);
150  #define PION_LOG_SETLEVEL_UP(LOG) LOG.setLogLevel(LOG.getLogLevel()+1);
151  #define PION_LOG_SETLEVEL_DOWN(LOG) LOG.setLogLevel(LOG.getLogLevel()-1);
152 
153  #define PION_LOG_DEBUG LOG4CPLUS_DEBUG
154  #define PION_LOG_INFO LOG4CPLUS_INFO
155  #define PION_LOG_WARN LOG4CPLUS_WARN
156  #define PION_LOG_ERROR LOG4CPLUS_ERROR
157  #define PION_LOG_FATAL LOG4CPLUS_FATAL
158 
159 
160 #elif defined(PION_USE_LOG4CPP)
161 
162 
163  // log4cpp headers
164  #include <log4cpp/Category.hh>
165  #include <log4cpp/BasicLayout.hh>
166  #include <log4cpp/OstreamAppender.hh>
167  #include <log4cpp/AppenderSkeleton.hh>
168 
169  namespace pion {
170  typedef log4cpp::Category* logger;
171  typedef log4cpp::AppenderSkeleton log_appender;
172  typedef log_appender * log_appender_ptr;
173  }
174 
175  #define PION_HAS_LOG_APPENDER 1
176  #define PION_LOG_CONFIG_BASIC { log4cpp::OstreamAppender *app = new log4cpp::OstreamAppender("cout", &std::cout); app->setLayout(new log4cpp::BasicLayout()); log4cpp::Category::getRoot().setAppender(app); }
177  #define PION_LOG_CONFIG(FILE) { log4cpp::PropertyConfigurator::configure(FILE); }
178  #define PION_GET_LOGGER(NAME) (&log4cpp::Category::getInstance(NAME))
179  #define PION_SHUTDOWN_LOGGER log4cpp::Category::shutdown();
180 
181  #define PION_LOG_SETLEVEL_DEBUG(LOG) { LOG->setPriority(log4cpp::Priority::DEBUG); }
182  #define PION_LOG_SETLEVEL_INFO(LOG) { LOG->setPriority(log4cpp::Priority::INFO); }
183  #define PION_LOG_SETLEVEL_WARN(LOG) { LOG->setPriority(log4cpp::Priority::WARN); }
184  #define PION_LOG_SETLEVEL_ERROR(LOG) { LOG->setPriority(log4cpp::Priority::ERROR); }
185  #define PION_LOG_SETLEVEL_FATAL(LOG) { LOG->setPriority(log4cpp::Priority::FATAL); }
186  #define PION_LOG_SETLEVEL_UP(LOG) { LOG->setPriority(LOG.getPriority()+1); }
187  #define PION_LOG_SETLEVEL_DOWN(LOG) { LOG->setPriority(LOG.getPriority()-1); }
188 
189  #define PION_LOG_DEBUG(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::DEBUG) { LOG->debugStream() << MSG; }
190  #define PION_LOG_INFO(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::INFO) { LOG->infoStream() << MSG; }
191  #define PION_LOG_WARN(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::WARN) { LOG->warnStream() << MSG; }
192  #define PION_LOG_ERROR(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::ERROR) { LOG->errorStream() << MSG; }
193  #define PION_LOG_FATAL(LOG, MSG) if (LOG->getPriority()>=log4cpp::Priority::FATAL) { LOG->fatalStream() << MSG; }
194 
195 #elif defined(PION_DISABLE_LOGGING)
196 
197  // Logging is disabled -> add do-nothing stubs for logging
198  namespace pion {
199  struct PION_API logger {
200  logger(int /* glog */) {}
201  operator bool() const { return false; }
202  static void shutdown() {}
203  };
204  typedef int log_appender;
205  typedef log_appender * log_appender_ptr;
206  }
207 
208  #undef PION_HAS_LOG_APPENDER
209  #define PION_LOG_CONFIG_BASIC {}
210  #define PION_LOG_CONFIG(FILE) {}
211  #define PION_GET_LOGGER(NAME) 0
212  #define PION_SHUTDOWN_LOGGER 0
213 
214  // use LOG to avoid warnings about LOG not being used
215  #define PION_LOG_SETLEVEL_DEBUG(LOG) { if (LOG) {} }
216  #define PION_LOG_SETLEVEL_INFO(LOG) { if (LOG) {} }
217  #define PION_LOG_SETLEVEL_WARN(LOG) { if (LOG) {} }
218  #define PION_LOG_SETLEVEL_ERROR(LOG) { if (LOG) {} }
219  #define PION_LOG_SETLEVEL_FATAL(LOG) { if (LOG) {} }
220  #define PION_LOG_SETLEVEL_UP(LOG) { if (LOG) {} }
221  #define PION_LOG_SETLEVEL_DOWN(LOG) { if (LOG) {} }
222 
223  #define PION_LOG_DEBUG(LOG, MSG) { if (LOG) {} }
224  #define PION_LOG_INFO(LOG, MSG) { if (LOG) {} }
225  #define PION_LOG_WARN(LOG, MSG) { if (LOG) {} }
226  #define PION_LOG_ERROR(LOG, MSG) { if (LOG) {} }
227  #define PION_LOG_FATAL(LOG, MSG) { if (LOG) {} }
228 #else
229 
230  #define PION_USE_OSTREAM_LOGGING
231 
232  // Logging uses std::cout and std::cerr
233  #include <iostream>
234  #include <string>
235  #include <ctime>
236 
237  namespace pion {
238  struct PION_API logger {
239  enum log_priority_type {
240  LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARN,
241  LOG_LEVEL_ERROR, LOG_LEVEL_FATAL
242  };
243  ~logger() {}
244  logger(void) : m_name("pion") {}
245  logger(const std::string& name) : m_name(name) {}
246  logger(const logger& p) : m_name(p.m_name) {}
247  static void shutdown() {}
248  std::string m_name;
249  static log_priority_type m_priority;
250  };
251  typedef int log_appender;
252  typedef log_appender * log_appender_ptr;
253  }
254 
255  #undef PION_HAS_LOG_APPENDER
256  #define PION_LOG_CONFIG_BASIC {}
257  #define PION_LOG_CONFIG(FILE) {}
258  #define PION_GET_LOGGER(NAME) pion::logger(NAME)
259  #define PION_SHUTDOWN_LOGGER {}
260 
261  #define PION_LOG_SETLEVEL_DEBUG(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_DEBUG; }
262  #define PION_LOG_SETLEVEL_INFO(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_INFO; }
263  #define PION_LOG_SETLEVEL_WARN(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_WARN; }
264  #define PION_LOG_SETLEVEL_ERROR(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_ERROR; }
265  #define PION_LOG_SETLEVEL_FATAL(LOG) { LOG.m_priority = pion::logger::LOG_LEVEL_FATAL; }
266  #define PION_LOG_SETLEVEL_UP(LOG) { ++LOG.m_priority; }
267  #define PION_LOG_SETLEVEL_DOWN(LOG) { --LOG.m_priority; }
268 
269  #define PION_LOG_DEBUG(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_DEBUG) { std::cout << time(NULL) << " DEBUG " << LOG.m_name << ' ' << MSG << std::endl; }
270  #define PION_LOG_INFO(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_INFO) { std::cout << time(NULL) << " INFO " << LOG.m_name << ' ' << MSG << std::endl; }
271  #define PION_LOG_WARN(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_WARN) { std::cerr << time(NULL) << " WARN " << LOG.m_name << ' ' << MSG << std::endl; }
272  #define PION_LOG_ERROR(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_ERROR) { std::cerr << time(NULL) << " ERROR " << LOG.m_name << ' ' << MSG << std::endl; }
273  #define PION_LOG_FATAL(LOG, MSG) if (LOG.m_priority <= pion::logger::LOG_LEVEL_FATAL) { std::cerr << time(NULL) << " FATAL " << LOG.m_name << ' ' << MSG << std::endl; }
274 
275 #endif
276 
277 #endif