converters/log.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Aldebaran
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #include "log.hpp"
19 
20 #include <qicore/logmessage.hpp>
21 #include <queue>
22 
23 #include <std_msgs/String.h>
24 
25 #include <boost/algorithm/string.hpp>
26 #include <boost/thread/mutex.hpp>
27 #include <boost/foreach.hpp>
28 
29 #include <ros/console.h>
30 
31 #define for_each BOOST_FOREACH
32 
33 namespace naoqi
34 {
35 namespace converter
36 {
37 
39 boost::mutex MUTEX_LOGS;
41 std::queue<rosgraph_msgs::Log> LOGS;
43 class LogLevel
44 {
45 public:
46  LogLevel(qi::LogLevel qi, rosgraph_msgs::Log::_level_type ros_msg, ros::console::levels::Level ros_console) :
47  qi_(qi), ros_msg_(ros_msg), ros_console_(ros_console)
48  {
49  all_.push_back(*this);
50  }
51 
52  static const LogLevel& get_from_qi(qi::LogLevel qi)
53  {
54  for_each(const LogLevel& log_level, all_)
55  if (log_level.qi_ == qi)
56  return log_level;
57  }
58 
59  static const LogLevel& get_from_ros_msg(rosgraph_msgs::Log::_level_type ros_msg)
60  {
61  for_each(const LogLevel& log_level, all_)
62  if (log_level.ros_msg_ == ros_msg)
63  return log_level;
64  }
65 
67  {
68  for_each(const LogLevel& log_level, all_)
69  if (log_level.ros_console_ == ros_console)
70  return log_level;
71  }
72 
73  qi::LogLevel qi_;
74  rosgraph_msgs::Log::_level_type ros_msg_;
76 
77 private:
78  static std::vector<LogLevel> all_;
79 };
80 
81 std::vector<LogLevel> LogLevel::all_ = std::vector<LogLevel>();
82 
85 void logCallback(const qi::LogMessage& msg)
86 {
87  // Convert the NAOqi log to a ROS log
88  rosgraph_msgs::Log log;
89 
90  std::vector<std::string> results;
91  boost::split(results, msg.source, boost::is_any_of(":"));
92  log.file = results[0];
93  log.function = results[1];
94  log.line = atoi(results[2].c_str());
95  log.level = LogLevel::get_from_qi(msg.level).ros_msg_;
96  log.name = msg.category;
97  log.msg = msg.message;
98  log.header.stamp = ros::Time(msg.timestamp.tv_sec, msg.timestamp.tv_usec);
99 
100  // If we are not publishing, the queue will increase, so we have to prevent an explosion
101  // We only keep a log if it's within 5 second of the last publish (totally arbitrary)
102  boost::mutex::scoped_lock lock( MUTEX_LOGS );
103  while (LOGS.size() > 1000)
104  {
105  LOGS.pop();
106  }
107  LOGS.push(log);
108 }
109 
110 LogConverter::LogConverter( const std::string& name, float frequency, const qi::SessionPtr& session )
111  : BaseConverter( name, frequency, session ),
112  logger_( session->service("LogManager") ),
113  // Default log level is info
114  log_level_(qi::LogLevel_Info)
115 {
116  // Define the log equivalents
118  LogLevel(qi::LogLevel_Fatal, rosgraph_msgs::Log::FATAL, ros::console::levels::Fatal);
119  LogLevel(qi::LogLevel_Error, rosgraph_msgs::Log::ERROR, ros::console::levels::Error);
120  LogLevel(qi::LogLevel_Warning, rosgraph_msgs::Log::WARN, ros::console::levels::Warn);
121  LogLevel(qi::LogLevel_Info, rosgraph_msgs::Log::INFO, ros::console::levels::Info);
124 
125  listener_ = logger_->getListener();
127  listener_->onLogMessage.connect(logCallback);
128 }
129 
131 {
132  callbacks_[action] = cb;
133 }
134 
135 void LogConverter::callAll( const std::vector<message_actions::MessageAction>& actions )
136 {
137  while ( !LOGS.empty() )
138  {
139  rosgraph_msgs::Log& log_msg = LOGS.front();
141  {
142  callbacks_[action](log_msg);
143  }
144  {
145  boost::mutex::scoped_lock lock( MUTEX_LOGS );
146  LOGS.pop();
147  }
148  }
150 }
151 
153 {
154 }
155 
157 {
158  // Check that the log level is above or equal to the current one
159  std::map<std::string, ros::console::levels::Level> loggers;
160  ros::console::get_loggers(loggers);
161 
162  std::map<std::string, ros::console::levels::Level>::iterator iter = loggers.find("ros.naoqi_driver");
163 
164  if (iter == loggers.end())
165  return;
166 
167  qi::LogLevel new_level = LogLevel::get_from_ros_console(iter->second).qi_;
168  // Only change the log level if it has changed (otherwise, there is a flood of warnings)
169  if (new_level == log_level_)
170  return;
171 
172  log_level_ = new_level;
173  qi::log::setLogLevel(log_level_);
174 }
175 
176 } // publisher
177 } //naoqi
INLINE Rall1d< T, V, S > log(const Rall1d< T, V, S > &arg)
void callAll(const std::vector< message_actions::MessageAction > &actions)
boost::function< void(rosgraph_msgs::Log &) > Callback_t
ROSCONSOLE_DECL bool get_loggers(std::map< std::string, levels::Level > &loggers)
void logCallback(const qi::LogMessage &msg)
#define DEBUG
static const LogLevel & get_from_ros_console(ros::console::levels::Level ros_console)
std::map< message_actions::MessageAction, Callback_t > callbacks_
LogConverter(const std::string &name, float frequency, const qi::SessionPtr &sessions)
static const LogLevel & get_from_ros_msg(rosgraph_msgs::Log::_level_type ros_msg)
void registerCallback(const message_actions::MessageAction action, Callback_t cb)
boost::mutex MUTEX_LOGS
action
rosgraph_msgs::Log::_level_type ros_msg_
std::queue< rosgraph_msgs::Log > LOGS
LogLevel(qi::LogLevel qi, rosgraph_msgs::Log::_level_type ros_msg, ros::console::levels::Level ros_console)
static const LogLevel & get_from_qi(qi::LogLevel qi)
#define for_each
static std::vector< LogLevel > all_
ros::console::levels::Level ros_console_


naoqi_driver
Author(s): Karsten Knese
autogenerated on Sat Feb 15 2020 03:24:26