net/services/LogService.cpp

00001 // ------------------------------------------------------------------
00002 // pion-net: a C++ framework for building lightweight HTTP interfaces
00003 // ------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
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/net/HTTPResponseWriter.hpp>
00023 
00024 using namespace pion;
00025 using namespace pion::net;
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 
00051 #if defined(PION_USE_LOG4CXX)
00052 void LogServiceAppender::append(const log4cxx::spi::LoggingEventPtr& event)
00053 {
00054     // custom layouts is not supported for log4cxx library
00055     std::string formatted_string(boost::lexical_cast<std::string>(event->getTimeStamp()));
00056     formatted_string += ' ';
00057     formatted_string += event->getLevel()->toString();
00058     formatted_string += ' ';
00059     formatted_string += event->getLoggerName();
00060     formatted_string += " - ";
00061     formatted_string += event->getRenderedMessage();
00062     formatted_string += '\n';
00063     addLogString(formatted_string);
00064 }
00065 #elif defined(PION_USE_LOG4CPLUS)
00066 void LogServiceAppender::append(const log4cplus::spi::InternalLoggingEvent& event)
00067 {
00068     // custom layouts is not supported for log4cplus library
00069     std::string formatted_string(boost::lexical_cast<std::string>(event.getTimestamp().sec()));
00070     formatted_string += ' ';
00071     formatted_string += m_log_level_manager.toString(event.getLogLevel());
00072     formatted_string += ' ';
00073     formatted_string += event.getLoggerName();
00074     formatted_string += " - ";
00075     formatted_string += event.getMessage();
00076     formatted_string += '\n';
00077     addLogString(formatted_string);
00078 }
00079 #elif defined(PION_USE_LOG4CPP)
00080 void LogServiceAppender::_append(const log4cpp::LoggingEvent& event)
00081 {
00082     std::string formatted_string(m_layout_ptr->format(event));
00083     addLogString(formatted_string);
00084 }
00085 #endif
00086 
00087 void LogServiceAppender::addLogString(const std::string& log_string)
00088 {
00089     boost::mutex::scoped_lock log_lock(m_log_mutex);
00090     m_log_events.push_back(log_string);
00091     ++m_num_events;
00092     while (m_num_events > m_max_events) {
00093         m_log_events.erase(m_log_events.begin());
00094         --m_num_events;
00095     }
00096 }
00097 
00098 void LogServiceAppender::writeLogEvents(pion::net::HTTPResponseWriterPtr& writer)
00099 {
00100 #if defined(PION_USE_LOG4CXX) || defined(PION_USE_LOG4CPLUS) || defined(PION_USE_LOG4CPP)
00101     boost::mutex::scoped_lock log_lock(m_log_mutex);
00102     for (std::list<std::string>::const_iterator i = m_log_events.begin();
00103          i != m_log_events.end(); ++i)
00104     {
00105         writer << *i;
00106     }
00107 #elif defined(PION_DISABLE_LOGGING)
00108     writer << "Logging is disabled." << HTTPTypes::STRING_CRLF;
00109 #else
00110     writer << "Using ostream logging." << HTTPTypes::STRING_CRLF;
00111 #endif
00112 }
00113 
00114 
00115 // LogService member functions
00116 
00117 LogService::LogService(void)
00118     : m_log_appender_ptr(new LogServiceAppender())
00119 {
00120 #if defined(PION_USE_LOG4CXX)
00121     m_log_appender_ptr->setName("LogServiceAppender");
00122     log4cxx::Logger::getRootLogger()->addAppender(m_log_appender_ptr);
00123 #elif defined(PION_USE_LOG4CPLUS)
00124     m_log_appender_ptr->setName("LogServiceAppender");
00125     log4cplus::Logger::getRoot().addAppender(m_log_appender_ptr);
00126 #elif defined(PION_USE_LOG4CPP)
00127     log4cpp::Category::getRoot().addAppender(m_log_appender_ptr);
00128 #endif
00129 }
00130 
00131 LogService::~LogService()
00132 {
00133 #if defined(PION_USE_LOG4CXX)
00134     // removeAppender() also deletes the object
00135     log4cxx::Logger::getRootLogger()->removeAppender(m_log_appender_ptr);
00136 #elif defined(PION_USE_LOG4CPLUS)
00137     // removeAppender() also deletes the object
00138     log4cplus::Logger::getRoot().removeAppender("LogServiceAppender");
00139 #elif defined(PION_USE_LOG4CPP)
00140     // removeAppender() also deletes the object
00141     log4cpp::Category::getRoot().removeAppender(m_log_appender_ptr);
00142 #else
00143     delete m_log_appender_ptr;
00144 #endif
00145 }
00146 
00148 void LogService::operator()(HTTPRequestPtr& request, TCPConnectionPtr& tcp_conn)
00149 {
00150     // Set Content-type to "text/plain" (plain ascii text)
00151     HTTPResponseWriterPtr writer(HTTPResponseWriter::create(tcp_conn, *request,
00152                                                             boost::bind(&TCPConnection::finish, tcp_conn)));
00153     writer->getResponse().setContentType(HTTPTypes::CONTENT_TYPE_TEXT);
00154     getLogAppender().writeLogEvents(writer);
00155     writer->send();
00156 }
00157 
00158 
00159 }   // end namespace plugins
00160 }   // end namespace pion
00161 
00162 
00164 extern "C" PION_SERVICE_API pion::plugins::LogService *pion_create_LogService(void)
00165 {
00166     return new pion::plugins::LogService();
00167 }
00168 
00170 extern "C" PION_SERVICE_API void pion_destroy_LogService(pion::plugins::LogService *service_ptr)
00171 {
00172     delete service_ptr;
00173 }

Generated on Fri Apr 30 14:48:53 2010 for pion-net by  doxygen 1.4.7