diff --git a/src/debug.cpp b/src/debug.cpp index dc5546065..c1ab8d0d3 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -126,6 +126,13 @@ void log_msg(int level, const char *format, ...) LOG(level) << buffer; } +void log_msg_once(int level, uint32_t id, const char *msg) { + if (log_level < level) { + return; + } + Logger(level).once(id, msg); +} + /** * This function is analogous to perror(). The message is printed using the logger. */ @@ -349,6 +356,7 @@ void debug_file_dump(const char *key, void (*serialize)(void *data, FILE *), voi #endif std::atomic Logger::last_msg{}; +thread_local std::set Logger::oneshot_messages; std::atomic Logger::skip_repeated{true}; int Logger::show_timestamps = -1; diff --git a/src/debug.h b/src/debug.h index ab8a378f7..7a3a91b13 100644 --- a/src/debug.h +++ b/src/debug.h @@ -40,9 +40,12 @@ #ifndef _RAT_DEBUG_H #define _RAT_DEBUG_H -#ifndef __cplusplus +#ifdef __cplusplus +#include +#else #include -#endif // ! defined __cplusplus +#include +#endif // defined __cplusplus #define UNUSED(x) (x=x) @@ -82,6 +85,7 @@ void debug_file_dump(const char *key, void (*serialize)(void *data, FILE *), voi ///#define debug_msg(...) log_msg(LOG_LEVEL_DEBUG, "[pid/%d +%d %s] ", getpid(), __LINE__, __FILE__), log_msg(LOG_LEVEL_DEBUG, __VA_ARGS__) #define debug_msg(...) log_msg(LOG_LEVEL_DEBUG, __VA_ARGS__) void log_msg(int log_level, const char *format, ...) ATTRIBUTE(format (printf, 2, 3)); +void log_msg_once(int log_level, uint32_t id, const char *msg); void log_perror(int log_level, const char *msg); bool set_log_level(const char *optarg, bool *logger_repeat_msgs, int *show_timestamps); @@ -96,6 +100,7 @@ bool set_log_level(const char *optarg, bool *logger_repeat_msgs, int *show_times #include #include #include +#include #include #include #include "compat/platform_time.h" @@ -154,6 +159,13 @@ public: inline std::ostream& Get() { return oss; } + inline void once(uint32_t id, const std::string &msg) { + if (oneshot_messages.count(id) > 0) { + return; + } + oneshot_messages.insert(id); + oss << msg; + } private: int level; std::ostringstream oss; @@ -165,6 +177,7 @@ private: int count{0}; }; static std::atomic last_msg; // leaks last message upon exit + static thread_local std::set oneshot_messages; friend class keyboard_control; }; @@ -172,6 +185,9 @@ private: #define LOG(level) \ if (level <= log_level) Logger(level).Get() +#define LOG_ONCE(level, id, msg) \ +if (level <= log_level) Logger(level).once(id, msg) + #endif #ifdef DEBUG