00001 
00002 
00003 
00004 
00005 
00006 
00007 
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 
00026 namespace pion {        
00027 namespace plugins {     
00028 
00029 
00030 
00031 
00032 const unsigned int      LogServiceAppender::DEFAULT_MAX_EVENTS = 25;
00033 
00034 
00035 
00036 
00037 #if defined(PION_USE_LOG4CPP)
00038 LogServiceAppender::LogServiceAppender(void)
00039     : log4cpp::AppenderSkeleton("LogServiceAppender"),
00040     m_max_events(DEFAULT_MAX_EVENTS), m_num_events(0),
00041     m_layout_ptr(new log4cpp::BasicLayout())
00042     {}
00043 #else
00044 LogServiceAppender::LogServiceAppender(void)
00045     : m_max_events(DEFAULT_MAX_EVENTS), m_num_events(0)
00046     {}
00047 #endif
00048 
00049 
00050 #if defined(PION_USE_LOG4CXX)
00051 void LogServiceAppender::append(const log4cxx::spi::LoggingEventPtr& event)
00052 {
00053     
00054     std::string formatted_string(boost::lexical_cast<std::string>(event->getTimeStamp()));
00055     formatted_string += ' ';
00056     formatted_string += event->getLevel()->toString();
00057     formatted_string += ' ';
00058     formatted_string += event->getLoggerName();
00059     formatted_string += " - ";
00060     formatted_string += event->getRenderedMessage();
00061     formatted_string += '\n';
00062     addLogString(formatted_string);
00063 }
00064 #elif defined(PION_USE_LOG4CPLUS)
00065 void LogServiceAppender::append(const log4cplus::spi::InternalLoggingEvent& event)
00066 {
00067     
00068     std::string formatted_string(boost::lexical_cast<std::string>(event.getTimestamp().sec()));
00069     formatted_string += ' ';
00070     formatted_string += m_log_level_manager.toString(event.getLogLevel());
00071     formatted_string += ' ';
00072     formatted_string += event.getLoggerName();
00073     formatted_string += " - ";
00074     formatted_string += event.getMessage();
00075     formatted_string += '\n';
00076     addLogString(formatted_string);
00077 }
00078 #elif defined(PION_USE_LOG4CPP)
00079 void LogServiceAppender::_append(const log4cpp::LoggingEvent& event)
00080 {
00081     std::string formatted_string(m_layout_ptr->format(event));
00082     addLogString(formatted_string);
00083 }
00084 #endif
00085 
00086 void LogServiceAppender::addLogString(const std::string& log_string)
00087 {
00088     boost::mutex::scoped_lock log_lock(m_log_mutex);
00089     m_log_events.push_back(log_string);
00090     ++m_num_events;
00091     while (m_num_events > m_max_events) {
00092         m_log_events.erase(m_log_events.begin());
00093         --m_num_events;
00094     }
00095 }
00096 
00097 void LogServiceAppender::writeLogEvents(pion::http::response_writer_ptr& writer)
00098 {
00099 #if defined(PION_USE_LOG4CXX) || defined(PION_USE_LOG4CPLUS) || defined(PION_USE_LOG4CPP)
00100     boost::mutex::scoped_lock log_lock(m_log_mutex);
00101     for (std::list<std::string>::const_iterator i = m_log_events.begin();
00102          i != m_log_events.end(); ++i)
00103     {
00104         writer << *i;
00105     }
00106 #elif defined(PION_DISABLE_LOGGING)
00107     writer << "Logging is disabled." << http::types::STRING_CRLF;
00108 #else
00109     writer << "Using ostream logging." << http::types::STRING_CRLF;
00110 #endif
00111 }
00112 
00113 
00114 
00115 
00116 LogService::LogService(void)
00117     : m_log_appender_ptr(new LogServiceAppender())
00118 {
00119 #if defined(PION_USE_LOG4CXX)
00120     m_log_appender_ptr->setName("LogServiceAppender");
00121     log4cxx::Logger::getRootLogger()->addAppender(m_log_appender_ptr);
00122 #elif defined(PION_USE_LOG4CPLUS)
00123     m_log_appender_ptr->setName("LogServiceAppender");
00124     log4cplus::Logger::getRoot().addAppender(m_log_appender_ptr);
00125 #elif defined(PION_USE_LOG4CPP)
00126     log4cpp::Category::getRoot().addAppender(m_log_appender_ptr);
00127 #endif
00128 }
00129 
00130 LogService::~LogService()
00131 {
00132 #if defined(PION_USE_LOG4CXX)
00133     
00134     log4cxx::Logger::getRootLogger()->removeAppender(m_log_appender_ptr);
00135 #elif defined(PION_USE_LOG4CPLUS)
00136     
00137     log4cplus::Logger::getRoot().removeAppender("LogServiceAppender");
00138 #elif defined(PION_USE_LOG4CPP)
00139     
00140     log4cpp::Category::getRoot().removeAppender(m_log_appender_ptr);
00141 #else
00142     delete m_log_appender_ptr;
00143 #endif
00144 }
00145 
00147 void LogService::operator()(http::request_ptr& http_request_ptr, tcp::connection_ptr& tcp_conn)
00148 {
00149     
00150     http::response_writer_ptr writer(http::response_writer::create(tcp_conn, *http_request_ptr,
00151                                                                    boost::bind(&tcp::connection::finish, tcp_conn)));
00152     writer->get_response().set_content_type(http::types::CONTENT_TYPE_TEXT);
00153     getLogAppender().writeLogEvents(writer);
00154     writer->send();
00155 }
00156 
00157 
00158 }   
00159 }   
00160 
00161 
00163 extern "C" PION_PLUGIN pion::plugins::LogService *pion_create_LogService(void)
00164 {
00165     return new pion::plugins::LogService();
00166 }
00167 
00169 extern "C" PION_PLUGIN void pion_destroy_LogService(pion::plugins::LogService *service_ptr)
00170 {
00171     delete service_ptr;
00172 }