70 void print(Ice::Int controlThreadId)
const;
71 virtual std::size_t
line()
const = 0;
72 virtual std::string
file()
const = 0;
73 virtual std::string
func()
const = 0;
74 virtual std::string
format()
const = 0;
83 float deactivateSpamSec{0};
85 std::uint64_t deactivateSpamTag_;
94 std::string
format() const final override;
95 std::
size_t line() const final override;
96 std::
string file() const final override;
97 std::
string func() const final override;
138 std::size_t numEntries,
139 std::size_t bufferMaxSize,
140 std::size_t bufferMaxNumberEntries);
148 void reset(std::size_t& bufferSize, std::size_t& numEntries, std::size_t iterationCount);
150 const std::vector<const RtMessageLogEntryBase*>&
getEntries()
const;
159 friend struct ::armarx::ControlThreadOutputBuffer;
160 friend class ::armarx::RobotUnit;
161 friend class ::armarx::RobotUnitModule::Logging;
163 const std::size_t initialBufferSize;
164 const std::size_t initialBufferEntryNumbers;
165 const std::size_t bufferMaxSize;
166 const std::size_t bufferMaxNumberEntries;
168 std::vector<std::uint8_t> buffer;
169 std::size_t bufferSpace;
172 std::vector<const RtMessageLogEntryBase*> entries;
173 std::size_t entriesWritten{0};
175 std::size_t requiredAdditionalBufferSpace{0};
176 std::size_t requiredAdditionalEntries{0};
177 std::size_t messagesLost{0};
179 std::size_t maxAlign{1};
189 std::size_t messageBufferSize,
190 std::size_t messageBufferNumberEntries,
191 std::size_t messageBufferMaxSize,
192 std::size_t messageBufferMaxNumberEntries);
194 bool minimize =
false);
208 std::vector<PropagateConst<SensorValueBase*>>
sensors;
209 std::vector<std::vector<PropagateConst<ControlTargetBase*>>>
control;
215 std::vector<std::uint8_t> buffer;
226 std::size_t
initialize(std::size_t numEntries,
229 std::size_t messageBufferSize,
230 std::size_t messageBufferNumberEntries,
231 std::size_t messageBufferMaxSize,
232 std::size_t messageBufferMaxNumberEntries);
239 return RtLoggingInstance;
257 template <
class LoggingEntryT,
class... Ts>
265 std::size_t toBounds(std::size_t idx)
const;
268 bool isInitialized{
false};
269 std::size_t numEntries{0};
271 std::atomic_size_t writePosition{0};
272 mutable std::atomic_size_t onePastLoggingReadPosition{0};
273 mutable std::atomic_size_t onePastReadPosition{0};
275 std::vector<Entry> entries;
276 std::vector<std::uint8_t> data;
278 std::size_t messageBufferSize{0};
279 std::size_t messageBufferEntries{0};
285#define ARMARX_RT_LOGF(...) \
286 (*(_detail_ARMARX_RT_LOGF(__FILE__, ARMARX_FUNCTION, __LINE__, __VA_ARGS__, true)))
288#define _detail_ARMARX_RT_LOGF(file_, func_, line_, FormatString, ...) \
292 using namespace ::armarx; \
293 using RtMessageLogEntryBase = ControlThreadOutputBuffer::RtMessageLogEntryBase; \
294 struct RtMessageLogEntry : RtMessageLogEntryBase \
296 using TupleT = decltype(std::make_tuple(__VA_ARGS__)); \
297 const TupleT tuple; \
298 ARMARX_MINIMAL_PLACEMENT_CONSTRUCTION_HELPER \
300 line() const final override \
305 file() const final override \
310 func() const final override \
315 format() const final override \
317 return TupleToStringF<0, std::tuple_size<TupleT>::value - 1>(FormatString, \
320 RtMessageLogEntry(TupleT tuple) : tuple{std::move(tuple)} \
323 RtMessageLogEntry(const RtMessageLogEntry&) = default; \
325 if (::armarx::ControlThreadOutputBuffer::GetRtLoggingInstance()) \
327 return ::armarx::ControlThreadOutputBuffer::GetRtLoggingInstance() \
328 ->addMessageToLog<RtMessageLogEntry>(__VA_ARGS__); \
332 *(loghelper(file_, line_, func_)) \
333 << "Redirected RT Logging:\n" \
334 << RtMessageLogEntry(std::make_tuple(__VA_ARGS__)).format(); \
335 return dynamic_cast<RtMessageLogEntryBase*>( \
336 &::armarx::detail::RtMessageLogEntryNull::Instance); \
340#define ARMARX_RT_LOGF_DEBUG(...) \
341 ARMARX_RT_LOGF(__VA_ARGS__).setLoggingLevel(::armarx::MessageTypeT::DEBUG)
342#define ARMARX_RT_LOGF_VERBOSE(...) \
343 ARMARX_RT_LOGF(__VA_ARGS__).setLoggingLevel(::armarx::MessageTypeT::VERBOSE)
344#define ARMARX_RT_LOGF_INFO(...) \
345 ARMARX_RT_LOGF(__VA_ARGS__).setLoggingLevel(::armarx::MessageTypeT::INFO)
346#define ARMARX_RT_LOGF_IMPORTANT(...) \
347 ARMARX_RT_LOGF(__VA_ARGS__).setLoggingLevel(::armarx::MessageTypeT::IMPORTANT)
348#define ARMARX_RT_LOGF_WARNING(...) \
349 ARMARX_RT_LOGF(__VA_ARGS__).setLoggingLevel(::armarx::MessageTypeT::WARN)
350#define ARMARX_RT_LOGF_WARN(...) \
351 ARMARX_RT_LOGF(__VA_ARGS__).setLoggingLevel(::armarx::MessageTypeT::WARN)
352#define ARMARX_RT_LOGF_ERROR(...) \
353 ARMARX_RT_LOGF(__VA_ARGS__).setLoggingLevel(::armarx::MessageTypeT::ERROR)
354#define ARMARX_RT_LOGF_FATAL(...) \
355 ARMARX_RT_LOGF(__VA_ARGS__).setLoggingLevel(::armarx::MessageTypeT::FATAL)
369 throw std::logic_error{
"called 'format' of RtMessageLogEntryDummy"};
375 throw std::logic_error{
"called 'line' of RtMessageLogEntryDummy"};
381 throw std::logic_error{
"called 'file' of RtMessageLogEntryDummy"};
387 throw std::logic_error{
"called 'func' of RtMessageLogEntryDummy"};
391 std::size_t numEntries,
392 std::size_t bufferMaxSize,
393 std::size_t bufferMaxNumberEntries) :
394 initialBufferSize{bufferSize},
395 initialBufferEntryNumbers{numEntries},
396 bufferMaxSize{bufferMaxSize},
397 bufferMaxNumberEntries{bufferMaxNumberEntries},
398 buffer(bufferSize, 0),
399 bufferSpace{buffer.size()},
400 bufferPlace{buffer.
data()},
401 entries(numEntries, nullptr)
403 ARMARX_DEBUG <<
"RtMessageLogBuffer created with bufferSize=" << bufferSize
404 <<
" and numEntries=" << numEntries <<
" and bufferMaxSize=" << bufferMaxSize
405 <<
" and bufferMaxNumberEntries " << bufferMaxNumberEntries;
413 inline const std::vector<const RtMessageLogEntryBase*>&
422 return bufferMaxSize;
428 return bufferMaxNumberEntries;
434 return buffer.size();
441 ControlThreadOutputBuffer::toBounds(std::size_t idx)
const
443 return idx % numEntries;
452 template <
class LoggingEntryT,
class... Ts>
457 if (messages.entries.size() <= messages.entriesWritten)
459 ++messages.requiredAdditionalEntries;
460 ++messages.messagesLost;
463 messages.maxAlign = std::max(messages.maxAlign,
alignof(LoggingEntryT));
464 void* place =
std::align(
alignof(LoggingEntryT),
465 sizeof(LoggingEntryT),
466 messages.bufferPlace,
467 messages.bufferSpace);
470 messages.requiredAdditionalBufferSpace +=
471 sizeof(LoggingEntryT) +
alignof(LoggingEntryT) - 1;
472 ++messages.messagesLost;
476 new (place) LoggingEntryT(std::make_tuple(std::forward<Ts>(args)...));
478 messages.bufferPlace =
static_cast<std::uint8_t*
>(place) +
sizeof(LoggingEntryT);
480 messages.bufferSpace -=
sizeof(LoggingEntryT);
483 messages.entries.at(messages.entriesWritten++) = entry;
#define ARMARX_MINIMAL_PLACEMENT_CONSTRUCTION_HELPER
#define ARMARX_MINIMAL_PLACEMENT_CONSTRUCTION_HELPER_BASE(CommonBaseType)
This class is pretty much similar to a map.
This Module manages logging of data.
The RobotUnit class manages a robot and its controllers.
#define ARMARX_CHECK_IS_NULL(ptr)
This macro evaluates whether ptr is null and if it turns out to be false it will throw an ExpressionE...
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
This file offers overloads of toIce() and fromIce() functions for STL container types.
detail::ControlThreadOutputBufferEntry SensorAndControl
This file is part of ArmarX.
void * align(size_t alignment, size_t bytes, void *&bufferPlace, size_t &bufferSpace) noexcept
std::size_t initialize(std::size_t numEntries, const KeyValueVector< std::string, ControlDevicePtr > &controlDevices, const KeyValueVector< std::string, SensorDevicePtr > &sensorDevices, std::size_t messageBufferSize, std::size_t messageBufferNumberEntries, std::size_t messageBufferMaxSize, std::size_t messageBufferMaxNumberEntries)
void forEachNewLoggingEntry(ConsumerFunctor consumer)
detail::RtMessageLogEntryBase RtMessageLogEntryBase
void forLatestLoggingEntry(ConsumerFunctor consumer, size_t numberOfEntriesToLog)
std::function< void(const Entry &, std::size_t, std::size_t)> ConsumerFunctor
~ControlThreadOutputBuffer()
static ControlThreadOutputBuffer * GetRtLoggingInstance()
detail::ControlThreadOutputBufferEntry Entry
bool updateReadBuffer() const
const Entry & getReadBuffer() const
void resetLoggingPosition() const
std::size_t getNumberOfBytes() const
RtMessageLogEntryBase * addMessageToLog(Ts &&... args)
IceUtil::Time writeTimestamp
Timestamp in wall time (never use the virtual time for this)
IceUtil::Time sensorValuesTimestamp
ControlThreadOutputBufferEntry & operator=(const ControlThreadOutputBufferEntry &)=delete
ControlThreadOutputBufferEntry(const KeyValueVector< std::string, ControlDevicePtr > &controlDevices, const KeyValueVector< std::string, SensorDevicePtr > &sensorDevices, std::size_t messageBufferSize, std::size_t messageBufferNumberEntries, std::size_t messageBufferMaxSize, std::size_t messageBufferMaxNumberEntries)
IceUtil::Time timeSinceLastIteration
std::size_t getDataBufferSize() const
std::vector< PropagateConst< SensorValueBase * > > sensors
RtMessageLogBuffer messages
ControlThreadOutputBufferEntry(ControlThreadOutputBufferEntry &&)=delete
ControlThreadOutputBufferEntry()=delete
ControlThreadOutputBufferEntry & operator=(ControlThreadOutputBufferEntry &&)=delete
const std::vector< const RtMessageLogEntryBase * > & getEntries() const
RtMessageLogBuffer & operator=(RtMessageLogBuffer &&)=delete
RtMessageLogBuffer & operator=(const RtMessageLogBuffer &)=delete
friend struct ControlThreadOutputBufferEntry
std::size_t getMaximalNumberOfBufferEntries() const
RtMessageLogBuffer(RtMessageLogBuffer &&)=delete
RtMessageLogBuffer()=delete
std::size_t getMaximalBufferSize() const
void reset(std::size_t &bufferSize, std::size_t &numEntries, std::size_t iterationCount)
RtMessageLogBuffer(const RtMessageLogBuffer &other, bool minimize=false)
RtMessageLogEntryBase & setLoggingLevel(MessageTypeT lvl)
void print(Ice::Int controlThreadId) const
virtual std::string func() const =0
RtMessageLogEntryBase & deactivateSpamTag(std::uint64_t tag)
virtual ~RtMessageLogEntryBase()=default
virtual std::string file() const =0
friend struct RtMessageLogBuffer
IceUtil::Time getTime() const
virtual std::string format() const =0
virtual std::size_t line() const =0
RtMessageLogEntryBase & deactivateSpam(float sec)
std::size_t line() const final override
std::string func() const final override
static RtMessageLogEntryDummy Instance
std::string format() const final override
std::string file() const final override
std::size_t line() const final override
std::string func() const final override
static RtMessageLogEntryNull Instance
std::string format() const final override
std::string file() const final override