# 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 }