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
This commit is contained in:
est31 2015-10-24 12:52:14 +02:00
parent 6f2d9de769
commit 2f19abd704
2 changed files with 92 additions and 60 deletions

View File

@ -68,21 +68,6 @@ class RawLogBuffer : public StringBuffer {
void flush(const std::string &buffer); 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 //// Globals
//// ////
@ -124,6 +109,41 @@ std::ostream actionstream(&action_buf);
std::ostream infostream(&info_buf); std::ostream infostream(&info_buf);
std::ostream verbosestream(&verbose_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 thread_name = getThreadName();
const std::string label = getLevelLabel(lev); const std::string label = getLevelLabel(lev);
const std::string timestamp = getTimestamp();
std::ostringstream os(std::ios_base::binary); 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(), timestamp, thread_name, text);
logToOutputs(lev, os.str());
} }
void Logger::logRaw(LogLevel lev, const std::string &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]) if (m_silenced_levels[lev])
return; return;
logToSystem(lev, text); logToOutputsRaw(lev, text);
logToOutputs(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
}
void Logger::logToOutputs(LogLevel lev, const std::string &text)
{ {
MutexAutoLock lock(m_mutex); MutexAutoLock lock(m_mutex);
for (size_t i = 0; i != m_outputs[lev].size(); i++) 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) void FileLogOutput::open(const std::string &filename)
{ {
stream.open(filename.c_str(), std::ios::app | std::ios::ate); m_stream.open(filename.c_str(), std::ios::app | std::ios::ate);
if (!stream.good()) if (!m_stream.good())
throw FileNotGoodException("Failed to open log file " + throw FileNotGoodException("Failed to open log file " +
filename + ": " + strerror(errno)); filename + ": " + strerror(errno));
stream << "\n\n" m_stream << "\n\n"
"-------------" << std::endl "-------------" << std::endl
<< " Separator" << std::endl << " Separator" << std::endl
<< "-------------\n" << std::endl; << "-------------\n" << std::endl;
@ -313,8 +332,6 @@ void StringBuffer::push_back(char c)
} }
void LogBuffer::flush(const std::string &buffer) void LogBuffer::flush(const std::string &buffer)
{ {
logger.log(level, buffer); logger.log(level, buffer);

View File

@ -57,12 +57,14 @@ class Logger {
bool getTraceEnabled() { return m_trace_enabled; } bool getTraceEnabled() { return m_trace_enabled; }
static LogLevel stringToLevel(const std::string &name); static LogLevel stringToLevel(const std::string &name);
static const std::string getLevelLabel(LogLevel lev);
private: private:
void logToSystem(LogLevel, const std::string &text); void logToOutputsRaw(LogLevel, const std::string &line);
void logToOutputs(LogLevel, const std::string &text); 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(); const std::string getThreadName();
std::vector<ILogOutput *> m_outputs[LL_MAX]; std::vector<ILogOutput *> m_outputs[LL_MAX];
@ -78,73 +80,86 @@ class Logger {
class ILogOutput { class ILogOutput {
public: 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: public:
StreamLogOutput(std::ostream &stream) : 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: private:
std::ostream &stream; std::ostream &m_stream;
}; };
class FileLogOutput : public ILogOutput { class FileLogOutput : public ICombinedLogOutput {
public: public:
void open(const std::string &filename); 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: private:
std::ofstream stream; std::ofstream m_stream;
}; };
class LogOutputBuffer : public ILogOutput { class LogOutputBuffer : public ICombinedLogOutput {
public: public:
LogOutputBuffer(Logger &logger, LogLevel lev) : LogOutputBuffer(Logger &logger, LogLevel lev) :
logger(logger) m_logger(logger)
{ {
logger.addOutput(this, lev); m_logger.addOutput(this, lev);
} }
~LogOutputBuffer() ~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() bool empty()
{ {
return buffer.empty(); return m_buffer.empty();
} }
std::string get() std::string get()
{ {
if (empty()) if (empty())
return ""; return "";
std::string s = buffer.front(); std::string s = m_buffer.front();
buffer.pop(); m_buffer.pop();
return s; return s;
} }
private: private:
std::queue<std::string> buffer; std::queue<std::string> m_buffer;
Logger &logger; Logger &m_logger;
}; };