summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Streetman <ddstreet@canonical.com>2021-05-19 16:22:21 +0200
committerDan Streetman <ddstreet@canonical.com>2021-05-20 21:39:15 +0200
commit264f0afe0d200fcc64647eed417f0f2b293224a7 (patch)
treee8d3980cd687b71759fb3a843b57cb0a09d94fc3
parentmacro: add ONCE macro that evaluates to 1 one time (diff)
downloadsystemd-264f0afe0d200fcc64647eed417f0f2b293224a7.tar.xz
systemd-264f0afe0d200fcc64647eed417f0f2b293224a7.zip
log: add log_once() and log_once_errno() macros
These macros will log a message at the specified level only the first time they are called. On all later calls, if the specified level is debug, the logs will be suppressed; otherwise the message will be logged at debug.
-rw-r--r--src/basic/log.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/basic/log.h b/src/basic/log.h
index 51ba3d8fde..738c181070 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -236,6 +236,29 @@ int log_emergency_level(void);
#define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__)
#define log_emergency_errno(error, ...) log_full_errno(log_emergency_level(), error, __VA_ARGS__)
+/* This logs at the specified level the first time it is called, and then
+ * logs at debug. If the specified level is debug, this logs only the first
+ * time it is called. */
+#define log_once(level, ...) \
+ ({ \
+ if (ONCE) \
+ log_full(level, __VA_ARGS__); \
+ else if (LOG_PRI(level) != LOG_DEBUG) \
+ log_debug(__VA_ARGS__); \
+ })
+
+#define log_once_errno(level, error, ...) \
+ ({ \
+ int _err = (error); \
+ if (ONCE) \
+ _err = log_full_errno(level, _err, __VA_ARGS__); \
+ else if (LOG_PRI(level) != LOG_DEBUG) \
+ _err = log_debug_errno(_err, __VA_ARGS__); \
+ else \
+ _err = -ERRNO_VALUE(_err); \
+ _err; \
+ })
+
#if LOG_TRACE
# define log_trace(...) log_debug(__VA_ARGS__)
#else