pion  5.0.6
include/pion/logger.hpp
00001 // ---------------------------------------------------------------------
00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
00003 // ---------------------------------------------------------------------
00004 // Copyright (C) 2007-2014 Splunk Inc.  (https://github.com/splunk/pion)
00005 //
00006 // Distributed under the Boost Software License, Version 1.0.
00007 // See http://www.boost.org/LICENSE_1_0.txt
00008 //
00009 
00010 #ifndef __PION_LOGGER_HEADER__
00011 #define __PION_LOGGER_HEADER__
00012 
00013 #include <pion/config.hpp>
00014 
00015 
00016 #if defined(PION_USE_LOG4CXX)
00017 
00018     // unfortunately, the current version of log4cxx has many problems that
00019     // produce very annoying warnings
00020 
00021     // log4cxx headers
00022     #include <log4cxx/logger.h>
00023     #include <log4cxx/logmanager.h>
00024 #ifdef _MSC_VER
00025     #pragma warning(push)
00026     #pragma warning(disable: 4231) // nonstandard extension used : 'extern' before template explicit instantiation
00027 #endif
00028     #include <log4cxx/basicconfigurator.h>
00029     #include <log4cxx/propertyconfigurator.h>
00030 #ifdef _MSC_VER
00031     #pragma warning(pop)
00032 #endif
00033 
00034     #if defined _MSC_VER
00035         #if defined _DEBUG
00036             #pragma comment(lib, "log4cxxd")
00037         #else
00038             #pragma comment(lib, "log4cxx")
00039         #endif
00040         #pragma comment(lib, "odbc32")
00041     #endif
00042 
00043     namespace pion {
00044         typedef log4cxx::LoggerPtr  logger;
00045         typedef log4cxx::AppenderSkeleton   log_appender;
00046         typedef log_appender *   log_appender_ptr;
00047     }
00048 
00049     #define PION_HAS_LOG_APPENDER   1
00050     #define PION_LOG_CONFIG_BASIC   log4cxx::BasicConfigurator::configure();
00051     #define PION_LOG_CONFIG(FILE)   log4cxx::PropertyConfigurator::configure(FILE);
00052     #define PION_GET_LOGGER(NAME)   log4cxx::Logger::get_logger(NAME)
00053     #define PION_SHUTDOWN_LOGGER    log4cxx::LogManager::shutdown();
00054 
00055     #define PION_LOG_SETLEVEL_DEBUG(LOG)    LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::DEBUG_INT));
00056     #define PION_LOG_SETLEVEL_INFO(LOG)     LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::INFO_INT));
00057     #define PION_LOG_SETLEVEL_WARN(LOG)     LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::WARN_INT));
00058     #define PION_LOG_SETLEVEL_ERROR(LOG)    LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::ERROR_INT));
00059     #define PION_LOG_SETLEVEL_FATAL(LOG)    LOG->setLevel(log4cxx::Level::toLevel(log4cxx::Level::FATAL_INT));
00060     #define PION_LOG_SETLEVEL_UP(LOG)       LOG->setLevel(LOG->getLevel()->toInt()+1);
00061     #define PION_LOG_SETLEVEL_DOWN(LOG)     LOG->setLevel(LOG->getLevel()->toInt()-1);
00062 
00063     #define PION_LOG_DEBUG  LOG4CXX_DEBUG
00064     #define PION_LOG_INFO   LOG4CXX_INFO
00065     #define PION_LOG_WARN   LOG4CXX_WARN
00066     #define PION_LOG_ERROR  LOG4CXX_ERROR
00067     #define PION_LOG_FATAL  LOG4CXX_FATAL
00068 
00069 #elif defined(PION_USE_LOG4CPLUS)
00070 
00071 
00072     // log4cplus headers
00073     #include <log4cplus/logger.h>
00074     #include <log4cplus/configurator.h>
00075     #include <log4cplus/appender.h>
00076     #include <log4cplus/spi/loggingevent.h>
00077     #include <log4cplus/loglevel.h>
00078     #include <log4cplus/loggingmacros.h>
00079 
00080     #include <boost/circular_buffer.hpp>
00081     #include <boost/thread/mutex.hpp>
00082 
00083     #if defined(_MSC_VER) && !defined(PION_CMAKE_BUILD)
00084         #if defined _DEBUG
00085             #if defined PION_STATIC_LINKING
00086                 #pragma comment(lib, "log4cplusSD")
00087             #else
00088                 #pragma comment(lib, "log4cplusD")
00089             #endif
00090         #else
00091             #if defined PION_STATIC_LINKING
00092                 #pragma comment(lib, "log4cplusS")
00093             #else
00094                 #pragma comment(lib, "log4cplus")
00095             #endif
00096         #endif
00097     #endif
00098 
00099     namespace pion {
00100         typedef log4cplus::Logger   logger;
00101         typedef log4cplus::Appender log_appender;
00102         typedef log4cplus::SharedAppenderPtr    log_appender_ptr;
00103 
00107         class circular_buffer_appender : public log4cplus::Appender
00108         {
00109         public:
00110             typedef boost::circular_buffer<log4cplus::spi::InternalLoggingEvent> LogEventBuffer;
00111 
00112             // default constructor and destructor
00113             circular_buffer_appender(void) : m_log_events(1000) {};
00114             virtual ~circular_buffer_appender() { destructorImpl(); }
00115 
00117             const LogEventBuffer& getLogIterator() const {
00118                 return m_log_events;
00119             }
00120 
00121         public:
00122             // member functions inherited from the Appender interface class
00123             virtual void close() {}
00124         protected:
00125             virtual void append(const log4cplus::spi::InternalLoggingEvent& event) {
00126                 boost::mutex::scoped_lock log_lock(m_log_mutex);
00127                 m_log_events.push_back(*event.clone());
00128             }
00129 
00130         private:
00132             LogEventBuffer  m_log_events;
00133 
00135             boost::mutex    m_log_mutex;
00136         };
00137     }
00138 
00139     #define PION_HAS_LOG_APPENDER   1
00140     #define PION_LOG_CONFIG_BASIC   log4cplus::BasicConfigurator::doConfigure();
00141     #define PION_LOG_CONFIG(FILE)   log4cplus::PropertyConfigurator::doConfigure(FILE);
00142     #define PION_GET_LOGGER(NAME)   log4cplus::Logger::getInstance(NAME)
00143     #define PION_SHUTDOWN_LOGGER    log4cplus::Logger::shutdown();
00144 
00145     #define PION_LOG_SETLEVEL_DEBUG(LOG)    LOG.setLogLevel(log4cplus::DEBUG_LOG_LEVEL);
00146     #define PION_LOG_SETLEVEL_INFO(LOG)     LOG.setLogLevel(log4cplus::INFO_LOG_LEVEL);
00147     #define PION_LOG_SETLEVEL_WARN(LOG)     LOG.setLogLevel(log4cplus::WARN_LOG_LEVEL);
00148     #define PION_LOG_SETLEVEL_ERROR(LOG)    LOG.setLogLevel(log4cplus::ERROR_LOG_LEVEL);
00149     #define PION_LOG_SETLEVEL_FATAL(LOG)    LOG.setLogLevel(log4cplus::FATAL_LOG_LEVEL);
00150     #define PION_LOG_SETLEVEL_UP(LOG)       LOG.setLogLevel(LOG.getLogLevel()+1);
00151     #define PION_LOG_SETLEVEL_DOWN(LOG)     LOG.setLogLevel(LOG.getLogLevel()-1);
00152 
00153     #define PION_LOG_DEBUG  LOG4CPLUS_DEBUG
00154     #define PION_LOG_INFO   LOG4CPLUS_INFO
00155     #define PION_LOG_WARN   LOG4CPLUS_WARN
00156     #define PION_LOG_ERROR  LOG4CPLUS_ERROR
00157     #define PION_LOG_FATAL  LOG4CPLUS_FATAL
00158 
00159 
00160 #elif defined(PION_USE_LOG4CPP)
00161 
00162 
00163     // log4cpp headers
00164     #include <log4cpp/Category.hh>
00165     #include <log4cpp/BasicLayout.hh>
00166     #include <log4cpp/OstreamAppender.hh>
00167     #include <log4cpp/AppenderSkeleton.hh>
00168 
00169     namespace pion {
00170         typedef log4cpp::Category*  logger;
00171         typedef log4cpp::AppenderSkeleton   log_appender;
00172         typedef log_appender *   log_appender_ptr;
00173     }
00174 
00175     #define PION_HAS_LOG_APPENDER   1
00176     #define PION_LOG_CONFIG_BASIC   { log4cpp::OstreamAppender *app = new log4cpp::OstreamAppender("cout", &std::cout); app->setLayout(new log4cpp::BasicLayout()); log4cpp::Category::getRoot().setAppender(app); }
00177     #define PION_LOG_CONFIG(FILE)   { log4cpp::PropertyConfigurator::configure(FILE); }
00178     #define PION_GET_LOGGER(NAME)   (&log4cpp::Category::getInstance(NAME))
00179     #define PION_SHUTDOWN_LOGGER    log4cpp::Category::shutdown();
00180 
00181     #define PION_LOG_SETLEVEL_DEBUG(LOG)    { LOG->setPriority(log4cpp::Priority::DEBUG); }
00182     #define PION_LOG_SETLEVEL_INFO(LOG)     { LOG->setPriority(log4cpp::Priority::INFO); }
00183     #define PION_LOG_SETLEVEL_WARN(LOG)     { LOG->setPriority(log4cpp::Priority::WARN); }
00184     #define PION_LOG_SETLEVEL_ERROR(LOG)    { LOG->setPriority(log4cpp::Priority::ERROR); }
00185     #define PION_LOG_SETLEVEL_FATAL(LOG)    { LOG->setPriority(log4cpp::Priority::FATAL); }
00186     #define PION_LOG_SETLEVEL_UP(LOG)       { LOG->setPriority(LOG.getPriority()+1); }
00187     #define PION_LOG_SETLEVEL_DOWN(LOG)     { LOG->setPriority(LOG.getPriority()-1); }
00188 
00189     #define PION_LOG_DEBUG(LOG, MSG)    if (LOG->getPriority()>=log4cpp::Priority::DEBUG) { LOG->debugStream() << MSG; }
00190     #define PION_LOG_INFO(LOG, MSG)     if (LOG->getPriority()>=log4cpp::Priority::INFO) { LOG->infoStream() << MSG; }
00191     #define PION_LOG_WARN(LOG, MSG)     if (LOG->getPriority()>=log4cpp::Priority::WARN) { LOG->warnStream() << MSG; }
00192     #define PION_LOG_ERROR(LOG, MSG)    if (LOG->getPriority()>=log4cpp::Priority::ERROR) { LOG->errorStream() << MSG; }
00193     #define PION_LOG_FATAL(LOG, MSG)    if (LOG->getPriority()>=log4cpp::Priority::FATAL) { LOG->fatalStream() << MSG; }
00194 
00195 #elif defined(PION_DISABLE_LOGGING)
00196 
00197     // Logging is disabled -> add do-nothing stubs for logging
00198     namespace pion {
00199         struct PION_API logger {
00200             logger(int /* glog */) {}
00201             operator bool() const { return false; }
00202             static void shutdown() {}
00203         };
00204         typedef int     log_appender;
00205         typedef log_appender *   log_appender_ptr;
00206     }
00207 
00208     #undef PION_HAS_LOG_APPENDER
00209     #define PION_LOG_CONFIG_BASIC   {}
00210     #define PION_LOG_CONFIG(FILE)   {}
00211     #define PION_GET_LOGGER(NAME)   0
00212     #define PION_SHUTDOWN_LOGGER    0
00213 
00214     // use LOG to avoid warnings about LOG not being used
00215     #define PION_LOG_SETLEVEL_DEBUG(LOG)    { if (LOG) {} }
00216     #define PION_LOG_SETLEVEL_INFO(LOG)     { if (LOG) {} }
00217     #define PION_LOG_SETLEVEL_WARN(LOG)     { if (LOG) {} }
00218     #define PION_LOG_SETLEVEL_ERROR(LOG)    { if (LOG) {} }
00219     #define PION_LOG_SETLEVEL_FATAL(LOG)    { if (LOG) {} }
00220     #define PION_LOG_SETLEVEL_UP(LOG)       { if (LOG) {} }
00221     #define PION_LOG_SETLEVEL_DOWN(LOG)     { if (LOG) {} }
00222 
00223     #define PION_LOG_DEBUG(LOG, MSG)    { if (LOG) {} }
00224     #define PION_LOG_INFO(LOG, MSG)     { if (LOG) {} }
00225     #define PION_LOG_WARN(LOG, MSG)     { if (LOG) {} }
00226     #define PION_LOG_ERROR(LOG, MSG)    { if (LOG) {} }
00227     #define PION_LOG_FATAL(LOG, MSG)    { if (LOG) {} }
00228 #else
00229 
00230     #define PION_USE_OSTREAM_LOGGING
00231 
00232     // Logging uses std::cout and std::cerr
00233     #include <iostream>
00234     #include <string>
00235     #include <ctime>
00236 
00237     namespace pion {
00238         struct PION_API logger {
00239             enum log_priority_type {
00240                 LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARN,
00241                 LOG_LEVEL_ERROR, LOG_LEVEL_FATAL
00242             };
00243             ~logger() {}
00244             logger(void) : m_name("pion") {}
00245             logger(const std::string& name) : m_name(name) {}
00246             logger(const logger& p) : m_name(p.m_name) {}
00247             static void shutdown() {}
00248             std::string                 m_name;
00249             static log_priority_type     m_priority;
00250         };
00251         typedef int     log_appender;
00252         typedef log_appender *   log_appender_ptr;
00253     }
00254 
00255     #undef PION_HAS_LOG_APPENDER
00256     #define PION_LOG_CONFIG_BASIC   {}
00257     #define PION_LOG_CONFIG(FILE)   {}
00258     #define PION_GET_LOGGER(NAME)   pion::logger(NAME)
00259     #define PION_SHUTDOWN_LOGGER    {}
00260 
00261     #define PION_LOG_SETLEVEL_DEBUG(LOG)    { LOG.m_priority = pion::logger::LOG_LEVEL_DEBUG; }
00262     #define PION_LOG_SETLEVEL_INFO(LOG)     { LOG.m_priority = pion::logger::LOG_LEVEL_INFO; }
00263     #define PION_LOG_SETLEVEL_WARN(LOG)     { LOG.m_priority = pion::logger::LOG_LEVEL_WARN; }
00264     #define PION_LOG_SETLEVEL_ERROR(LOG)    { LOG.m_priority = pion::logger::LOG_LEVEL_ERROR; }
00265     #define PION_LOG_SETLEVEL_FATAL(LOG)    { LOG.m_priority = pion::logger::LOG_LEVEL_FATAL; }
00266     #define PION_LOG_SETLEVEL_UP(LOG)       { ++LOG.m_priority; }
00267     #define PION_LOG_SETLEVEL_DOWN(LOG)     { --LOG.m_priority; }
00268 
00269     #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; }
00270     #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; }
00271     #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; }
00272     #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; }
00273     #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; }
00274 
00275 #endif
00276 
00277 #endif