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 requiredmaster
parent
6f2d9de769
commit
2f19abd704
89
src/log.cpp
89
src/log.cpp
|
@ -68,21 +68,6 @@ public:
|
||||||
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);
|
||||||
|
|
63
src/log.h
63
src/log.h
|
@ -57,12 +57,14 @@ public:
|
||||||
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 @@ private:
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue