1 #include "logging/LoggingService.hpp" 2 #include "logging/Category.hpp" 5 #include <boost/algorithm/string.hpp> 6 #include <log4cpp/Category.hh> 7 #include <log4cpp/Priority.hh> 8 #include <log4cpp/HierarchyMaintainer.hh> 10 #include <rtt/Logger.hpp> 19 LoggingService::LoggingService(std::string name) :
20 RTT::TaskContext(name),
21 levels_prop(
"Levels",
"A PropertyBag defining the level of each category of interest."),
22 additivity_prop(
"Additivity",
"A PropertyBag defining the additivity of each category of interest."),
23 appenders_prop(
"Appenders",
"A PropertyBag defining the appenders for each category of interest."),
24 logCategories_mtd(
"logCategories", &LoggingService::logCategories, this)
26 this->properties()->addProperty( levels_prop );
27 this->properties()->addProperty( additivity_prop );
28 this->properties()->addProperty( appenders_prop );
29 this->provides()->addOperation( logCategories_mtd ).doc(
"Log category hierarchy (not realtime!)");
32 LoggingService::~LoggingService()
36 bool LoggingService::configureHook()
38 log(Debug) <<
"Configuring LoggingService" << endlog();
42 PropertyBag bag = levels_prop.value();
45 PropertyBag::const_iterator it;
46 for (it=bag.getProperties().begin(); it != bag.getProperties().end(); ++it)
48 Property<std::string>* category =
dynamic_cast<Property<std::string>*
>( *it );
51 log(Error) <<
"Expected Property '" 52 << (*it)->getName() <<
"' to be of type string." << endlog();
56 std::string categoryName = category->getName();
57 std::string levelName = category->value();
64 boost::algorithm::to_upper(levelName);
66 log4cpp::Priority::Value priority = log4cpp::Priority::NOTSET;
69 priority = log4cpp::Priority::getPriorityValue(levelName);
72 catch (std::invalid_argument)
75 log(Error) <<
"Bad level name: " << levelName << endlog();
79 log(Debug) <<
"Getting category '" << categoryName <<
"'" << endlog();
80 log4cpp::Category& category =
81 log4cpp::Category::getInstance(categoryName);
83 category.setPriority(priority);
84 log(Info) <<
"Category '" << categoryName
85 <<
"' has priority '" << levelName <<
"'" 91 for(vector<string>::iterator it = active_appenders.begin(); it != active_appenders.end(); ++it) {
92 base::PortInterface* port = 0;
93 TaskContext* appender = getPeer(*it);
94 if (appender && (port = appender->ports()->getPort(
"LogPort")) )
97 if ( !active_appenders.empty() )
98 log(Warning) <<
"Reconfiguring LoggingService '"<<getName() <<
"': I've removed all existing Appender connections and will now rebuild them."<<endlog();
99 active_appenders.clear();
103 bag = additivity_prop.value();
105 for (it=bag.getProperties().begin(); it != bag.getProperties().end(); ++it)
107 Property<bool>* category =
dynamic_cast<Property<bool>*
>( *it );
110 log(Error) <<
"Expected Property '" 111 << (*it)->getName() <<
"' to be of type boolean." << endlog();
115 std::string categoryName = category->getName();
116 bool additivity = category->value();
120 log(Debug) <<
"Getting category '" << categoryName <<
"'" << endlog();
121 log4cpp::Category& category =
122 log4cpp::Category::getInstance(categoryName);
124 category.setAdditivity(additivity);
125 log(Info) <<
"Category '" << categoryName
126 <<
"' has additivity '" << std::string(additivity ?
"on":
"off") <<
"'" 133 bag = appenders_prop.value();
136 for (it=bag.getProperties().begin(); it != bag.getProperties().end(); ++it)
138 Property<std::string>* association =
dynamic_cast<Property<std::string>*
>( *it );
141 log(Error) <<
"Expected Property '" 142 << (*it)->getName() <<
"' to be of type string." << endlog();
147 std::string categoryName = association->getName();
148 std::string appenderName = association->value();
151 log4cpp::Category* p = log4cpp::HierarchyMaintainer::getDefaultMaintainer().getExistingInstance(categoryName);
158 log(Error) <<
"Category '" << categoryName <<
"' is not an OCL category: type is '" <<
typeid(*p).name() <<
"'" << endlog();
162 log(Error) <<
"Category '" << categoryName <<
"' does not exist!" << endlog();
169 RTT::TaskContext* appender = getPeer(appenderName);
173 RTT::base::PortInterface* appenderPort = 0;
175 appenderPort = appender->ports()->getPort(
"LogPort");
179 ConnPolicy cp = ConnPolicy::buffer(100,ConnPolicy::LOCK_FREE,
false,
false);
180 if ( appenderPort->connectTo( &(category->log_port), cp) )
182 std::stringstream str;
183 str <<
"Category '" << categoryName
184 <<
"' has appender '" << appenderName <<
"'" 186 << log4cpp::Priority::getPriorityName(category->getPriority());
187 log(Info) << str.str() << endlog();
189 active_appenders.push_back(appenderName);
193 log(Error) <<
"Failed to connect port to appender '" << appenderName <<
"'" << endlog();
200 log(Error) <<
"Failed to find log port in appender" << endlog();
207 log(Error) <<
"Could not find appender '" << appenderName <<
"'" << endlog();
218 void LoggingService::logCategories()
220 std::vector<log4cpp::Category*>* categories =
221 log4cpp::Category::getCurrentCategories();
223 std::vector<log4cpp::Category*>::iterator iter;
224 log(Info) <<
"Number categories = " << (int)categories->size() << endlog();
225 for (iter = categories->begin(); iter != categories->end(); ++iter)
227 std::stringstream str;
230 <<
"Category '" << (*iter)->getName() <<
"', level=" 231 << log4cpp::Priority::getPriorityName((*iter)->getPriority())
233 <<
typeid(*iter).name()
234 <<
"', type really is '" 235 << std::string(0 != dynamic_cast<OCL::logging::Category*>(*iter)
236 ?
"OCL::Category" :
"log4cpp::Category")
237 <<
"', additivity=" << (
const char*)((*iter)->getAdditivity()?
"yes":
"no");
238 log4cpp::Category* p = (*iter)->getParent();
241 str <<
", parent name='" << p->getName() <<
"'";
245 str <<
", No parent";
248 log(Info) << str.str() << endlog();
256 ORO_CREATE_COMPONENT_TYPE();
This component is responsible for reading the logging configuration setting up the logging categories...
This file contains the macros and definitions to create dynamically loadable components.
The Orocos Component Library.
A real-time capable category.