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
00015
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),
00045 socketAppender(0),
00046 hostname_prop("localhost"), port_prop(4560),
00047 maxEventsPerCycle_prop(0),
00048 maxEventsPerCycle(1)
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
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
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;
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;
00098
00099
00100
00101
00102
00103 OCL::logging::LoggingEvent event;
00104 assert(socketAppender);
00105 assert(0 <= maxEventsPerCycle);
00106 if (0 == maxEventsPerCycle)
00107 {
00108
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;
00119 }
00120 }
00121 }
00122 else
00123 {
00124
00125
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;
00137 }
00138 --n;
00139 }
00140 while (0 < n);
00141 }
00142 }
00143
00144 void Log4cxxAppender::cleanupHook()
00145 {
00146
00147
00148
00149
00150 socketAppender->close();
00151 delete socketAppender;
00152 socketAppender = 0;
00153 }
00154
00155
00156 }
00157 }
00158
00159 ORO_CREATE_COMPONENT(OCL::logging::Log4cxxAppender);