LoggingService.cpp
Go to the documentation of this file.
2 #include "logging/Category.hpp"
3 #include "ocl/Component.hpp"
4 
5 #include <boost/algorithm/string.hpp>
6 #include <log4cpp/Category.hh>
7 #include <log4cpp/Priority.hh>
9 
10 #include <rtt/Logger.hpp>
11 #include <typeinfo>
12 
13 using namespace RTT;
14 using namespace std;
15 
16 namespace OCL {
17 namespace logging {
18 
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  level_EMERG_attr ("EMERG", log4cpp::Priority::EMERG ),
25  level_FATAL_attr ("FATAL", log4cpp::Priority::FATAL ),
26  level_ALERT_attr ("ALERT", log4cpp::Priority::ALERT ),
27  level_CRIT_attr ("CRIT", log4cpp::Priority::CRIT ),
28  level_ERROR_attr ("ERROR", log4cpp::Priority::ERROR ),
29  level_WARN_attr ("WARN", log4cpp::Priority::WARN ),
30  level_NOTICE_attr("NOTICE", log4cpp::Priority::NOTICE),
31  level_INFO_attr ("INFO", log4cpp::Priority::INFO ),
32  level_DEBUG_attr ("DEBUG", log4cpp::Priority::DEBUG ),
33  level_NOTSET_attr("NOTSET", log4cpp::Priority::NOTSET),
34  setCategoryPriority_mtd("setCategoryPriority", &LoggingService::setCategoryPriority, this),
35  getCategoryPriorityName_mtd("getCategoryPriorityName", &LoggingService::getCategoryPriorityName, this),
36  logCategories_mtd("logCategories", &LoggingService::logCategories, this)
37 {
41  this->provides()->addAttribute(level_EMERG_attr);
42  this->provides()->addAttribute(level_FATAL_attr);
43  this->provides()->addAttribute(level_ALERT_attr);
44  this->provides()->addAttribute(level_CRIT_attr);
45  this->provides()->addAttribute(level_ERROR_attr);
46  this->provides()->addAttribute(level_WARN_attr);
47  this->provides()->addAttribute(level_NOTICE_attr);
48  this->provides()->addAttribute(level_INFO_attr);
49  this->provides()->addAttribute(level_DEBUG_attr);
50  this->provides()->addAttribute(level_NOTSET_attr);
51  this->provides()->addOperation( setCategoryPriority_mtd ).doc("Set the priority of category to p").arg("name", "Name of the category").arg("p", "Priority to set");
52  this->provides()->addOperation( getCategoryPriorityName_mtd ).doc("Get the priority name of category").arg("name", "Name of the category");
53  this->provides()->addOperation( logCategories_mtd ).doc("Log category hierarchy (not realtime!)");
54 }
55 
57 {
58 }
59 
61 {
62  log(Debug) << "Configuring LoggingService" << endlog();
63 
64  // set the priority/level for each category
65 
66  PropertyBag bag = levels_prop.value(); // an empty bag is ok
67 
68  bool ok = true;
70  for (it=bag.getProperties().begin(); it != bag.getProperties().end(); ++it)
71  {
72  Property<std::string>* category = dynamic_cast<Property<std::string>* >( *it );
73  if ( !category )
74  {
75  log(Error) << "Expected Property '"
76  << (*it)->getName() << "' to be of type string." << endlog();
77  }
78  else
79  {
80  std::string categoryName = category->getName();
81  std::string levelName = category->value();
82 
83  // "" == categoryName implies the root category.
84 
85  // \todo else if level is empty
86 
87  // log4cpp only takes upper case
88  boost::algorithm::to_upper(levelName);
89 
91  try
92  {
93  priority = log4cpp::Priority::getPriorityValue(levelName);
94 
95  }
96  catch (std::invalid_argument)
97  {
98  // \todo more descriptive
99  log(Error) << "Bad level name: " << levelName << endlog();
100  return false;
101  }
102 
103  log(Debug) << "Getting category '" << categoryName << "'" << endlog();
104  // will create category if not exists
105  log4cpp::Category& category =
106  log4cpp::Category::getInstance(categoryName);
107 
108  category.setPriority(priority);
109  log(Info) << "Category '" << categoryName
110  << "' has priority '" << levelName << "'"
111  << endlog();
112  }
113  }
114 
115  // first clear all existing appenders in order to avoid double connects:
116  for(vector<string>::iterator it = active_appenders.begin(); it != active_appenders.end(); ++it) {
117  base::PortInterface* port = 0;
118  TaskContext* appender = getPeer(*it);
119  if (appender && (port = appender->ports()->getPort("LogPort")) )
120  port->disconnect();
121  }
122  if ( !active_appenders.empty() )
123  log(Warning) <<"Reconfiguring LoggingService '"<<getName() << "': I've removed all existing Appender connections and will now rebuild them."<<endlog();
124  active_appenders.clear();
125 
126  // set the additivity of each category
127 
128  bag = additivity_prop.value(); // an empty bag is ok
129 
130  for (it=bag.getProperties().begin(); it != bag.getProperties().end(); ++it)
131  {
132  Property<bool>* category = dynamic_cast<Property<bool>* >( *it );
133  if ( !category )
134  {
135  log(Error) << "Expected Property '"
136  << (*it)->getName() << "' to be of type boolean." << endlog();
137  }
138  else
139  {
140  std::string categoryName = category->getName();
141  bool additivity = category->value();
142 
143  // "" == categoryName implies the root category.
144 
145  log(Debug) << "Getting category '" << categoryName << "'" << endlog();
146  // will create category if not exists
147  log4cpp::Category& category =
148  log4cpp::Category::getInstance(categoryName);
149 
150  category.setAdditivity(additivity);
151  log(Info) << "Category '" << categoryName
152  << "' has additivity '" << std::string(additivity ? "on":"off") << "'"
153  << endlog();
154  }
155  }
156 
157  // create a port for each appender, and associate category/appender
158 
159  bag = appenders_prop.value(); // an empty bag is ok
160 
161  ok = true;
162  for (it=bag.getProperties().begin(); it != bag.getProperties().end(); ++it)
163  {
164  Property<std::string>* association = dynamic_cast<Property<std::string>* >( *it );
165  if ( !association )
166  {
167  log(Error) << "Expected Property '"
168  << (*it)->getName() << "' to be of type string." << endlog();
169  }
170  // \todo else if name or level are empty
171  else
172  {
173  std::string categoryName = association->getName();
174  std::string appenderName = association->value();
175 
176  // find category - will create category if not exists
178  OCL::logging::Category* category =
179  dynamic_cast<OCL::logging::Category*>(&p);
180  if (0 == category)
181  {
182  log(Error) << "Category '" << categoryName << "' is not an OCL category: type is '" << typeid(p).name() << "'" << endlog();
183  ok = false;
184  break;
185  }
186 
187  // find appender
188  RTT::TaskContext* appender = getPeer(appenderName);
189  if (appender)
190  {
191  // connect category port with appender port
192  RTT::base::PortInterface* appenderPort = 0;
193 
194  appenderPort = appender->ports()->getPort("LogPort");
195  if (appenderPort)
196  {
197  // \todo make connection policy configurable (from xml).
199  if ( appenderPort->connectTo( &(category->log_port), cp) )
200  {
201  std::stringstream str;
202  str << "Category '" << categoryName
203  << "' has appender '" << appenderName << "'"
204  << " with level "
206  log(Info) << str.str() << endlog();
207 // std::cout << str.str() << std::endl;
208  active_appenders.push_back(appenderName);
209  }
210  else
211  {
212  log(Error) << "Failed to connect port to appender '" << appenderName << "'" << endlog();
213  ok = false;
214  break;
215  }
216  }
217  else
218  {
219  log(Error) << "Failed to find log port in appender" << endlog();
220  ok = false;
221  break;
222  }
223  }
224  else
225  {
226  log(Error) << "Could not find appender '" << appenderName << "'" << endlog();
227  ok = false;
228  break;
229  }
230  }
231  }
232 
233  return ok;
234 }
235 
236 bool LoggingService::setCategoryPriority(const std::string& name,
237  const int priority)
238 {
239  bool rc = false; // prove otherwise
241  if (NULL != c)
242  {
243  try {
244  c->setPriority(priority);
245  const std::string level = log4cpp::Priority::getPriorityName(priority);
246  rc = true;
247  log(Info) << "Category '" << name << "' set to priority '" << level << "'" << endlog();
248  } catch (...) {
249  log(Error) << "Priority value '" << priority << "' is not known!" << endlog();
250  }
251  }
252  else
253  {
254  log(Error) << "Could not find category '" << name << "'" << endlog();
255  }
256  return rc;
257 }
258 
259 std::string LoggingService::getCategoryPriorityName(const std::string& name)
260 {
261  std::string rc;
263  if (NULL != c)
264  {
265  try {
267  log(Info) << "Category '" << name << "' has priority '" << rc << "'" << endlog();
268  } catch (...) {
269  rc = "UNKNOWN PRIORITY";
270  log(Error) << "Category '" << name << "' has unknown priority!" << endlog();
271  }
272  }
273  else
274  {
275  rc = "UNKNOWN CATEGORY";
276  log(Error) << "Could not find category '" << name << "'" << endlog();
277  }
278  return rc;
279 }
280 
281 // NOT realtime
283 {
284  std::vector<log4cpp::Category*>* categories =
286  assert(categories);
287  std::vector<log4cpp::Category*>::iterator iter;
288  log(Info) << "Number categories = " << (int)categories->size() << endlog();
289  for (iter = categories->begin(); iter != categories->end(); ++iter)
290  {
291  std::stringstream str;
292 
293  OCL::logging::Category* c = dynamic_cast<OCL::logging::Category*>(*iter);
294  str
295  << "Category '" << (*iter)->getName() << "', level="
296  << log4cpp::Priority::getPriorityName((*iter)->getPriority())
297  << ", typeid='"
298  << typeid(*iter).name()
299  << "', type really is '"
300  << std::string(0 != c ? "OCL::Category" : "log4cpp::Category")
301  << "', additivity=" << (const char*)((*iter)->getAdditivity()?"yes":"no");
302  if (0 != c)
303  {
304  str << ", port=" << (c->log_port.connected() ? "connected" : "not connected");
305  }
306  log4cpp::Category* p = (*iter)->getParent();
307  if (p)
308  {
309  str << ", parent name='" << p->getName() << "'";
310  }
311  else
312  {
313  str << ", No parent";
314  }
315 
316  log(Info) << str.str() << endlog();
317  }
318 }
319 
320 // namespaces
321 }
322 }
323 
RTT::OutputPort< OCL::logging::LoggingEvent > log_port
Definition: Category.hpp:162
std::vector< std::string > active_appenders
bool setCategoryPriority(const std::string &name, const int priority)
RTT::Property< RTT::PropertyBag > additivity_prop
Service::shared_ptr provides()
RTT::Attribute< int > level_NOTICE_attr
RTT::Attribute< int > level_WARN_attr
RTT::Attribute< int > level_ERROR_attr
virtual Category * getParent()
RTT::Attribute< int > level_NOTSET_attr
virtual void setAdditivity(bool additivity)
static Category & getInstance(const std::string &name)
ORO_LIST_COMPONENT_TYPE(OCL::logging::LoggingService)
reference_t value()
virtual TaskContext * getPeer(const std::string &peer_name) const
RTT::Attribute< int > level_FATAL_attr
RTT::Attribute< int > level_ALERT_attr
RTT::Attribute< int > level_EMERG_attr
RTT::Operation< std::string(std::string)> getCategoryPriorityName_mtd
virtual void disconnect()=0
DataFlowInterface * ports()
static const char * categoryName
Property< T > & addProperty(const std::string &name, T &attr)
base::PortInterface * getPort(const std::string &name) const
virtual const std::string & getName() const
RTT::Attribute< int > level_DEBUG_attr
static ConnPolicy buffer(int size, int lock_policy=LOCK_FREE, bool init_connection=false, bool pull=false)
Debug
virtual Priority::Value getPriority() const
virtual void setPriority(Priority::Value priority)
Properties & getProperties()
Properties::const_iterator const_iterator
static const int LOCK_FREE
Error
static std::vector< Category * > * getCurrentCategories()
#define DEBUG
Definition: rtt.cpp:45
RTT::Attribute< int > level_CRIT_attr
#define ERROR
Info
PropertyBag * properties()
static Category * exists(const std::string &name)
Warning
virtual bool connectTo(PortInterface *other, ConnPolicy const &policy)=0
RTT::Operation< bool(std::string, int)> setCategoryPriority_mtd
const std::string & getName() const
std::string getCategoryPriorityName(const std::string &name)
RTT::Attribute< int > level_INFO_attr
RTT::Property< RTT::PropertyBag > appenders_prop
RTT::Property< RTT::PropertyBag > levels_prop
static const std::string & getPriorityName(int priority)
ORO_CREATE_COMPONENT_TYPE()
RTT::Operation< void(void)> logCategories_mtd
static Value getPriorityValue(const std::string &priorityName)
virtual const std::string & getName() const


ocl
Author(s): OCL Development Team
autogenerated on Wed Jun 26 2019 19:26:27