Go to the documentation of this file.00001 #include "logging/LoggingService.hpp"
00002 #include "logging/Category.hpp"
00003 #include "ocl/Component.hpp"
00004
00005 #include <boost/algorithm/string.hpp>
00006 #include <log4cpp/Category.hh>
00007 #include <log4cpp/Priority.hh>
00008 #include <log4cpp/HierarchyMaintainer.hh>
00009
00010 #include <rtt/Logger.hpp>
00011 #include <typeinfo>
00012
00013 using namespace RTT;
00014 using namespace std;
00015
00016 namespace OCL {
00017 namespace logging {
00018
00019 LoggingService::LoggingService(std::string name) :
00020 RTT::TaskContext(name),
00021 levels_prop("Levels","A PropertyBag defining the level of each category of interest."),
00022 appenders_prop("Appenders","A PropertyBag defining the appenders for each category of interest."),
00023 logCategories_mtd("logCategories", &LoggingService::logCategories, this)
00024 {
00025 this->properties()->addProperty( levels_prop );
00026 this->properties()->addProperty( appenders_prop );
00027 this->provides()->addOperation( logCategories_mtd ).doc("Log category hierarchy (not realtime!)");
00028 }
00029
00030 LoggingService::~LoggingService()
00031 {
00032 }
00033
00034 bool LoggingService::configureHook()
00035 {
00036 log(Debug) << "Configuring LoggingService" << endlog();
00037
00038
00039
00040 PropertyBag bag = levels_prop.value();
00041
00042 bool ok = true;
00043 PropertyBag::const_iterator it;
00044 for (it=bag.getProperties().begin(); it != bag.getProperties().end(); ++it)
00045 {
00046 Property<std::string>* category = dynamic_cast<Property<std::string>* >( *it );
00047 if ( !category )
00048 {
00049 log(Error) << "Expected Property '"
00050 << (*it)->getName() << "' to be of type string." << endlog();
00051 }
00052 else
00053 {
00054 std::string categoryName = category->getName();
00055 std::string levelName = category->value();
00056
00057
00058
00059
00060
00061
00062 boost::algorithm::to_upper(levelName);
00063
00064 log4cpp::Priority::Value priority = log4cpp::Priority::NOTSET;
00065 try
00066 {
00067 priority = log4cpp::Priority::getPriorityValue(levelName);
00068
00069 }
00070 catch (std::invalid_argument)
00071 {
00072
00073 log(Error) << "Bad level name: " << levelName << endlog();
00074 return false;
00075 }
00076
00077 log(Debug) << "Getting category '" << categoryName << "'" << endlog();
00078 log4cpp::Category& category =
00079 log4cpp::Category::getInstance(categoryName);
00080
00081 category.setPriority(priority);
00082 log(Info) << "Category '" << categoryName
00083 << "' has priority '" << levelName << "'"
00084 << endlog();
00085 }
00086 }
00087
00088
00089 for(vector<string>::iterator it = active_appenders.begin(); it != active_appenders.end(); ++it) {
00090 base::PortInterface* port = 0;
00091 TaskContext* appender = getPeer(*it);
00092 if (appender && (port = appender->ports()->getPort("LogPort")) )
00093 port->disconnect();
00094 }
00095 if ( !active_appenders.empty() )
00096 log(Warning) <<"Reconfiguring LoggingService '"<<getName() << "': I've removed all existing Appender connections and will now rebuild them."<<endlog();
00097 active_appenders.clear();
00098
00099
00100
00101 bag = appenders_prop.value();
00102
00103 ok = true;
00104 for (it=bag.getProperties().begin(); it != bag.getProperties().end(); ++it)
00105 {
00106 Property<std::string>* association = dynamic_cast<Property<std::string>* >( *it );
00107 if ( !association )
00108 {
00109 log(Error) << "Expected Property '"
00110 << (*it)->getName() << "' to be of type string." << endlog();
00111 }
00112
00113 else
00114 {
00115 std::string categoryName = association->getName();
00116 std::string appenderName = association->value();
00117
00118
00119 log4cpp::Category* p = log4cpp::HierarchyMaintainer::getDefaultMaintainer().getExistingInstance(categoryName);
00120 OCL::logging::Category* category =
00121 dynamic_cast<OCL::logging::Category*>(p);
00122 if (0 == category)
00123 {
00124 if (0 != p)
00125 {
00126 log(Error) << "Category '" << categoryName << "' is not an OCL category: type is '" << typeid(*p).name() << "'" << endlog();
00127 }
00128 else
00129 {
00130 log(Error) << "Category '" << categoryName << "' does not exist!" << endlog();
00131 }
00132 ok = false;
00133 break;
00134 }
00135
00136
00137 RTT::TaskContext* appender = getPeer(appenderName);
00138 if (appender)
00139 {
00140
00141 RTT::base::PortInterface* appenderPort = 0;
00142
00143 appenderPort = appender->ports()->getPort("LogPort");
00144 if (appenderPort)
00145 {
00146
00147 ConnPolicy cp = ConnPolicy::buffer(100,ConnPolicy::LOCK_FREE,false,false);
00148 if ( appenderPort->connectTo( &(category->log_port), cp) )
00149 {
00150 std::stringstream str;
00151 str << "Category '" << categoryName
00152 << "' has appender '" << appenderName << "'"
00153 << " with level "
00154 << log4cpp::Priority::getPriorityName(category->getPriority());
00155 log(Info) << str.str() << endlog();
00156
00157 active_appenders.push_back(appenderName);
00158 }
00159 else
00160 {
00161 log(Error) << "Failed to connect port to appender '" << appenderName << "'" << endlog();
00162 ok = false;
00163 break;
00164 }
00165 }
00166 else
00167 {
00168 log(Error) << "Failed to find log port in appender" << endlog();
00169 ok = false;
00170 break;
00171 }
00172 }
00173 else
00174 {
00175 log(Error) << "Could not find appender '" << appenderName << "'" << endlog();
00176 ok = false;
00177 break;
00178 }
00179 }
00180 }
00181
00182 return ok;
00183 }
00184
00185
00186 void LoggingService::logCategories()
00187 {
00188 std::vector<log4cpp::Category*>* categories =
00189 log4cpp::Category::getCurrentCategories();
00190 assert(categories);
00191 std::vector<log4cpp::Category*>::iterator iter;
00192 log(Info) << "Number categories = " << (int)categories->size() << endlog();
00193 for (iter = categories->begin(); iter != categories->end(); ++iter)
00194 {
00195 log(Info)
00196 << "Category '" << (*iter)->getName() << "', level="
00197 << log4cpp::Priority::getPriorityName((*iter)->getPriority())
00198 << ", typeid='"
00199 << typeid(*iter).name()
00200 << "', type really is '"
00201 << std::string(0 != dynamic_cast<OCL::logging::Category*>(*iter)
00202 ? "OCL::Category" : "log4cpp::Category")
00203 << "'" << endlog();
00204 }
00205 }
00206
00207
00208 }
00209 }
00210
00211 ORO_CREATE_COMPONENT_TYPE();
00212 ORO_LIST_COMPONENT_TYPE(OCL::logging::LoggingService);