4#include <condition_variable>
70 static constexpr std::uint16_t DEVICE_NAME_BUFFER_SIZE = 64;
72 static constexpr std::uint16_t MESSAGE_BUFFER_SIZE = 1024;
73 static constexpr std::uint16_t IDENTIFIER_BUFFER_SIZE = 128;
74 static constexpr char OVERFLOW_MESSAGE[] = {
"[ERROR MESSAGE TOO LONG]"};
75 static_assert(MESSAGE_BUFFER_SIZE >
sizeof(OVERFLOW_MESSAGE) + 1);
77 static constexpr std::uint16_t FILE_STRING_BUFFER_SIZE = 256;
78 static constexpr std::uint16_t FUNCTION_STRING_BUFFER_SIZE = 256;
83 char m_message[MESSAGE_BUFFER_SIZE];
84 std::size_t m_message_size = 0;
85 char m_identifier[IDENTIFIER_BUFFER_SIZE];
86 std::size_t m_identifier_size = 0;
89 char m_device_name[DEVICE_NAME_BUFFER_SIZE];
91 IceUtil::Time m_timestamp;
92 std::uint64_t m_bus_iteration_number = 0;
93 float m_deactivate_spam_seconds = 0;
97 char file[FILE_STRING_BUFFER_SIZE];
99 char function[FUNCTION_STRING_BUFFER_SIZE];
108 template <
typename...
T>
112#pragma GCC diagnostic ignored "-Wformat-security"
113 int sz = std::snprintf(m_message,
sizeof(m_message), fmt, args...);
114 if (sz >=
static_cast<int>(
sizeof(m_message)))
116 std::snprintf(m_message + MESSAGE_BUFFER_SIZE -
sizeof(OVERFLOW_MESSAGE),
117 sizeof(OVERFLOW_MESSAGE),
119 m_message_size = MESSAGE_BUFFER_SIZE;
123 m_message_size =
static_cast<std::size_t
>(sz);
125#pragma GCC diagnostic pop
129 template <
typename...
T>
133#pragma GCC diagnostic ignored "-Wformat-security"
134 int sz = std::snprintf(m_identifier,
sizeof(m_identifier), fmt, args...);
135 if (sz >=
static_cast<int>(
sizeof(m_identifier)))
137 std::snprintf(m_identifier + IDENTIFIER_BUFFER_SIZE -
sizeof(OVERFLOW_MESSAGE),
138 sizeof(OVERFLOW_MESSAGE),
140 m_identifier_size = MESSAGE_BUFFER_SIZE;
144 m_identifier_size =
static_cast<std::size_t
>(sz);
146#pragma GCC diagnostic pop
152 Entry&
metaInfo(
const char* file,
int line,
const char* function);
174 ReportWrapper(
Entry& error, Reporter* reporter);
176 ReportWrapper(
const ReportWrapper&) =
delete;
177 ReportWrapper& operator=(
const ReportWrapper&) =
delete;
181 template <
typename...
T>
183 identifier(
const char* fmt,
T... args)
191 Reporter* m_reporter;
204 Reporter(Reporting* errorReporting);
205 Reporting* m_errorReporting;
206 unsigned int m_errorCount = 0;
227 std::optional<std::filesystem::path>
dumpToFile(std::filesystem::path file,
228 std::uint64_t lastNSeconds = 1000000);
231 Reporting(std::size_t maxErrorHistorySize = 1000);
232 ~Reporting()
override;
234 std::vector<Entry> m_errors;
239 struct ErrorTimestamp
247 return std::tie(this->timestamp, this->subid) < std::tie(
x.timestamp,
x.subid);
251 std::map<ErrorTimestamp, Entry> m_errorHistory;
252 std::size_t m_maxErrorHistorySize;
254 std::thread m_errorProcessingThread;
255 std::atomic_bool m_errorProcessingRunning{
true};
256 void errorProcessingLoop();
257 std::condition_variable m_errorProcessingCondition;
258 std::mutex m_errorProcessingConditionMutex;
260 IceUtil::Time m_timestampReportingStart;
273#define _detail_GENERAL_REPORT_CONSTRUCTION(...) \
274 armarx::control::ethercat::ReportingEntry() \
275 .errorType(armarx::control::ethercat::ReportingType::General) \
276 .metaInfo(__FILE__, __LINE__, ARMARX_FUNCTION) \
277 .message(__VA_ARGS__)
279#define GENERAL_DEBUG(...) \
280 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportDebug( \
281 _detail_GENERAL_REPORT_CONSTRUCTION(__VA_ARGS__))
282#define GENERAL_INFO(...) \
283 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportInfo( \
284 _detail_GENERAL_REPORT_CONSTRUCTION(__VA_ARGS__))
285#define GENERAL_WARNING(...) \
286 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportWarning( \
287 _detail_GENERAL_REPORT_CONSTRUCTION(__VA_ARGS__))
288#define GENERAL_ERROR(...) \
289 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportError( \
290 _detail_GENERAL_REPORT_CONSTRUCTION(__VA_ARGS__))
294#define _detail_BUS_REPORT_CONSTRUCTION(bin, ...) \
295 armarx::control::ethercat::ReportingEntry() \
296 .errorType(armarx::control::ethercat::ReportingType::Bus) \
297 .metaInfo(__FILE__, __LINE__, ARMARX_FUNCTION) \
298 .message(__VA_ARGS__) \
299 .busIterationNumber(bin)
301#define BUS_DEBUG(bin, ...) \
302 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportDebug( \
303 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
304#define BUS_INFO(bin, ...) \
305 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportInfo( \
306 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
307#define BUS_WARNING(bin, ...) \
308 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportWarning( \
309 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
310#define BUS_ERROR(bin, ...) \
311 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportError( \
312 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
313#define BUS_FATAL_AND_THROW(bin, ...) \
314 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportErrorAndThrow( \
315 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
317#define BUS_WARNING_LOCAL(reporter, bin, ...) \
318 (reporter).reportWarning(_detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
319#define BUS_ERROR_LOCAL(reporter, bin, ...) \
320 (reporter).reportError(_detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
323#define _detail_SLAVE_REPORT_CONSTRUCTION(_sid, ...) \
324 armarx::control::ethercat::ReportingEntry() \
325 .errorType(armarx::control::ethercat::ReportingType::Slave) \
326 .metaInfo(__FILE__, __LINE__, ARMARX_FUNCTION) \
327 .message(__VA_ARGS__) \
328 .slaveIdentifier(_sid)
330#define SLAVE_DEBUG(sid, ...) \
331 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportDebug( \
332 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
333#define SLAVE_INFO(sid, ...) \
334 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportInfo( \
335 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
336#define SLAVE_WARNING(sid, ...) \
337 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportWarning( \
338 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
339#define SLAVE_ERROR(sid, ...) \
340 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportError( \
341 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
342#define SLAVE_FATAL_AND_THROW(sid, ...) \
343 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportErrorAndThrow( \
344 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
346#define SLAVE_WARNING_LOCAL(reporter, sid, ...) \
347 (reporter).reportWarning(_detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
348#define SLAVE_ERROR_LOCAL(reporter, sid, ...) \
349 (reporter).reportError(_detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
352#define _detail_DEVICE_REPORT_CONSTRUCTION(devName, ...) \
353 armarx::control::ethercat::ReportingEntry() \
354 .errorType(armarx::control::ethercat::ReportingType::Device) \
355 .metaInfo(__FILE__, __LINE__, ARMARX_FUNCTION) \
356 .message(__VA_ARGS__) \
359#define DEVICE_INFO(deviceName, ...) \
360 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportInfo( \
361 _detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
362#define DEVICE_WARNING(deviceName, ...) \
363 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportWarning( \
364 _detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
365#define DEVICE_ERROR(deviceName, ...) \
366 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportError( \
367 _detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
368#define DEVICE_FATAL_AND_THROW(deviceName, ...) \
369 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportErrorAndThrow( \
370 _detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
372#define DEVICE_WARNING_LOCAL(reporter, deviceName, ...) \
373 (reporter).reportWarning(_detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
374#define DEVICE_ERROR_LOCAL(reporter, deviceName, ...) \
375 (reporter).reportError(_detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Wrapper for a pointer to propagate const to the pointed to value.
The SlaveIdentifier class is a POD-type representing a unique set of values identifying an EtherCAT s...
Brief description of class Entry.
Entry & slaveIdentifier(SlaveIdentifier sid)
std::string toString() const
Entry & message(const char *fmt, T... args)
Entry & busIterationNumber(std::uint64_t iteration)
Entry & deviceName(const char *deviceName)
Entry & metaInfo(const char *file, int line, const char *function)
Entry & errorType(Type type)
Entry & identifier(const char *fmt, T... args)
std::string getIdentifier() const
Brief description of class Reporter.
ReportWrapper reportInfo(Entry &error)
void reportErrorAndThrow(Entry &error)
ReportWrapper reportDebug(Entry &error)
ReportWrapper reportWarning(Entry &error)
ReportWrapper reportError(Entry &error)
Brief description of class Reporting.
std::optional< std::filesystem::path > dumpToFile(std::filesystem::path file, std::uint64_t lastNSeconds=1000000)
static Reporting & getErrorReporting()
void report(Entry &&error)
static Reporter & getGlobalErrorReporter()
Reporter getErrorReporter()
void setMaxErrorHistorySize(std::size_t maxErrorHistorySize)
Severity
The Severity enum.
std::ostream & operator<<(std::ostream &stream, const Type &rhs)
reporting::Reporting Reporting
reporting::Entry ReportingEntry
reporting::Type ReportingType
This file offers overloads of toIce() and fromIce() functions for STL container types.
bool operator<(const RemoteHandle< PrxTA > &fst, const RemoteHandle< PrxTB > &snd)