From 185c0ce97c2b80f913c28f14f439a7dfd8e9e0f8 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 20 Dec 2018 02:34:45 +0000 Subject: [PATCH] Guard log_printf in LOG macros with a log level check So that the format arguments will only be evaluated if the log is enabled by the log level. Allow us to add more expensive logs without impact performance when they are not enabled. Signed-off-by: Yuxuan Shui --- src/log.c | 4 ++++ src/log.h | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/log.c b/src/log.c index 4e13d9d..3368e05 100644 --- a/src/log.c +++ b/src/log.c @@ -98,6 +98,10 @@ void log_set_level(struct log *l, int level) { l->log_level = level; } +enum log_level log_get_level(const struct log *l) { + return l->log_level; +} + attr_printf(4, 5) void log_printf(struct log *l, int level, const char *func, const char *fmt, ...) { assert(level <= LOG_LEVEL_FATAL && level >= 0); diff --git a/src/log.h b/src/log.h index ef90a9b..660db87 100644 --- a/src/log.h +++ b/src/log.h @@ -18,7 +18,12 @@ enum log_level { }; #define LOG(level, x, ...) \ - log_printf(tls_logger, LOG_LEVEL_##level, __func__, x, ##__VA_ARGS__) + do { \ + if (LOG_LEVEL_##level >= log_get_level_tls()) { \ + log_printf(tls_logger, LOG_LEVEL_##level, __func__, x, \ + ##__VA_ARGS__); \ + } \ + } while (0) #define log_trace(x, ...) LOG(TRACE, x, ##__VA_ARGS__) #define log_debug(x, ...) LOG(DEBUG, x, ##__VA_ARGS__) #define log_info(x, ...) LOG(INFO, x, ##__VA_ARGS__) @@ -55,6 +60,7 @@ attr_printf(4, 5) void log_printf(struct log *, int level, const char *func, attr_malloc struct log *log_new(void); attr_nonnull_all void log_destroy(struct log *); attr_nonnull(1) void log_set_level(struct log *l, int level); +attr_pure enum log_level log_get_level(const struct log *l); attr_nonnull_all void log_add_target(struct log *, struct log_target *); attr_const enum log_level string_to_log_level(const char *); @@ -74,6 +80,11 @@ static inline attr_nonnull_all void log_add_target_tls(struct log_target *tgt) { log_add_target(tls_logger, tgt); } +static inline attr_pure enum log_level log_get_level_tls(void) { + assert(tls_logger); + return log_get_level(tls_logger); +} + static inline void log_deinit_tls(void) { assert(tls_logger); log_destroy(tls_logger);