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
char OVERFLOW_MESSAGE[] = {
"[ERROR MESSAGE TOO LONG]"};
74 static_assert(MESSAGE_BUFFER_SIZE >
sizeof(OVERFLOW_MESSAGE) + 1);
76 static constexpr std::uint16_t FILE_STRING_BUFFER_SIZE = 256;
77 static constexpr std::uint16_t FUNCTION_STRING_BUFFER_SIZE = 256;
82 char m_message[MESSAGE_BUFFER_SIZE];
83 std::size_t m_message_size = 0;
86 char m_device_name[DEVICE_NAME_BUFFER_SIZE];
89 std::uint64_t m_bus_iteration_number = 0;
90 float m_deactivate_spam_seconds = 0;
94 char file[FILE_STRING_BUFFER_SIZE];
96 char function[FUNCTION_STRING_BUFFER_SIZE];
105 template <
typename...
T>
109 #pragma GCC diagnostic ignored "-Wformat-security"
110 int sz = std::snprintf(m_message,
sizeof(m_message), fmt, args...);
111 if (sz >=
static_cast<int>(
sizeof(m_message)))
113 std::snprintf(m_message + MESSAGE_BUFFER_SIZE -
sizeof(OVERFLOW_MESSAGE),
114 sizeof(OVERFLOW_MESSAGE),
116 m_message_size = MESSAGE_BUFFER_SIZE;
120 m_message_size =
static_cast<std::size_t
>(sz);
122 #pragma GCC diagnostic pop
128 Entry&
metaInfo(
const char* file,
int line,
const char*
function);
151 ReportWrapper(
const ReportWrapper&) =
delete;
152 ReportWrapper& operator=(
const ReportWrapper&) =
delete;
173 unsigned int m_errorCount = 0;
194 std::optional<std::filesystem::path>
dumpToFile(std::filesystem::path file,
195 std::uint64_t lastNSeconds = 1000000);
198 Reporting(std::size_t maxErrorHistorySize = 1000);
201 std::vector<Entry> m_errors;
206 struct ErrorTimestamp
208 std::int64_t timestamp;
214 return std::tie(this->timestamp, this->subid) < std::tie(x.timestamp, x.subid);
218 std::map<ErrorTimestamp, Entry> m_errorHistory;
219 std::size_t m_maxErrorHistorySize;
221 std::thread m_errorProcessingThread;
222 std::atomic_bool m_errorProcessingRunning{
true};
223 void errorProcessingLoop();
224 std::condition_variable m_errorProcessingCondition;
225 std::mutex m_errorProcessingConditionMutex;
240 #define _detail_GENERAL_REPORT_CONSTRUCTION(...) \
241 armarx::control::ethercat::ReportingEntry() \
242 .errorType(armarx::control::ethercat::ReportingType::General) \
243 .metaInfo(__FILE__, __LINE__, ARMARX_FUNCTION) \
244 .message(__VA_ARGS__)
246 #define GENERAL_DEBUG(...) \
247 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportDebug( \
248 _detail_GENERAL_REPORT_CONSTRUCTION(__VA_ARGS__))
249 #define GENERAL_INFO(...) \
250 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportInfo( \
251 _detail_GENERAL_REPORT_CONSTRUCTION(__VA_ARGS__))
252 #define GENERAL_WARNING(...) \
253 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportWarning( \
254 _detail_GENERAL_REPORT_CONSTRUCTION(__VA_ARGS__))
255 #define GENERAL_ERROR(...) \
256 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportError( \
257 _detail_GENERAL_REPORT_CONSTRUCTION(__VA_ARGS__))
261 #define _detail_BUS_REPORT_CONSTRUCTION(bin, ...) \
262 armarx::control::ethercat::ReportingEntry() \
263 .errorType(armarx::control::ethercat::ReportingType::Bus) \
264 .metaInfo(__FILE__, __LINE__, ARMARX_FUNCTION) \
265 .message(__VA_ARGS__) \
266 .busIterationNumber(bin)
268 #define BUS_DEBUG(bin, ...) \
269 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportDebug( \
270 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
271 #define BUS_INFO(bin, ...) \
272 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportInfo( \
273 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
274 #define BUS_WARNING(bin, ...) \
275 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportWarning( \
276 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
277 #define BUS_ERROR(bin, ...) \
278 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportError( \
279 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
280 #define BUS_FATAL_AND_THROW(bin, ...) \
281 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportErrorAndThrow( \
282 _detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
284 #define BUS_WARNING_LOCAL(reporter, bin, ...) \
285 (reporter).reportWarning(_detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
286 #define BUS_ERROR_LOCAL(reporter, bin, ...) \
287 (reporter).reportError(_detail_BUS_REPORT_CONSTRUCTION(bin, __VA_ARGS__))
290 #define _detail_SLAVE_REPORT_CONSTRUCTION(_sid, ...) \
291 armarx::control::ethercat::ReportingEntry() \
292 .errorType(armarx::control::ethercat::ReportingType::Slave) \
293 .metaInfo(__FILE__, __LINE__, ARMARX_FUNCTION) \
294 .message(__VA_ARGS__) \
295 .slaveIdentifier(_sid)
297 #define SLAVE_DEBUG(sid, ...) \
298 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportDebug( \
299 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
300 #define SLAVE_INFO(sid, ...) \
301 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportInfo( \
302 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
303 #define SLAVE_WARNING(sid, ...) \
304 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportWarning( \
305 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
306 #define SLAVE_ERROR(sid, ...) \
307 armarx::control::ethercat::reporting::Reporting::getGlobalErrorReporter().reportError( \
308 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
309 #define SLAVE_FATAL_AND_THROW(sid, ...) \
310 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportErrorAndThrow( \
311 _detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
313 #define SLAVE_WARNING_LOCAL(reporter, sid, ...) \
314 (reporter).reportWarning(_detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
315 #define SLAVE_ERROR_LOCAL(reporter, sid, ...) \
316 (reporter).reportError(_detail_SLAVE_REPORT_CONSTRUCTION(sid, __VA_ARGS__))
319 #define _detail_DEVICE_REPORT_CONSTRUCTION(devName, ...) \
320 armarx::control::ethercat::ReportingEntry() \
321 .errorType(armarx::control::ethercat::ReportingType::Device) \
322 .metaInfo(__FILE__, __LINE__, ARMARX_FUNCTION) \
323 .message(__VA_ARGS__) \
326 #define DEVICE_WARNING(deviceName, ...) \
327 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportWarning( \
328 _detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
329 #define DEVICE_ERROR(deviceName, ...) \
330 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportError( \
331 _detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
332 #define DEVICE_FATAL_AND_THROW(deviceName, ...) \
333 armarx::control::ethercat::Reporting::getGlobalErrorReporter().reportErrorAndThrow( \
334 _detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
336 #define DEVICE_WARNING_LOCAL(reporter, deviceName, ...) \
337 (reporter).reportWarning(_detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))
338 #define DEVICE_ERROR_LOCAL(reporter, deviceName, ...) \
339 (reporter).reportError(_detail_DEVICE_REPORT_CONSTRUCTION(deviceName, __VA_ARGS__))