diff --git a/src/logger.cpp b/src/logger.cpp index 6167a903f251fe34743a6db64f3818399bdeda0d..d33265a612651bf878344a51ae26fa4bb5720074 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -163,48 +163,48 @@ contextHeader(const char* const file, int line) } } -struct BufDeleter +std::string +formatPrintfArgs(const char* format, va_list ap) { - void operator()(char* ptr) - { - if (ptr) { - free(ptr); - } + std::string ret; + /* A good guess of what we might encounter. */ + static constexpr size_t default_buf_size = 80; + + ret.resize(default_buf_size); + + /* Necessary if we don't have enough space in buf. */ + va_list cp; + va_copy(cp, ap); + + int size = vsnprintf(ret.data(), ret.size(), format, ap); + + /* Not enough space? Well try again. */ + if (size >= ret.size()) { + ret.resize(size + 1); + vsnprintf((char*) ret.data(), ret.size(), format, cp); } -}; + + va_end(cp); + return ret; +} struct Logger::Msg { Msg() = delete; - Msg(int level, const char* file, int line, bool linefeed, const char* fmt, va_list ap) + Msg(int level, const char* file, int line, bool linefeed, std::string&& message) : header_(contextHeader(file, line)) , level_(level) , linefeed_(linefeed) - { - /* A good guess of what we might encounter. */ - static constexpr size_t default_buf_size = 80; - - char* buf = (char*) malloc(default_buf_size); - int buf_size = default_buf_size; - va_list cp; - - /* Necessary if we don't have enough space in buf. */ - va_copy(cp, ap); - - int size = vsnprintf(buf, buf_size, fmt, ap); - - /* Not enough space? Well try again. */ - if (size >= buf_size) { - buf_size = size + 1; - buf = (char*) realloc(buf, buf_size); - vsnprintf(buf, buf_size, fmt, cp); - } + , payload_(std::move(message)) + {} - payload_.reset(buf); - - va_end(cp); - } + Msg(int level, const char* file, int line, bool linefeed, const char* fmt, va_list ap) + : header_(contextHeader(file, line)) + , level_(level) + , linefeed_(linefeed) + , payload_(formatPrintfArgs(fmt, ap)) + {} Msg(Msg&& other) { @@ -214,7 +214,7 @@ struct Logger::Msg linefeed_ = other.linefeed_; } - std::unique_ptr<char, BufDeleter> payload_; + std::string payload_; std::string header_; int level_; bool linefeed_; @@ -277,7 +277,7 @@ public: fputs(msg.header_.c_str(), stderr); } - fputs(msg.payload_.get(), stderr); + fputs(msg.payload_.c_str(), stderr); if (msg.linefeed_) { putc(ENDL, stderr); @@ -312,7 +312,7 @@ public: fputs(msg.header_.c_str(), stderr); } - fputs(msg.payload_.get(), stderr); + fputs(msg.payload_.c_str(), stderr); if (msg.linefeed_) { putc(ENDL, stderr); @@ -385,9 +385,9 @@ public: virtual void consume(Logger::Msg& msg) override { #ifdef __ANDROID__ - __android_log_print(msg.level_, APP_NAME, "%s%s", msg.header_.c_str(), msg.payload_.get()); + __android_log_print(msg.level_, APP_NAME, "%s%s", msg.header_.c_str(), msg.payload_.c_str()); #else - ::syslog(msg.level_, "%s", msg.payload_.get()); + ::syslog(msg.level_, "%s", msg.payload_.c_str()); #endif } }; @@ -415,7 +415,7 @@ public: * TODO - Maybe change the MessageSend sigature to avoid copying * of message payload? */ - auto tmp = msg.header_ + std::string(msg.payload_.get()); + auto tmp = msg.header_ + msg.payload_; jami::emitSignal<DRing::ConfigurationSignal::MessageSend>(tmp); } @@ -496,7 +496,7 @@ private: void do_consume(std::ofstream& file, const std::vector<Logger::Msg>& messages) { for (const auto& msg : messages) { - file << msg.header_ << msg.payload_.get(); + file << msg.header_ << msg.payload_; if (msg.linefeed_) file << ENDL; @@ -572,6 +572,17 @@ Logger::vlog(int level, const char* file, int line, bool linefeed, const char* f log_to_if_enabled(FileLog::instance(), msg); // Takes ownership of msg if enabled } +void +Logger::write(int level, const char* file, int line, std::string&& message) { + /* Timestamp is generated here. */ + Msg msg(level, file, line, true, std::move(message)); + + log_to_if_enabled(ConsoleLog::instance(), msg); + log_to_if_enabled(SysLog::instance(), msg); + log_to_if_enabled(MonitorLog::instance(), msg); + log_to_if_enabled(FileLog::instance(), msg); // Takes ownership of msg if enabled +} + void Logger::fini() { diff --git a/src/logger.h b/src/logger.h index ae75fe8e206bd18c146b113e8f6867841d3d817d..690ccf8a07530d1ee329ba06a4e267acd4e8d413 100644 --- a/src/logger.h +++ b/src/logger.h @@ -24,6 +24,9 @@ #include "jami/def.h" //#define __STDC_FORMAT_MACROS 1 +#include <fmt/core.h> +#include <fmt/format.h> + #include <cinttypes> // for PRIx64 #include <cstdarg> @@ -107,6 +110,9 @@ public: return *this; } + DRING_PUBLIC + static void write(int level, const char* file, int line, std::string&& message); + /// /// Printf fashion logging. /// @@ -152,6 +158,25 @@ private: std::ostringstream os_; ///< string stream used with C++ stream style (stream operator<<) }; +namespace log { + +template<typename S, typename... Args> +void dbg(const char* file, int line, S&& format, Args&&... args) { + Logger::write(LOG_DEBUG, file, line, fmt::format(std::forward<S>(format), std::forward<Args>(args)...)); +} + +template<typename S, typename... Args> +void warn(const char* file, int line, S&& format, Args&&... args) { + Logger::write(LOG_WARNING, file, line, fmt::format(std::forward<S>(format), std::forward<Args>(args)...)); +} + +template<typename S, typename... Args> +void error(const char* file, int line, S&& format, Args&&... args) { + Logger::write(LOG_ERR, file, line, fmt::format(std::forward<S>(format), std::forward<Args>(args)...)); +} + +} + // We need to use macros for contextual information #define JAMI_INFO(...) ::jami::Logger::log(LOG_INFO, __FILE__, __LINE__, true, ##__VA_ARGS__) #define JAMI_DBG(...) ::jami::Logger::log(LOG_DEBUG, __FILE__, __LINE__, true, ##__VA_ARGS__) @@ -163,4 +188,8 @@ private: #define JAMI_XWARN(...) ::jami::Logger::log(LOG_WARNING, __FILE__, __LINE__, false, ##__VA_ARGS__) #define JAMI_XERR(...) ::jami::Logger::log(LOG_ERR, __FILE__, __LINE__, false, ##__VA_ARGS__) +#define JAMI_DEBUG(...) if(::jami::Logger::debugEnabled()) { ::jami::log::dbg(__FILE__, __LINE__, ##__VA_ARGS__); } +#define JAMI_WARNING(...) ::jami::log::warn(__FILE__, __LINE__, ##__VA_ARGS__) +#define JAMI_ERROR(...) ::jami::log::error(__FILE__, __LINE__, ##__VA_ARGS__) + } // namespace jami