mc_rtc  2.14.0
Logger.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015-2021 CNRS-UM LIRMM, CNRS-AIST JRL
3  */
4 
5 #pragma once
6 
7 #include <mc_rtc/log/utils.h>
8 #include <mc_rtc/logging.h>
9 #include <mc_rtc/utils_api.h>
10 
11 #include <mc_rtc/Configuration.h>
12 
13 #include <memory>
14 #include <unordered_map>
15 #include <variant>
16 
17 namespace mc_rtc
18 {
19 
20 struct LoggerImpl;
30 {
31 public:
33  static const uint8_t magic[4];
38  static const uint8_t version;
40  typedef std::function<void(mc_rtc::MessagePackBuilder &)> serialize_fn;
42  enum struct Policy
43  {
51  NON_THREADED = 0,
59  THREADED = 1
60  };
61 
64  {
68  std::string key;
69  };
70 
73  {
75  std::string key;
76  };
77 
79  struct GUIEvent
80  {
82  std::vector<std::string> category;
84  std::string name;
87  };
88 
95  struct StartEvent
96  {
97  };
98 
99  using LogEvent = std::variant<KeyAddedEvent, KeyRemovedEvent, GUIEvent, StartEvent>;
100 
102  struct Meta
103  {
105  double timestep;
107  std::string main_robot;
109  std::vector<std::string> main_robot_module;
111  std::map<std::string, sva::PTransformd> init;
113  std::map<std::string, std::vector<std::vector<double>>> init_q;
115  std::map<std::string, std::map<std::string, mc_rtc::Configuration>> calibs;
116  };
117 
118 public:
127  Logger(const Policy & policy, const std::string & directory, const std::string & tmpl);
128 
131 
140  void setup(const Policy & policy, const std::string & directory, const std::string & tmpl);
141 
143  inline Meta & meta() noexcept { return meta_; }
144 
146  inline const Meta & meta() const noexcept { return meta_; }
147 
162  void start(const std::string & ctl_name, double timestep, bool resume = false, double start_t = 0.0);
163 
175  void open(const std::string & file, double timestep, double start_t = 0.0);
176 
182  void log();
183 
205  template<typename CallbackT,
206  typename SourceT = void,
207  typename std::enable_if<mc_rtc::log::callback_is_serializable<CallbackT>::value, int>::type = 0>
208  void addLogEntry(const std::string & name, const SourceT * source, CallbackT && get_fn, bool overwrite = false)
209  {
210  using ret_t = decltype(get_fn());
211  using base_t = typename std::decay<ret_t>::type;
212  auto it = find_entry(name);
213  if(it != log_entries_.end())
214  {
215  if(!overwrite)
216  {
217  log::error("Already logging an entry named {}", name);
218  return;
219  }
220  else
221  {
222  log_entries_.erase(it);
223  }
224  }
226  log_events_.push_back(KeyAddedEvent{log_type, name});
227  log_entries_.push_back({log_type, name, source, [get_fn](mc_rtc::MessagePackBuilder & builder) mutable
228  { mc_rtc::log::LogWriter<base_t>::write(get_fn(), builder); }});
229  }
230 
246  template<typename MemberPtrT,
247  MemberPtrT member,
248  typename SourceT,
249  typename std::enable_if<mc_rtc::log::is_serializable_member<MemberPtrT>::value, int>::type = 0>
250  void addLogEntry(const std::string & name, const SourceT * source, bool overwrite = false)
251  {
252  using MemberT = decltype(source->*member);
253  addLogEntry(name, source, [source]() -> const MemberT & { return source->*member; }, overwrite);
254  }
255 
271  template<typename MethodPtrT,
272  MethodPtrT method,
273  typename SourceT,
274  typename std::enable_if<mc_rtc::log::is_serializable_getter<MethodPtrT>::value, int>::type = 0>
275  void addLogEntry(const std::string & name, const SourceT * source, bool overwrite = false)
276  {
277  using MethodRetT = decltype((source->*method)());
278  addLogEntry(name, source, [source]() -> MethodRetT { return (source->*method)(); }, overwrite);
279  }
280 
296  template<typename T, typename std::enable_if<mc_rtc::log::callback_is_serializable<T>::value, int>::type = 0>
297  void addLogEntry(const std::string & name, T && get_fn, bool overwrite = false)
298  {
299  addLogEntry(name, static_cast<const void *>(nullptr), std::forward<T>(get_fn), overwrite);
300  }
301 
314  template<typename SourceT, typename CallbackT, typename... Args>
315  void addLogEntries(const SourceT * source, const std::string & name, CallbackT && get_fn, Args &&... args)
316  {
317  addLogEntry(name, source, get_fn);
318  addLogEntries(source, std::forward<Args>(args)...);
319  }
320 
325  inline void addGUIEvent(GUIEvent && event) { log_events_.push_back(std::move(event)); }
326 
334  void removeLogEntry(const std::string & name);
335 
343  void removeLogEntries(const void * source);
344 
346  double t() const;
347 
352  const std::string & path() const;
353 
355  void flush();
356 
358  inline size_t size() const { return log_entries_.size(); }
359 
366  void clear(bool record = true);
367 
368 private:
370  struct LogEntry
371  {
373  log::LogType type;
375  std::string key;
377  const void * source;
379  serialize_fn log_cb;
380  };
382  std::shared_ptr<LoggerImpl> impl_ = nullptr;
384  Meta meta_;
386  std::vector<LogEvent> log_events_;
388  std::vector<LogEntry> log_entries_;
389 
390  std::vector<LogEntry>::iterator find_entry(const std::string & name);
391 
393  template<typename SourceT>
394  void addLogEntries(const SourceT *)
395  {
396  }
397 };
398 
400 #define MC_RTC_LOG_HELPER(NAME, MEMBER) \
401  do \
402  { \
403  using ThisT = typename std::remove_pointer<decltype(this)>::type; \
404  logger.addLogEntry<decltype(&ThisT::MEMBER), &ThisT::MEMBER>(NAME, this); \
405  } while(0)
406 
408 #define MC_RTC_LOG_GETTER(NAME, METHOD) \
409  do \
410  { \
411  using MethodRetT = decltype(this->METHOD()); \
412  logger.addLogEntry(NAME, this, [this]() -> MethodRetT { return METHOD(); }); \
413  } while(0)
414 
415 } // namespace mc_rtc
void error(Args &&... args)
Definition: logging.h:63
LogType
Definition: utils.h:13
Definition: Contact.h:88
Simplify access to values hold within a JSON file.
Definition: Configuration.h:166
GUI callback event.
Definition: Logger.h:80
std::string name
Definition: Logger.h:84
mc_rtc::Configuration data
Definition: Logger.h:86
std::vector< std::string > category
Definition: Logger.h:82
Data for a key added event.
Definition: Logger.h:64
log::LogType type
Definition: Logger.h:66
std::string key
Definition: Logger.h:68
Data for a key removed event.
Definition: Logger.h:73
std::string key
Definition: Logger.h:75
Log meta data written in the first call to log after a call to \start.
Definition: Logger.h:103
std::string main_robot
Definition: Logger.h:107
std::map< std::string, std::map< std::string, mc_rtc::Configuration > > calibs
Definition: Logger.h:115
std::map< std::string, std::vector< std::vector< double > > > init_q
Definition: Logger.h:113
std::vector< std::string > main_robot_module
Definition: Logger.h:109
double timestep
Definition: Logger.h:105
std::map< std::string, sva::PTransformd > init
Definition: Logger.h:111
Start event.
Definition: Logger.h:96
Logs controller data to disk.
Definition: Logger.h:30
const Meta & meta() const noexcept
Access the log's metadata (const)
Definition: Logger.h:146
size_t size() const
Definition: Logger.h:358
Policy
Defines available policies for the logger.
Definition: Logger.h:43
Logger(const Policy &policy, const std::string &directory, const std::string &tmpl)
Constructor.
static const uint8_t version
Definition: Logger.h:38
void removeLogEntry(const std::string &name)
std::variant< KeyAddedEvent, KeyRemovedEvent, GUIEvent, StartEvent > LogEvent
Definition: Logger.h:99
void clear(bool record=true)
void removeLogEntries(const void *source)
void addLogEntry(const std::string &name, T &&get_fn, bool overwrite=false)
Definition: Logger.h:297
void addLogEntries(const SourceT *source, const std::string &name, CallbackT &&get_fn, Args &&... args)
Definition: Logger.h:315
void addGUIEvent(GUIEvent &&event)
Definition: Logger.h:325
std::function< void(mc_rtc::MessagePackBuilder &)> serialize_fn
Definition: Logger.h:40
~Logger()
Destructor.
Meta & meta() noexcept
Access the log's metadata.
Definition: Logger.h:143
const std::string & path() const
void start(const std::string &ctl_name, double timestep, bool resume=false, double start_t=0.0)
Start logging.
void setup(const Policy &policy, const std::string &directory, const std::string &tmpl)
Setup the constructor configuration.
void addLogEntry(const std::string &name, const SourceT *source, bool overwrite=false)
Definition: Logger.h:250
void open(const std::string &file, double timestep, double start_t=0.0)
Open a new file for logging.
void addLogEntry(const std::string &name, const SourceT *source, CallbackT &&get_fn, bool overwrite=false)
Definition: Logger.h:208
double t() const
void log()
Log controller's data.
Definition: MessagePackBuilder.h:87
static void write(const T &data, mc_rtc::MessagePackBuilder &builder)
Definition: utils.h:185
#define MC_RTC_UTILS_DLLAPI
Definition: utils_api.h:50