Robot Raconteur Core C++ Library
Logging.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include "RobotRaconteurConfig.h"
28 #include <boost/smart_ptr/intrusive_ref_counter.hpp>
29 
30 #include <fstream>
31 
32 namespace RobotRaconteur
33 {
34 
35 class ROBOTRACONTEUR_CORE_API RobotRaconteurNode;
36 class ROBOTRACONTEUR_CORE_API MessageStringRef;
37 
38 // Inspired by Boost.Log V2
39 
48 class ROBOTRACONTEUR_CORE_API RRLogRecord
49 {
50  public:
52  RR_WEAK_PTR<RobotRaconteurNode> Node;
58  std::string ComponentName;
60  std::string ComponentObjectID;
62  int64_t Endpoint;
64  std::string ServicePath;
66  std::string Member;
68  std::string Message;
70  boost::posix_time::ptime Time;
72  std::string SourceFile;
74  uint32_t SourceLine;
76  std::string ThreadID;
78  std::string FiberID;
79 
80  RRLogRecord();
81 };
82 
84 ROBOTRACONTEUR_CORE_API std::ostream& operator<<(std::ostream& out, const RRLogRecord& record);
85 
87 ROBOTRACONTEUR_CORE_API std::string RRLogRecord_Level_ToString(RobotRaconteur_LogLevel level);
89 ROBOTRACONTEUR_CORE_API std::string RRLogRecord_Component_ToString(RobotRaconteur_LogComponent component);
91 ROBOTRACONTEUR_CORE_API std::string RRLogRecord_Node_ToString(const RR_WEAK_PTR<RobotRaconteurNode>& node);
92 
93 class ROBOTRACONTEUR_CORE_API RRLogRecordStream : public boost::intrusive_ref_counter<RRLogRecordStream>
94 {
95  protected:
96  RRLogRecord record;
97  RR_SHARED_PTR<RobotRaconteurNode> node;
98  std::stringstream ss;
99 
100  public:
101  RRLogRecordStream(const RR_SHARED_PTR<RobotRaconteurNode>& node);
102  RRLogRecordStream(const RR_SHARED_PTR<RobotRaconteurNode>& node, RobotRaconteur_LogLevel lvl,
103  RobotRaconteur_LogComponent component, int64_t ep, const boost::posix_time::ptime& time,
104  const std::string& source_file, uint32_t source_line, const std::string& thread_id);
105  RRLogRecordStream(const RR_SHARED_PTR<RobotRaconteurNode>& node, RobotRaconteur_LogLevel lvl,
106  RobotRaconteur_LogComponent component, const std::string& component_name,
107  const std::string& component_object_id, int64_t ep, const std::string& service_path,
108  const std::string& member, const boost::posix_time::ptime& time, const std::string& source_file,
109  uint32_t source_line, const std::string& thread_id, const std::string& fiber_id);
110  ~RRLogRecordStream();
111  std::stringstream& Stream();
112 
113  static RR_INTRUSIVE_PTR<RRLogRecordStream> OpenRecordStream(
114  RR_WEAK_PTR<RobotRaconteurNode> node, RobotRaconteur_LogLevel lvl, RobotRaconteur_LogComponent component,
115  const std::string& component_name, const std::string& component_object_id, int64_t ep,
116  MessageStringRef service_path, MessageStringRef member_name, const std::string& source_file,
117  uint32_t source_line);
118 };
119 
129 class ROBOTRACONTEUR_CORE_API LogRecordHandler
130 {
131  public:
139  virtual void HandleLogRecord(const RRLogRecord& record) = 0;
140  virtual ~LogRecordHandler() {}
141 };
142 
148 class ROBOTRACONTEUR_CORE_API FileLogRecordHandler : public LogRecordHandler
149 {
150  std::ofstream file;
151 
152  public:
159  void OpenFile(const std::string& filename, bool append = true);
160  RR_OVIRTUAL void HandleLogRecord(const RRLogRecord& record) RR_OVERRIDE;
161 };
162 
163 #define ROBOTRACONTEUR_LOG_EMPTY_NODE
164 #define ROBOTRACONTEUR_LOG_DEFAULT_NODE RobotRaconteur::RobotRaconteurNode::weak_sp()
165 
166 #ifndef ROBOTRACONTEUR_DISABLE_LOGGING
167 
168 // NOLINTBEGIN(bugprone-macro-parentheses)
169 #define ROBOTRACONTEUR_LOG(node, lvl, component, component_name, component_object_id, ep, service_path, member, args) \
170  { \
171  boost::intrusive_ptr<RobotRaconteur::RRLogRecordStream> ____rr_log_record_stream____ = \
172  RobotRaconteur::RRLogRecordStream::OpenRecordStream( \
173  node, RobotRaconteur::RobotRaconteur_LogLevel_##lvl, \
174  RobotRaconteur::RobotRaconteur_LogComponent_##component, component_name, component_object_id, ep, \
175  service_path, member, __FILE__, __LINE__); \
176  if (____rr_log_record_stream____) \
177  { \
178  ____rr_log_record_stream____->Stream() << args; \
179  } \
180  }
181 
182 // NOLINTEND(bugprone-macro-parentheses)
183 
184 // TODO: Implement throttling
185 #define ROBOTRACONTEUR_LOG_THROTTLE(node, lvl, component, component_name, component_object_id, ep, service_path, \
186  member, limit, args) \
187  ROBOTRACONTEUR_LOG(node, lvl, component, component_name, component_object_id, ep, service_path, member, args)
188 #else
189 #define ROBOTRACONTEUR_LOG(node, lvl, component, component_name, component_object_id, ep, service_path, member, args)
190 #define ROBOTRACONTEUR_LOG_THROTTLE(node, lvl, component, component_name, component_object_id, ep, service_path, \
191  member, limit, args)
192 #endif
193 
194 #define ROBOTRACONTEUR_LOG_FATAL(node, args) ROBOTRACONTEUR_LOG(node, Fatal, Default, "", "", -1, "", "", args)
195 #define ROBOTRACONTEUR_LOG_FATAL_DEFAULT(args) \
196  ROBOTRACONTEUR_LOG(ROBOTRACONTEUR_LOG_DEFAULT_NODE, Fatal, Default, "", "", -1, "", "", args)
197 #define ROBOTRACONTEUR_LOG_FATAL_COMPONENT(node, component, ep, args) \
198  ROBOTRACONTEUR_LOG(node, Fatal, component, "", "", ep, "", "", args)
199 #define ROBOTRACONTEUR_LOG_FATAL_COMPONENT_PATH(node, component, ep, service_path, member, args) \
200  ROBOTRACONTEUR_LOG(node, Fatal, component, "", "", ep, service_path, member, args)
201 #define ROBOTRACONTEUR_LOG_FATAL_COMPONENTNAME(node, component, component_name, component_object_id, ep, args) \
202  ROBOTRACONTEUR_LOG(node, Fatal, component, component_name, component_object_id, ep, "", "", args)
203 #define ROBOTRACONTEUR_LOG_FATAL_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
204  service_path, member, args) \
205  ROBOTRACONTEUR_LOG(node, Fatal, component, component_name, component_object_id, ep, service_path, member, args)
206 #define ROBOTRACONTEUR_LOG_FATAL_THROTTLE(node, component, ep, limit, args) \
207  ROBOTRACONTEUR_LOG_THROTTLE(node, Fatal, component, "", "", ep, "", "", limit, args)
208 #define ROBOTRACONTEUR_LOG_FATAL_THROTTLE_PATH(node, component, ep, service_path, member, limit, args) \
209  ROBOTRACONTEUR_LOG_THROTTLE(node, Fatal, component, "", "", ep, service_path, member, limit, args)
210 #define ROBOTRACONTEUR_LOG_FATAL_THROTTLE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
211  service_path, member, limit, args) \
212  ROBOTRACONTEUR_LOG_THROTTLE(node, Fatal, component, component_name, component_object_id, ep, service_path, member, \
213  limit, args)
214 
215 #define ROBOTRACONTEUR_LOG_ERROR(node, args) ROBOTRACONTEUR_LOG(node, Error, Default, "", "", -1, "", "", args)
216 #define ROBOTRACONTEUR_LOG_ERROR_DEFAULT(args) \
217  ROBOTRACONTEUR_LOG(ROBOTRACONTEUR_LOG_DEFAULT_NODE, Error, Default, "", "", -1, "", "", args)
218 #define ROBOTRACONTEUR_LOG_ERROR_COMPONENT(node, component, ep, args) \
219  ROBOTRACONTEUR_LOG(node, Error, component, "", "", ep, "", "", args)
220 #define ROBOTRACONTEUR_LOG_ERROR_COMPONENT_PATH(node, component, ep, service_path, member, args) \
221  ROBOTRACONTEUR_LOG(node, Error, component, "", "", ep, service_path, member, args)
222 #define ROBOTRACONTEUR_LOG_ERROR_COMPONENTNAME(node, component, component_name, component_object_id, ep, args) \
223  ROBOTRACONTEUR_LOG(node, Error, component, component_name, component_object_id, ep, "", "", args)
224 #define ROBOTRACONTEUR_LOG_ERROR_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
225  service_path, member, args) \
226  ROBOTRACONTEUR_LOG(node, Error, component, component_name, component_object_id, ep, service_path, member, args)
227 #define ROBOTRACONTEUR_LOG_ERROR_THROTTLE(node, component, ep, limit, args) \
228  ROBOTRACONTEUR_LOG_THROTTLE(node, Error, component, "", "", ep, "", "", limit, args)
229 #define ROBOTRACONTEUR_LOG_ERROR_THROTTLE_PATH(node, component, ep, service_path, member, limit, args) \
230  ROBOTRACONTEUR_LOG_THROTTLE(node, Error, component, "", "", ep, service_path, member, limit, args)
231 #define ROBOTRACONTEUR_LOG_ERROR_THROTTLE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
232  service_path, member, limit, args) \
233  ROBOTRACONTEUR_LOG_THROTTLE(node, Error, component, component_name, component_object_id, ep, service_path, member, \
234  limit, args)
235 
236 #define ROBOTRACONTEUR_LOG_WARNING(node, args) ROBOTRACONTEUR_LOG(node, Warning, Default, "", "", -1, "", "", args)
237 #define ROBOTRACONTEUR_LOG_WARNING_DEFAULT(args) \
238  ROBOTRACONTEUR_LOG(ROBOTRACONTEUR_LOG_DEFAULT_NODE, Warning, Default, "", "", -1, "", "", args)
239 #define ROBOTRACONTEUR_LOG_WARNING_COMPONENT(node, component, ep, args) \
240  ROBOTRACONTEUR_LOG(node, Warning, component, "", "", ep, "", "", args)
241 #define ROBOTRACONTEUR_LOG_WARNING_COMPONENT_PATH(node, component, ep, service_path, member, args) \
242  ROBOTRACONTEUR_LOG(node, Warning, component, "", "", ep, service_path, member, args)
243 #define ROBOTRACONTEUR_LOG_WARNING_COMPONENTNAME(node, component, component_name, component_object_id, ep, args) \
244  ROBOTRACONTEUR_LOG(node, Warning, component, component_name, component_object_id, ep, "", "", args)
245 #define ROBOTRACONTEUR_LOG_WARNING_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
246  service_path, member, args) \
247  ROBOTRACONTEUR_LOG(node, Warning, component, component_name, component_object_id, ep, service_path, member, args)
248 #define ROBOTRACONTEUR_LOG_WARNING_THROTTLE(node, component, ep, limit, args) \
249  ROBOTRACONTEUR_LOG_THROTTLE(node, Warning, component, "", "", ep, "", "", limit, args)
250 #define ROBOTRACONTEUR_LOG_WARNING_THROTTLE_PATH(node, component, ep, service_path, member, limit, args) \
251  ROBOTRACONTEUR_LOG_THROTTLE(node, Warning, component, "", "", ep, service_path, member, limit, args)
252 #define ROBOTRACONTEUR_LOG_WARNING_THROTTLE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, \
253  ep, service_path, member, limit, args) \
254  ROBOTRACONTEUR_LOG_THROTTLE(node, Warning, component, component_name, component_object_id, ep, service_path, \
255  member, limit, args)
256 
257 #define ROBOTRACONTEUR_LOG_INFO(node, args) ROBOTRACONTEUR_LOG(node, Info, Default, "", "", -1, "", "", args)
258 #define ROBOTRACONTEUR_LOG_INFO_DEFAULT(args) \
259  ROBOTRACONTEUR_LOG(ROBOTRACONTEUR_LOG_DEFAULT_NODE, Info, Default, "", "", -1, "", "", args)
260 #define ROBOTRACONTEUR_LOG_INFO_COMPONENT(node, component, ep, args) \
261  ROBOTRACONTEUR_LOG(node, Info, component, "", "", ep, "", "", args)
262 #define ROBOTRACONTEUR_LOG_INFO_COMPONENT_PATH(node, component, ep, service_path, member, args) \
263  ROBOTRACONTEUR_LOG(node, Info, component, "", "", ep, service_path, member, args)
264 #define ROBOTRACONTEUR_LOG_INFO_COMPONENTNAME(node, component, component_name, component_object_id, ep, args) \
265  ROBOTRACONTEUR_LOG(node, Info, component, component_name, component_object_id, ep, "", "", args)
266 #define ROBOTRACONTEUR_LOG_INFO_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
267  service_path, member, args) \
268  ROBOTRACONTEUR_LOG(node, Info, component, component_name, component_object_id, ep, service_path, member, args)
269 #define ROBOTRACONTEUR_LOG_INFO_THROTTLE(node, component, ep, limit, args) \
270  ROBOTRACONTEUR_LOG_THROTTLE(node, Info, component, "", "", ep, "", "", limit, args)
271 #define ROBOTRACONTEUR_LOG_INFO_THROTTLE_PATH(node, component, ep, service_path, member, limit, args) \
272  ROBOTRACONTEUR_LOG_THROTTLE(node, Info, component, "", "", ep, service_path, member, limit, args)
273 #define ROBOTRACONTEUR_LOG_INFO_THROTTLE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
274  service_path, member, limit, args) \
275  ROBOTRACONTEUR_LOG_THROTTLE(node, Info, component, component_name, component_object_id, ep, service_path, member, \
276  limit, args)
277 
278 #define ROBOTRACONTEUR_LOG_DEBUG(node, args) ROBOTRACONTEUR_LOG(node, Debug, Default, "", "", -1, "", "", args)
279 #define ROBOTRACONTEUR_LOG_DEBUG_DEFAULT(args) \
280  ROBOTRACONTEUR_LOG(ROBOTRACONTEUR_LOG_DEFAULT_NODE, Debug, Default, "", "", -1, "", "", args)
281 #define ROBOTRACONTEUR_LOG_DEBUG_COMPONENT(node, component, ep, args) \
282  ROBOTRACONTEUR_LOG(node, Debug, component, "", "", ep, "", "", args)
283 #define ROBOTRACONTEUR_LOG_DEBUG_COMPONENT_PATH(node, component, ep, service_path, member, args) \
284  ROBOTRACONTEUR_LOG(node, Debug, component, "", "", ep, service_path, member, args)
285 #define ROBOTRACONTEUR_LOG_DEBUG_COMPONENTNAME(node, component, component_name, component_object_id, ep, args) \
286  ROBOTRACONTEUR_LOG(node, Debug, component, component_name, component_object_id, ep, "", "", args)
287 #define ROBOTRACONTEUR_LOG_DEBUG_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
288  service_path, member, args) \
289  ROBOTRACONTEUR_LOG(node, Debug, component, component_name, component_object_id, ep, service_path, member, args)
290 #define ROBOTRACONTEUR_LOG_DEBUG_THROTTLE(node, component, ep, limit, args) \
291  ROBOTRACONTEUR_LOG_THROTTLE(node, Debug, component, "", "", ep, "", "", limit, args)
292 #define ROBOTRACONTEUR_LOG_DEBUG_THROTTLE_PATH(node, component, ep, service_path, member, limit, args) \
293  ROBOTRACONTEUR_LOG_THROTTLE(node, Debug, component, "", "", ep, service_path, member, limit, args)
294 #define ROBOTRACONTEUR_LOG_DEBUG_THROTTLE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
295  service_path, member, limit, args) \
296  ROBOTRACONTEUR_LOG_THROTTLE(node, Debug, component, component_name, component_object_id, ep, service_path, member, \
297  limit, args)
298 
299 #ifndef NDEBUG
300 #define ROBOTRACONTEUR_LOG_TRACE(node, args) ROBOTRACONTEUR_LOG(node, Trace, Default, "", "", -1, "", "", args)
301 #define ROBOTRACONTEUR_LOG_TRACE_DEFAULT(args) \
302  ROBOTRACONTEUR_LOG(ROBOTRACONTEUR_LOG_DEFAULT_NODE, Trace, Default, "", "", -1, "", "", args)
303 #define ROBOTRACONTEUR_LOG_TRACE_COMPONENT(node, component, ep, args) \
304  ROBOTRACONTEUR_LOG(node, Trace, component, "", "", ep, "", "", args)
305 #define ROBOTRACONTEUR_LOG_TRACE_COMPONENT_PATH(node, component, ep, service_path, member, args) \
306  ROBOTRACONTEUR_LOG(node, Trace, component, "", "", ep, service_path, member, args)
307 #define ROBOTRACONTEUR_LOG_TRACE_COMPONENTNAME(node, component, component_name, component_object_id, ep, args) \
308  ROBOTRACONTEUR_LOG(node, Trace, component, component_name, component_object_id, ep, "", "", args)
309 #define ROBOTRACONTEUR_LOG_TRACE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
310  service_path, member, args) \
311  ROBOTRACONTEUR_LOG(node, Trace, component, component_name, component_object_id, ep, service_path, member, args)
312 #define ROBOTRACONTEUR_LOG_TRACE_THROTTLE(node, component, ep, limit, args) \
313  ROBOTRACONTEUR_LOG_THROTTLE(node, Trace, component, "", "", ep, "", "", limit, args)
314 #define ROBOTRACONTEUR_LOG_TRACE_THROTTLE_PATH(node, component, ep, service_path, member, limit, args) \
315  ROBOTRACONTEUR_LOG_THROTTLE(node, Trace, component, "", "", ep, service_path, member, limit, args)
316 #define ROBOTRACONTEUR_LOG_TRACE_THROTTLE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
317  service_path, member, limit, args) \
318  ROBOTRACONTEUR_LOG_THROTTLE(node, Trace, component, component_name, component_object_id, ep, service_path, member, \
319  limit, args)
320 #else
321 // Disable Trace log level in release builds for performance
322 #define ROBOTRACONTEUR_LOG_TRACE(node, args)
323 #define ROBOTRACONTEUR_LOG_TRACE_DEFAULT(args)
324 #define ROBOTRACONTEUR_LOG_TRACE_COMPONENT(node, component, ep, args)
325 #define ROBOTRACONTEUR_LOG_TRACE_COMPONENT_PATH(node, component, ep, service_path, member, args)
326 #define ROBOTRACONTEUR_LOG_TRACE_COMPONENTNAME(node, component, component_name, component_object_id, ep, args)
327 #define ROBOTRACONTEUR_LOG_TRACE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
328  service_path, member, args)
329 #define ROBOTRACONTEUR_LOG_TRACE_THROTTLE(node, component, ep, limit, args)
330 #define ROBOTRACONTEUR_LOG_TRACE_THROTTLE_PATH(node, component, ep, service_path, member, limit, args)
331 #define ROBOTRACONTEUR_LOG_TRACE_THROTTLE_COMPONENTNAME_PATH(node, component, component_name, component_object_id, ep, \
332  service_path, member, limit, args)
333 
334 #endif
335 
336 #ifndef ROBOTRACONTEUR_NO_CXX11_TEMPLATE_ALIASES
337 using RRLogRecordStreamPtr = RR_INTRUSIVE_PTR<RRLogRecordStream>;
338 using RRLogRecordStreamConstPtr = RR_INTRUSIVE_PTR<const RRLogRecordStream>;
340 using LogRecordHandlerPtr = RR_SHARED_PTR<LogRecordHandler>;
342 using LogRecordHandlerConstPtr = RR_SHARED_PTR<const LogRecordHandler>;
344 using FileLogRecordHandlerPtr = RR_SHARED_PTR<FileLogRecordHandler>;
346 using FileLogRecordHandlerConstPtr = RR_SHARED_PTR<const FileLogRecordHandler>;
347 #endif
348 
349 } // namespace RobotRaconteur
boost::shared_ptr< const LogRecordHandler > LogRecordHandlerConstPtr
Convenience alias for LogRecordHandler const shared_ptr.
Definition: Logging.h:342
boost::shared_ptr< LogRecordHandler > LogRecordHandlerPtr
Convenience alias for LogRecordHandler shared_ptr.
Definition: Logging.h:340
std::string RRLogRecord_Node_ToString(const RR_WEAK_PTR< RobotRaconteurNode > &node)
Convert a RobotRaconteurNode weak_ptr to a NodeID string. Returns "unknown" if could not resolve.
boost::shared_ptr< FileLogRecordHandler > FileLogRecordHandlerPtr
Convenience alias for FileLogRecordHandler shared_ptr.
Definition: Logging.h:344
std::string RRLogRecord_Level_ToString(RobotRaconteur_LogLevel level)
Convert a RobotRaconteur_LogLevel code to a string.
std::string RRLogRecord_Component_ToString(RobotRaconteur_LogComponent component)
Convert a RobotRaconteur_LogComponent code to a string.
boost::shared_ptr< const FileLogRecordHandler > FileLogRecordHandlerConstPtr
Convenience alias for FileLogRecordHandler const shared_ptr.
Definition: Logging.h:346
RobotRaconteur_LogLevel
Log level enum.
Definition: RobotRaconteurConstants.h:608
RobotRaconteur_LogComponent
Log component enum.
Definition: RobotRaconteurConstants.h:633
Log record handler that saves to a file.
Definition: Logging.h:149
void OpenFile(const std::string &filename, bool append=true)
Open a file to store log records.
Base class of log record handler.
Definition: Logging.h:130
virtual void HandleLogRecord(const RRLogRecord &record)=0
Function to accept log records from node.
Robot Raconteur log record.
Definition: Logging.h:49
int64_t Endpoint
The source endpoint.
Definition: Logging.h:62
RR_WEAK_PTR< RobotRaconteurNode > Node
The source node.
Definition: Logging.h:52
std::string ComponentObjectID
The source component object ID.
Definition: Logging.h:60
std::string SourceFile
The sourcecode filename.
Definition: Logging.h:72
std::string ComponentName
The source component name.
Definition: Logging.h:58
boost::posix_time::ptime Time
Time of logging event.
Definition: Logging.h:70
std::string FiberID
The source coroutine fiber.
Definition: Logging.h:78
RobotRaconteur_LogComponent Component
The source component.
Definition: Logging.h:56
RobotRaconteur_LogLevel Level
The log level.
Definition: Logging.h:54
std::string Member
The source member.
Definition: Logging.h:66
uint32_t SourceLine
The line within the sourcecode file.
Definition: Logging.h:74
std::string Message
Human readable log message.
Definition: Logging.h:68
std::string ThreadID
The source thread.
Definition: Logging.h:76
std::string ServicePath
The service path of the source object.
Definition: Logging.h:64