From 2f19abd70486e19e992f8a426ce718cbcadce210 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 24 Oct 2015 12:52:14 +0200 Subject: [PATCH] Small logging refactor and additional options -> Get rid of Logger::logToSystem and use normal downstream output system for android instead -> Give the downstream output system more information: enrich the log function of ILogOutput with information and add ICombinedLogOutput for easier use. -> Make Logger::getLevelLabel() static and public so that it can be used by downstream log output. -> Add g_ and m_ prefixes where required --- src/log.cpp | 89 +++++++++++++++++++++++++++++++---------------------- src/log.h | 63 ++++++++++++++++++++++--------------- 2 files changed, 92 insertions(+), 60 deletions(-) diff --git a/src/log.cpp b/src/log.cpp index e15bed52a..7cae8b670 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -68,21 +68,6 @@ public: void flush(const std::string &buffer); }; - -#ifdef __ANDROID__ -static unsigned int level_to_android[] = { - ANDROID_LOG_INFO, // LL_NONE - //ANDROID_LOG_FATAL, - ANDROID_LOG_ERROR, // LL_ERROR - ANDROID_LOG_WARN, // LL_WARNING - ANDROID_LOG_WARN, // LL_ACTION - //ANDROID_LOG_INFO, - ANDROID_LOG_DEBUG, // LL_INFO - ANDROID_LOG_VERBOSE, // LL_VERBOSE - -}; -#endif - //// //// Globals //// @@ -124,6 +109,41 @@ std::ostream actionstream(&action_buf); std::ostream infostream(&info_buf); std::ostream verbosestream(&verbose_buf); +// Android +#ifdef __ANDROID__ + +static unsigned int g_level_to_android[] = { + ANDROID_LOG_INFO, // LL_NONE + //ANDROID_LOG_FATAL, + ANDROID_LOG_ERROR, // LL_ERROR + ANDROID_LOG_WARN, // LL_WARNING + ANDROID_LOG_WARN, // LL_ACTION + //ANDROID_LOG_INFO, + ANDROID_LOG_DEBUG, // LL_INFO + ANDROID_LOG_VERBOSE, // LL_VERBOSE +}; + +class AndroidSystemLogOutput : public ICombinedLogOutput { + public: + AndroidSystemLogOutput() + { + g_logger.addOutput(this); + } + ~AndroidSystemLogOutput() + { + g_logger.removeOutput(this); + } + void logRaw(LogLevel lev, const std::string &line) + { + assert(ARRLEN(g_level_to_android) == LL_MAX); + __android_log_print(g_level_to_android[lev], + PROJECT_NAME_C, "%s", line.c_str()); + } +}; + +AndroidSystemLogOutput g_android_log_output; + +#endif /////////////////////////////////////////////////////////////////////////////// @@ -232,11 +252,11 @@ void Logger::log(LogLevel lev, const std::string &text) const std::string thread_name = getThreadName(); const std::string label = getLevelLabel(lev); + const std::string timestamp = getTimestamp(); std::ostringstream os(std::ios_base::binary); - os << getTimestamp() << ": " << label << "[" << thread_name << "]: " << text; + os << timestamp << ": " << label << "[" << thread_name << "]: " << text; - logToSystem(lev, text); - logToOutputs(lev, os.str()); + logToOutputs(lev, os.str(), timestamp, thread_name, text); } void Logger::logRaw(LogLevel lev, const std::string &text) @@ -244,24 +264,23 @@ void Logger::logRaw(LogLevel lev, const std::string &text) if (m_silenced_levels[lev]) return; - logToSystem(lev, text); - logToOutputs(lev, text); + logToOutputsRaw(lev, text); } -void Logger::logToSystem(LogLevel lev, const std::string &text) -{ -#ifdef __ANDROID__ - assert(ARRLEN(level_to_android) == LL_MAX); - __android_log_print(level_to_android[lev], - PROJECT_NAME_C, "%s", text.c_str()); -#endif -} - -void Logger::logToOutputs(LogLevel lev, const std::string &text) +void Logger::logToOutputsRaw(LogLevel lev, const std::string &line) { MutexAutoLock lock(m_mutex); for (size_t i = 0; i != m_outputs[lev].size(); i++) - m_outputs[lev][i]->log(text); + m_outputs[lev][i]->logRaw(lev, line); +} + +void Logger::logToOutputs(LogLevel lev, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text) +{ + MutexAutoLock lock(m_mutex); + for (size_t i = 0; i != m_outputs[lev].size(); i++) + m_outputs[lev][i]->log(lev, combined, time, thread_name, payload_text); } @@ -271,11 +290,11 @@ void Logger::logToOutputs(LogLevel lev, const std::string &text) void FileLogOutput::open(const std::string &filename) { - stream.open(filename.c_str(), std::ios::app | std::ios::ate); - if (!stream.good()) + m_stream.open(filename.c_str(), std::ios::app | std::ios::ate); + if (!m_stream.good()) throw FileNotGoodException("Failed to open log file " + filename + ": " + strerror(errno)); - stream << "\n\n" + m_stream << "\n\n" "-------------" << std::endl << " Separator" << std::endl << "-------------\n" << std::endl; @@ -313,8 +332,6 @@ void StringBuffer::push_back(char c) } - - void LogBuffer::flush(const std::string &buffer) { logger.log(level, buffer); diff --git a/src/log.h b/src/log.h index 0e63041cc..f877f2f8a 100644 --- a/src/log.h +++ b/src/log.h @@ -57,12 +57,14 @@ public: bool getTraceEnabled() { return m_trace_enabled; } static LogLevel stringToLevel(const std::string &name); + static const std::string getLevelLabel(LogLevel lev); private: - void logToSystem(LogLevel, const std::string &text); - void logToOutputs(LogLevel, const std::string &text); + void logToOutputsRaw(LogLevel, const std::string &line); + void logToOutputs(LogLevel, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text); - const std::string getLevelLabel(LogLevel lev); const std::string getThreadName(); std::vector m_outputs[LL_MAX]; @@ -78,73 +80,86 @@ private: class ILogOutput { public: - virtual void log(const std::string &line) = 0; + virtual void logRaw(LogLevel, const std::string &line) = 0; + virtual void log(LogLevel, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text) = 0; }; -class StreamLogOutput : public ILogOutput { +class ICombinedLogOutput : public ILogOutput { +public: + void log(LogLevel lev, const std::string &combined, + const std::string &time, const std::string &thread_name, + const std::string &payload_text) + { + logRaw(lev, combined); + } +}; + +class StreamLogOutput : public ICombinedLogOutput { public: StreamLogOutput(std::ostream &stream) : - stream(stream) + m_stream(stream) { } - void log(const std::string &line) + void logRaw(LogLevel lev, const std::string &line) { - stream << line << std::endl; + m_stream << line << std::endl; } private: - std::ostream &stream; + std::ostream &m_stream; }; -class FileLogOutput : public ILogOutput { +class FileLogOutput : public ICombinedLogOutput { public: void open(const std::string &filename); - void log(const std::string &line) + void logRaw(LogLevel lev, const std::string &line) { - stream << line << std::endl; + m_stream << line << std::endl; } private: - std::ofstream stream; + std::ofstream m_stream; }; -class LogOutputBuffer : public ILogOutput { +class LogOutputBuffer : public ICombinedLogOutput { public: LogOutputBuffer(Logger &logger, LogLevel lev) : - logger(logger) + m_logger(logger) { - logger.addOutput(this, lev); + m_logger.addOutput(this, lev); } ~LogOutputBuffer() { - logger.removeOutput(this); + m_logger.removeOutput(this); } - virtual void log(const std::string &line) + void logRaw(LogLevel lev, const std::string &line) { - buffer.push(line); + m_buffer.push(line); } bool empty() { - return buffer.empty(); + return m_buffer.empty(); } std::string get() { if (empty()) return ""; - std::string s = buffer.front(); - buffer.pop(); + std::string s = m_buffer.front(); + m_buffer.pop(); return s; } private: - std::queue buffer; - Logger &logger; + std::queue m_buffer; + Logger &m_logger; };