X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flog.cpp;h=589cfd909806ee7ba6be55d720c6f06ba486a6bf;hb=c5968049bbf73ceff08a2b1d35bb34192fa3f315;hp=4f77101f932efde992e09d2c433ef6e8d9a3854f;hpb=2139d7d45fb1a8ed250ad96c9975c581f02f72a9;p=dragonfireclient.git diff --git a/src/log.cpp b/src/log.cpp index 4f77101f9..589cfd909 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -34,9 +34,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +const int BUFFER_LENGTH = 256; + class StringBuffer : public std::streambuf { public: - StringBuffer() {} + StringBuffer() { + buffer_index = 0; + } int overflow(int c); virtual void flush(const std::string &buf) = 0; @@ -44,7 +48,8 @@ class StringBuffer : public std::streambuf { void push_back(char c); private: - std::string buffer; + char buffer[BUFFER_LENGTH]; + int buffer_index; }; @@ -68,21 +73,6 @@ class RawLogBuffer : public StringBuffer { 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 +114,42 @@ 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) + { + STATIC_ASSERT(ARRLEN(g_level_to_android) == LL_MAX, + mismatch_between_android_and_internal_loglevels); + __android_log_print(g_level_to_android[lev], + PROJECT_NAME_C, "%s", line.c_str()); + } +}; + +AndroidSystemLogOutput g_android_log_output; + +#endif /////////////////////////////////////////////////////////////////////////////// @@ -152,7 +178,7 @@ LogLevel Logger::stringToLevel(const std::string &name) void Logger::addOutput(ILogOutput *out) { - addOutputMaxLevel(out, LL_MAX); + addOutputMaxLevel(out, (LogLevel)(LL_MAX - 1)); } void Logger::addOutput(ILogOutput *out, LogLevel lev) @@ -160,21 +186,34 @@ void Logger::addOutput(ILogOutput *out, LogLevel lev) m_outputs[lev].push_back(out); } +void Logger::addOutputMasked(ILogOutput *out, LogLevelMask mask) +{ + for (size_t i = 0; i < LL_MAX; i++) { + if (mask & LOGLEVEL_TO_MASKLEVEL(i)) + m_outputs[i].push_back(out); + } +} + void Logger::addOutputMaxLevel(ILogOutput *out, LogLevel lev) { + assert(lev < LL_MAX); for (size_t i = 0; i <= lev; i++) m_outputs[i].push_back(out); } -void Logger::removeOutput(ILogOutput *out) +LogLevelMask Logger::removeOutput(ILogOutput *out) { + LogLevelMask ret_mask = 0; for (size_t i = 0; i < LL_MAX; i++) { std::vector::iterator it; it = std::find(m_outputs[i].begin(), m_outputs[i].end(), out); - if (it != m_outputs[i].end()) + if (it != m_outputs[i].end()) { + ret_mask |= LOGLEVEL_TO_MASKLEVEL(i); m_outputs[i].erase(it); + } } + return ret_mask; } void Logger::setLevelSilenced(LogLevel lev, bool silenced) @@ -184,14 +223,14 @@ void Logger::setLevelSilenced(LogLevel lev, bool silenced) void Logger::registerThread(const std::string &name) { - threadid_t id = get_current_thread_id(); + threadid_t id = thr_get_current_thread_id(); MutexAutoLock lock(m_mutex); m_thread_names[id] = name; } void Logger::deregisterThread() { - threadid_t id = get_current_thread_id(); + threadid_t id = thr_get_current_thread_id(); MutexAutoLock lock(m_mutex); m_thread_names.erase(id); } @@ -207,7 +246,8 @@ const std::string Logger::getLevelLabel(LogLevel lev) "VERBOSE", }; assert(lev < LL_MAX && lev >= 0); - assert(ARRLEN(names) == LL_MAX); + STATIC_ASSERT(ARRLEN(names) == LL_MAX, + mismatch_between_loglevel_names_and_enum); return names[lev]; } @@ -215,7 +255,7 @@ const std::string Logger::getThreadName() { std::map::const_iterator it; - threadid_t id = get_current_thread_id(); + threadid_t id = thr_get_current_thread_id(); it = m_thread_names.find(id); if (it != m_thread_names.end()) return it->second; @@ -232,11 +272,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 +284,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) +void Logger::logToOutputsRaw(LogLevel lev, const std::string &line) { -#ifdef __ANDROID__ - assert(ARRLEN(level_to_android) == LL_MAX); - __android_log_print(level_to_android[lev], - PROJECT_NAME_C, "%s", text.c_str()); -#endif + MutexAutoLock lock(m_mutex); + for (size_t i = 0; i != m_outputs[lev].size(); i++) + m_outputs[lev][i]->logRaw(lev, line); } -void Logger::logToOutputs(LogLevel lev, const std::string &text) +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(text); + m_outputs[lev][i]->log(lev, combined, time, thread_name, payload_text); } @@ -271,11 +310,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; @@ -304,17 +343,22 @@ std::streamsize StringBuffer::xsputn(const char *s, std::streamsize n) void StringBuffer::push_back(char c) { if (c == '\n' || c == '\r') { - if (!buffer.empty()) - flush(buffer); - buffer.clear(); + if (buffer_index) + flush(std::string(buffer, buffer_index)); + buffer_index = 0; } else { - buffer.push_back(c); + int index = buffer_index; + buffer[index++] = c; + if (index >= BUFFER_LENGTH) { + flush(std::string(buffer, buffer_index)); + buffer_index = 0; + } else { + buffer_index = index; + } } } - - void LogBuffer::flush(const std::string &buffer) { logger.log(level, buffer);