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