From 4c40f9ab1838d7b0b7cc08879915f7a3a9992e38 Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Tue, 17 Nov 2015 19:23:29 +0000 Subject: [PATCH] Improve logging facilities. Allow variadic 'log' calls, and automatically convert std::string and int arguments to char * in an exception-free manner. --- dinit-log.cc | 32 ++++++++++++++++++++++ dinit-log.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 4 deletions(-) diff --git a/dinit-log.cc b/dinit-log.cc index fe5bc30..8e031e7 100644 --- a/dinit-log.cc +++ b/dinit-log.cc @@ -3,6 +3,7 @@ LogLevel log_level = LogLevel::WARN; bool log_to_console = true; // whether we should output log messages to console +bool log_current_line; // Log a message void log(LogLevel lvl, const char *msg) noexcept @@ -14,6 +15,37 @@ void log(LogLevel lvl, const char *msg) noexcept } } +// Log a multi-part message beginning +void logMsgBegin(LogLevel lvl, const char *msg) noexcept +{ + log_current_line = lvl >= log_level; + if (log_current_line) { + if (log_to_console) { + std::cout << "dinit: " << msg; + } + } +} + +// Continue a multi-part log message +void logMsgPart(const char *msg) noexcept +{ + if (log_current_line) { + if (log_to_console) { + std::cout << msg; + } + } +} + +// Complete a multi-part log message +void logMsgEnd(const char *msg) noexcept +{ + if (log_current_line) { + if (log_to_console) { + std::cout << msg << std::endl; + } + } +} + void logServiceStarted(const char *service_name) noexcept { if (log_to_console) { diff --git a/dinit-log.h b/dinit-log.h index e771825..b54664e 100644 --- a/dinit-log.h +++ b/dinit-log.h @@ -4,6 +4,8 @@ // Logging for Dinit #include +#include +#include enum class LogLevel { DEBUG, @@ -17,28 +19,94 @@ extern LogLevel log_level; extern bool log_to_console; void log(LogLevel lvl, const char *msg) noexcept; +void logMsgBegin(LogLevel lvl, const char *msg) noexcept; +void logMsgPart(const char *msg) noexcept; +void logMsgEnd(const char *msg) noexcept; void logServiceStarted(const char *service_name) noexcept; void logServiceFailed(const char *service_name) noexcept; void logServiceStopped(const char *service_name) noexcept; -static inline void log(LogLevel lvl, const std::string &str) +// Convenience methods which perform type conversion of the argument. +// There is some duplication here that could possibly be avoided, but +// it doesn't seem like a big deal. +static inline void log(LogLevel lvl, const std::string &str) noexcept { log(lvl, str.c_str()); } -static inline void logServiceStarted(const std::string &str) +static inline void logMsgBegin(LogLevel lvl, const std::string &str) noexcept +{ + logMsgBegin(lvl, str.c_str()); +} + +static inline void logMsgBegin(LogLevel lvl, int a) noexcept +{ + constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2; + char nbuf[bufsz]; + snprintf(nbuf, bufsz, "%d", a); + logMsgBegin(lvl, nbuf); +} + +static inline void logMsgPart(const std::string &str) noexcept +{ + logMsgPart(str.c_str()); +} + +static inline void logMsgPart(int a) noexcept +{ + constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2; + char nbuf[bufsz]; + snprintf(nbuf, bufsz, "%d", a); + logMsgPart(nbuf); +} + +static inline void logMsgEnd(const std::string &str) noexcept +{ + logMsgEnd(str.c_str()); +} + +static inline void logMsgEnd(int a) noexcept +{ + constexpr int bufsz = (CHAR_BIT * sizeof(int) - 1) / 3 + 2; + char nbuf[bufsz]; + snprintf(nbuf, bufsz, "%d", a); + logMsgEnd(nbuf); +} + +static inline void logServiceStarted(const std::string &str) noexcept { logServiceStarted(str.c_str()); } -static inline void logServiceFailed(const std::string &str) +static inline void logServiceFailed(const std::string &str) noexcept { logServiceFailed(str.c_str()); } -static inline void logServiceStopped(const std::string &str) +static inline void logServiceStopped(const std::string &str) noexcept { logServiceStopped(str.c_str()); } +// It's not intended that methods in this namespace be called directly: +namespace dinit_log { + template static inline void logParts(A a) noexcept + { + logMsgEnd(a); + } + + template static inline void logParts(A a, B... b) noexcept + { + logMsgPart(a); + logParts(b...); + } +} + +// Variadic 'log' method. +template static inline void log(LogLevel lvl, A a, B ...b) noexcept +{ + logMsgBegin(lvl, a); + dinit_log::logParts(b...); +} + #endif -- 2.25.1