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 
130  ~Logger();
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 { log_entries_.erase(it); }
221  }
223  log_events_.push_back(KeyAddedEvent{log_type, name});
224  log_entries_.push_back({log_type, name, source, [get_fn](mc_rtc::MessagePackBuilder & builder) mutable
225  { mc_rtc::log::LogWriter<base_t>::write(get_fn(), builder); }});
226  }
227 
243  template<typename MemberPtrT,
244  MemberPtrT member,
245  typename SourceT,
246  typename std::enable_if<mc_rtc::log::is_serializable_member<MemberPtrT>::value, int>::type = 0>
247  void addLogEntry(const std::string & name, const SourceT * source, bool overwrite = false)
248  {
249  using MemberT = decltype(source->*member);
250  addLogEntry(name, source, [source]() -> const MemberT & { return source->*member; }, overwrite);
251  }
252 
268  template<typename MethodPtrT,
269  MethodPtrT method,
270  typename SourceT,
271  typename std::enable_if<mc_rtc::log::is_serializable_getter<MethodPtrT>::value, int>::type = 0>
272  void addLogEntry(const std::string & name, const SourceT * source, bool overwrite = false)
273  {
274  using MethodRetT = decltype((source->*method)());
275  addLogEntry(name, source, [source]() -> MethodRetT { return (source->*method)(); }, overwrite);
276  }
277 
293  template<typename T, typename std::enable_if<mc_rtc::log::callback_is_serializable<T>::value, int>::type = 0>
294  void addLogEntry(const std::string & name, T && get_fn, bool overwrite = false)
295  {
296  addLogEntry(name, static_cast<const void *>(nullptr), std::forward<T>(get_fn), overwrite);
297  }
298 
311  template<typename SourceT, typename CallbackT, typename... Args>
312  void addLogEntries(const SourceT * source, const std::string & name, CallbackT && get_fn, Args &&... args)
313  {
314  addLogEntry(name, source, get_fn);
315  addLogEntries(source, std::forward<Args>(args)...);
316  }
317 
322  inline void addGUIEvent(GUIEvent && event) { log_events_.push_back(std::move(event)); }
323 
331  void removeLogEntry(const std::string & name);
332 
340  void removeLogEntries(const void * source);
341 
343  double t() const;
344 
349  const std::string & path() const;
350 
352  void flush();
353 
355  inline size_t size() const { return log_entries_.size(); }
356 
363  void clear(bool record = true);
364 
365 private:
367  struct LogEntry
368  {
370  log::LogType type;
372  std::string key;
374  const void * source;
376  serialize_fn log_cb;
377  };
379  std::shared_ptr<LoggerImpl> impl_ = nullptr;
381  Meta meta_;
383  std::vector<LogEvent> log_events_;
385  std::vector<LogEntry> log_entries_;
386 
387  std::vector<LogEntry>::iterator find_entry(const std::string & name);
388 
390  template<typename SourceT>
391  void addLogEntries(const SourceT *)
392  {
393  }
394 };
395 
397 #define MC_RTC_LOG_HELPER(NAME, MEMBER) \
398  do { \
399  using ThisT = typename std::remove_pointer<decltype(this)>::type; \
400  logger.addLogEntry<decltype(&ThisT::MEMBER), &ThisT::MEMBER>(NAME, this); \
401  } while(0)
402 
404 #define MC_RTC_LOG_GETTER(NAME, METHOD) \
405  do { \
406  using MethodRetT = decltype(this->METHOD()); \
407  logger.addLogEntry(NAME, this, [this]() -> MethodRetT { return METHOD(); }); \
408  } while(0)
409 
410 } // namespace mc_rtc
mc_rtc::Configuration
Simplify access to values hold within a JSON file.
Definition: Configuration.h:165
mc_rtc::Logger::StartEvent
Start event.
Definition: Logger.h:95
mc_rtc::MessagePackBuilder
Definition: MessagePackBuilder.h:86
mc_rtc::Logger::meta
Meta & meta() noexcept
Access the log's metadata.
Definition: Logger.h:143
mc_rtc::Logger::KeyAddedEvent::type
log::LogType type
Definition: Logger.h:66
mc_rtc::Logger::GUIEvent::category
std::vector< std::string > category
Definition: Logger.h:82
mc_rtc::log::LogWriter::write
static void write(const T &data, mc_rtc::MessagePackBuilder &builder)
Definition: utils.h:185
mc_rtc::log::callback_is_serializable
Definition: utils.h:167
mc_rtc::log::LogType
LogType
Definition: utils.h:12
mc_rtc::Logger::Meta
Log meta data written in the first call to log after a call to \start.
Definition: Logger.h:102
mc_rtc::Logger::KeyAddedEvent
Data for a key added event.
Definition: Logger.h:63
mc_rtc::Logger::addLogEntry
void addLogEntry(const std::string &name, const SourceT *source, bool overwrite=false)
Definition: Logger.h:247
mc_rtc::Logger::addGUIEvent
void addGUIEvent(GUIEvent &&event)
Definition: Logger.h:322
mc_rtc::Logger
Logs controller data to disk.
Definition: Logger.h:29
mc_rtc::Logger::LogEvent
std::variant< KeyAddedEvent, KeyRemovedEvent, GUIEvent, StartEvent > LogEvent
Definition: Logger.h:99
mc_rtc::Logger::KeyRemovedEvent
Data for a key removed event.
Definition: Logger.h:72
mc_rtc::Logger::KeyAddedEvent::key
std::string key
Definition: Logger.h:68
mc_rtc::Logger::Meta::timestep
double timestep
Definition: Logger.h:105
mc_rtc::Logger::Meta::main_robot
std::string main_robot
Definition: Logger.h:107
utils.h
mc_rtc::Logger::meta
const Meta & meta() const noexcept
Access the log's metadata (const)
Definition: Logger.h:146
MC_RTC_UTILS_DLLAPI
#define MC_RTC_UTILS_DLLAPI
Definition: utils_api.h:50
mc_rtc::Logger::Meta::main_robot_module
std::vector< std::string > main_robot_module
Definition: Logger.h:109
mc_rtc::Logger::addLogEntry
void addLogEntry(const std::string &name, T &&get_fn, bool overwrite=false)
Definition: Logger.h:294
Configuration.h
utils_api.h
mc_rtc::Logger::Meta::init_q
std::map< std::string, std::vector< std::vector< double > > > init_q
Definition: Logger.h:113
mc_rtc::Logger::GUIEvent::data
mc_rtc::Configuration data
Definition: Logger.h:86
mc_rtc::Logger::Policy
Policy
Defines available policies for the logger.
Definition: Logger.h:42
mc_rtc::Logger::Meta::init
std::map< std::string, sva::PTransformd > init
Definition: Logger.h:111
logging.h
mc_rtc::Logger::KeyRemovedEvent::key
std::string key
Definition: Logger.h:75
mc_rtc::log::error
void error(Args &&... args)
Definition: logging.h:63
mc_rtc::Logger::addLogEntry
void addLogEntry(const std::string &name, const SourceT *source, CallbackT &&get_fn, bool overwrite=false)
Definition: Logger.h:208
mc_rtc::Logger::version
static const uint8_t version
Definition: Logger.h:38
mc_rtc::Logger::size
size_t size() const
Definition: Logger.h:355
mc_rtc::Logger::GUIEvent
GUI callback event.
Definition: Logger.h:79
mc_rtc::Logger::serialize_fn
std::function< void(mc_rtc::MessagePackBuilder &)> serialize_fn
Definition: Logger.h:40
mc_rtc::Logger::GUIEvent::name
std::string name
Definition: Logger.h:84
mc_rtc::Logger::addLogEntries
void addLogEntries(const SourceT *source, const std::string &name, CallbackT &&get_fn, Args &&... args)
Definition: Logger.h:312
mc_rtc::Logger::Meta::calibs
std::map< std::string, std::map< std::string, mc_rtc::Configuration > > calibs
Definition: Logger.h:115
mc_rtc
Definition: Contact.h:87