Log4cxxAppender.cpp
Go to the documentation of this file.
00001 #include "logging/Log4cxxAppender.hpp"
00002 #include "log4cxx/spi/loggingevent.h"
00003 #include "rtt/Component.hpp"
00004 #include <rtt/Logger.hpp>
00005 
00006 using namespace RTT;
00007 
00008 namespace OCL {
00009 namespace logging {
00010     using namespace log4cxx;
00011 
00012     log4cxx::LevelPtr tolog4cxxLevel( log4cpp::Priority::Value priority) {
00013         switch (priority) {
00014         //case log4cpp::Priority::EMERG : EMERG and FATAL are both zero
00015             //return Level::getFatal();
00016         case log4cpp::Priority::FATAL :
00017             return Level::getFatal();
00018         case log4cpp::Priority::ALERT :
00019             return Level::getError();
00020         case log4cpp::Priority::CRIT :
00021             return Level::getError();
00022         case log4cpp::Priority::ERROR :
00023             return Level::getError();
00024         case log4cpp::Priority::WARN :
00025             return Level::getWarn();
00026         case log4cpp::Priority::NOTICE :
00027             return Level::getInfo();
00028         case log4cpp::Priority::INFO :
00029             return Level::getInfo();
00030         case log4cpp::Priority::DEBUG :
00031             return Level::getDebug();
00032         case log4cpp::Priority::NOTSET :
00033             return Level::getDebug();
00034         }
00035         return Level::getDebug();
00036     }
00037 
00038     spi::LoggingEventPtr tolog4cxx(logging::LoggingEvent const& e, log4cxx::helpers::Pool & pool)
00039     {
00040         return spi::LoggingEventPtr(new spi::LoggingEvent(makeString( e.categoryName ), tolog4cxxLevel(e.priority), makeString( e.message ), log4cxx::spi::LocationInfo("filename", "functionname", 0)));
00041     }
00042 
00043 Log4cxxAppender::Log4cxxAppender(std::string name) :
00044     RTT::TaskContext(name,RTT::TaskContext::PreOperational),
00045         socketAppender(0),
00046         hostname_prop("localhost"), port_prop(4560),
00047         maxEventsPerCycle_prop(0),
00048         maxEventsPerCycle(0)
00049 {
00050 
00051     ports()->addEventPort("LogPort", log_port );
00052     properties()->addProperty("Hostname",hostname_prop).doc("Host name where ChainSaw or other logging server runs.");
00053     properties()->addProperty("MaxEventsPerCycle",maxEventsPerCycle_prop).doc("Maximum number of log events to pop per cycle");
00054     properties()->addProperty("Port", port_prop).doc("Logging server port to use on Hostname. ChainSaw uses port 4560.");
00055 }
00056 
00057 Log4cxxAppender::~Log4cxxAppender()
00058 {
00059 }
00060 
00061 bool Log4cxxAppender::configureHook()
00062 {
00063     // verify valid limits
00064     int m = maxEventsPerCycle_prop;
00065     if ((0 > m))
00066     {
00067         log(Error) << "Invalid maxEventsPerCycle value of "
00068                    << m << ". Value must be >= 0."
00069                    << endlog();
00070         return false;
00071     }
00072     maxEventsPerCycle = m;
00073 
00074     // \todo error checking
00075     if ( hostname_prop == "localhost")
00076         address = helpers::InetAddress::getLocalHost();
00077     else
00078         address = helpers::InetAddress::getByName( hostname_prop );
00079 
00080     if ( socketAppender ) {
00081         socketAppender->close();
00082         delete socketAppender;
00083     }
00084 
00085     net::SocketAppender::DEFAULT_RECONNECTION_DELAY = 3000; // 3s
00086 
00087     socketAppender = new
00088         log4cxx::net::SocketAppender( address, port_prop );
00089 
00090     socketAppender->activateOptions(p);
00091 
00092     return true;
00093 }
00094 
00095 void Log4cxxAppender::updateHook()
00096 {
00097     if (!log_port.connected()) return;      // no category connected to us
00098 
00099     /* Consume waiting events until
00100        a) the buffer is empty
00101        b) we consume too many events on one cycle
00102      */
00103     OCL::logging::LoggingEvent   event;
00104     assert(socketAppender);
00105     assert(0 <= maxEventsPerCycle);
00106     if (0 == maxEventsPerCycle)
00107     {
00108         // consume infinite events
00109         for (;;)
00110         {
00111             if (log_port.read( event ) == NewData)
00112             {
00113                 spi::LoggingEventPtr e2 = tolog4cxx( event, p );
00114                 socketAppender->doAppend(e2, p);
00115             }
00116             else
00117             {
00118                 break;      // nothing to do
00119             }
00120         }
00121     }
00122     else
00123     {
00124 
00125         // consume up to maxEventsPerCycle events
00126         int n       = maxEventsPerCycle;
00127         do
00128         {
00129             if (log_port.read( event ) == NewData)
00130             {
00131                 spi::LoggingEventPtr e2 = tolog4cxx( event, p );
00132                 socketAppender->doAppend(e2, p);
00133             }
00134             else
00135             {
00136                 break;      // nothing to do
00137             }
00138             --n;
00139         }
00140         while (0 < n);
00141     }
00142 }
00143 
00144 void Log4cxxAppender::cleanupHook()
00145 {
00146     /* normally in log4cpp the category owns the appenders and deletes them
00147        itself, however we don't associate appenders and categories in the
00148        same manner. Hence, you have to manually manage appenders.
00149     */
00150     socketAppender->close();
00151     delete socketAppender;
00152     socketAppender = 0;
00153 }
00154 
00155 // namespaces
00156 }
00157 }
00158 
00159 ORO_CREATE_COMPONENT(OCL::logging::Log4cxxAppender);


ocl
Author(s): OCL Development Team
autogenerated on Thu Jan 2 2014 11:38:08