pion
5.0.6
|
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 #include "LogService.hpp" 00011 00012 #if defined(PION_USE_LOG4CXX) 00013 #include <log4cxx/spi/loggingevent.h> 00014 #include <boost/lexical_cast.hpp> 00015 #elif defined(PION_USE_LOG4CPLUS) 00016 #include <log4cplus/spi/loggingevent.h> 00017 #include <boost/lexical_cast.hpp> 00018 #elif defined(PION_USE_LOG4CPP) 00019 #include <log4cpp/BasicLayout.hh> 00020 #endif 00021 00022 #include <pion/http/response_writer.hpp> 00023 00024 using namespace pion; 00025 using namespace log4cplus::helpers; 00026 00027 namespace pion { // begin namespace pion 00028 namespace plugins { // begin namespace plugins 00029 00030 00031 // static members of LogServiceAppender 00032 00033 const unsigned int LogServiceAppender::DEFAULT_MAX_EVENTS = 25; 00034 00035 00036 // LogServiceAppender member functions 00037 00038 #if defined(PION_USE_LOG4CPP) 00039 LogServiceAppender::LogServiceAppender(void) 00040 : log4cpp::AppenderSkeleton("LogServiceAppender"), 00041 m_max_events(DEFAULT_MAX_EVENTS), m_num_events(0), 00042 m_layout_ptr(new log4cpp::BasicLayout()) 00043 {} 00044 #else 00045 LogServiceAppender::LogServiceAppender(void) 00046 : m_max_events(DEFAULT_MAX_EVENTS), m_num_events(0) 00047 {} 00048 #endif 00049 00050 LogServiceAppender::~LogServiceAppender() 00051 { 00052 #if defined(PION_USE_LOG4CPLUS) 00053 destructorImpl(); 00054 #endif 00055 } 00056 00057 00058 #if defined(PION_USE_LOG4CXX) 00059 void LogServiceAppender::append(const log4cxx::spi::LoggingEventPtr& event) 00060 { 00061 // custom layouts is not supported for log4cxx library 00062 std::string formatted_string(boost::lexical_cast<std::string>(event->getTimeStamp())); 00063 formatted_string += ' '; 00064 formatted_string += event->getLevel()->toString(); 00065 formatted_string += ' '; 00066 formatted_string += event->getLoggerName(); 00067 formatted_string += " - "; 00068 formatted_string += event->getRenderedMessage(); 00069 formatted_string += '\n'; 00070 addLogString(formatted_string); 00071 } 00072 #elif defined(PION_USE_LOG4CPLUS) 00073 void LogServiceAppender::append(const log4cplus::spi::InternalLoggingEvent& event) 00074 { 00075 // custom layouts is not supported for log4cplus library 00076 //std::string formatted_string(boost::lexical_cast<std::string>(event.getTimestamp().sec())); 00077 time_t tt = log4cplus::helpers::to_time_t(event.getTimestamp()); 00078 tm* tmm = gmtime(&tt); 00079 std::string formatted_string(boost::lexical_cast<std::string>(tmm->tm_sec)); 00080 formatted_string += ' '; 00081 formatted_string += m_log_level_manager.toString(event.getLogLevel()); 00082 formatted_string += ' '; 00083 formatted_string += event.getLoggerName(); 00084 formatted_string += " - "; 00085 formatted_string += event.getMessage(); 00086 formatted_string += '\n'; 00087 addLogString(formatted_string); 00088 } 00089 #elif defined(PION_USE_LOG4CPP) 00090 void LogServiceAppender::_append(const log4cpp::LoggingEvent& event) 00091 { 00092 std::string formatted_string(m_layout_ptr->format(event)); 00093 addLogString(formatted_string); 00094 } 00095 #endif 00096 00097 void LogServiceAppender::addLogString(const std::string& log_string) 00098 { 00099 boost::mutex::scoped_lock log_lock(m_log_mutex); 00100 m_log_events.push_back(log_string); 00101 ++m_num_events; 00102 while (m_num_events > m_max_events) { 00103 m_log_events.erase(m_log_events.begin()); 00104 --m_num_events; 00105 } 00106 } 00107 00108 void LogServiceAppender::writeLogEvents(pion::http::response_writer_ptr& writer) 00109 { 00110 #if defined(PION_USE_LOG4CXX) || defined(PION_USE_LOG4CPLUS) || defined(PION_USE_LOG4CPP) 00111 boost::mutex::scoped_lock log_lock(m_log_mutex); 00112 for (std::list<std::string>::const_iterator i = m_log_events.begin(); 00113 i != m_log_events.end(); ++i) 00114 { 00115 writer << *i; 00116 } 00117 #elif defined(PION_DISABLE_LOGGING) 00118 writer << "Logging is disabled." << http::types::STRING_CRLF; 00119 #else 00120 writer << "Using ostream logging." << http::types::STRING_CRLF; 00121 #endif 00122 } 00123 00124 00125 // LogService member functions 00126 00127 LogService::LogService(void) 00128 : m_log_appender_ptr(new LogServiceAppender()) 00129 { 00130 #if defined(PION_USE_LOG4CXX) 00131 m_log_appender_ptr->setName("LogServiceAppender"); 00132 log4cxx::Logger::getRootLogger()->addAppender(m_log_appender_ptr); 00133 #elif defined(PION_USE_LOG4CPLUS) 00134 m_log_appender_ptr->setName("LogServiceAppender"); 00135 log4cplus::Logger::getRoot().addAppender(m_log_appender_ptr); 00136 #elif defined(PION_USE_LOG4CPP) 00137 log4cpp::Category::getRoot().addAppender(m_log_appender_ptr); 00138 #endif 00139 } 00140 00141 LogService::~LogService() 00142 { 00143 #if defined(PION_USE_LOG4CXX) 00144 // removeAppender() also deletes the object 00145 log4cxx::Logger::getRootLogger()->removeAppender(m_log_appender_ptr); 00146 #elif defined(PION_USE_LOG4CPLUS) 00147 // removeAppender() also deletes the object 00148 log4cplus::Logger::getRoot().removeAppender("LogServiceAppender"); 00149 #elif defined(PION_USE_LOG4CPP) 00150 // removeAppender() also deletes the object 00151 log4cpp::Category::getRoot().removeAppender(m_log_appender_ptr); 00152 #else 00153 delete m_log_appender_ptr; 00154 #endif 00155 } 00156 00158 void LogService::operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn) 00159 { 00160 // Set Content-type to "text/plain" (plain ascii text) 00161 http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr, 00162 boost::bind(&tcp::connection::finish, tcp_conn))); 00163 writer->get_response().set_content_type(http::types::CONTENT_TYPE_TEXT); 00164 getLogAppender().writeLogEvents(writer); 00165 writer->send(); 00166 } 00167 00168 00169 } // end namespace plugins 00170 } // end namespace pion 00171 00172 00174 extern "C" PION_PLUGIN pion::plugins::LogService *pion_create_LogService(void) 00175 { 00176 return new pion::plugins::LogService(); 00177 } 00178 00180 extern "C" PION_PLUGIN void pion_destroy_LogService(pion::plugins::LogService *service_ptr) 00181 { 00182 delete service_ptr; 00183 }