hyperion.ng/libsrc/utils/Logger.cpp

184 lines
4.4 KiB
C++

#include <utils/Logger.h>
#include <utils/FileUtils.h>
#include <iostream>
#include <algorithm>
#include <syslog.h>
#include <QFileInfo>
#include <time.h>
static const char * LogLevelStrings[] = { "", "DEBUG", "INFO", "WARNING", "ERROR" };
static const int LogLevelSysLog[] = { LOG_DEBUG, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR };
static unsigned int loggerCount = 0;
static unsigned int loggerId = 0;
std::map<QString,Logger*> *Logger::LoggerMap = nullptr;
Logger::LogLevel Logger::GLOBAL_MIN_LOG_LEVEL = Logger::UNSET;
LoggerManager* LoggerManager::_instance = nullptr;
Logger* Logger::getInstance(QString name, Logger::LogLevel minLevel)
{
qRegisterMetaType<Logger::T_LOG_MESSAGE>();
Logger* log = nullptr;
if (LoggerMap == nullptr)
{
LoggerMap = new std::map<QString,Logger*>;
}
if ( LoggerMap->find(name) == LoggerMap->end() )
{
log = new Logger(name,minLevel);
LoggerMap->insert(std::pair<QString,Logger*>(name,log)); // compat version, replace it with following line if we have 100% c++11
//LoggerMap->emplace(name,log); // not compat with older linux distro's e.g. wheezy
connect(log, SIGNAL(newLogMessage(Logger::T_LOG_MESSAGE)), LoggerManager::getInstance(), SLOT(handleNewLogMessage(Logger::T_LOG_MESSAGE)));
}
else
{
log = LoggerMap->at(name);
}
return log;
}
void Logger::deleteInstance(QString name)
{
if (LoggerMap == nullptr)
return;
if ( name.isEmpty() )
{
std::map<QString,Logger*>::iterator it;
for ( it=LoggerMap->begin(); it != LoggerMap->end(); it++)
{
delete it->second;
}
LoggerMap->clear();
}
else if (LoggerMap->find(name) != LoggerMap->end())
{
delete LoggerMap->at(name);
LoggerMap->erase(name);
}
}
void Logger::setLogLevel(LogLevel level,QString name)
{
if ( name.isEmpty() )
{
GLOBAL_MIN_LOG_LEVEL = level;
}
else
{
Logger* log = Logger::getInstance(name,level);
log->setMinLevel(level);
}
}
Logger::LogLevel Logger::getLogLevel(QString name)
{
if ( name.isEmpty() )
{
return GLOBAL_MIN_LOG_LEVEL;
}
Logger* log = Logger::getInstance(name);
return log->getMinLevel();
}
Logger::Logger ( QString name, LogLevel minLevel )
: QObject()
, _name(name)
, _minLevel(minLevel)
, _syslogEnabled(true)
, _loggerId(loggerId++)
{
#ifdef __GLIBC__
const char* _appname_char = program_invocation_short_name;
#else
const char* _appname_char = getprogname();
#endif
_appname = QString(_appname_char).toLower();
loggerCount++;
if (_syslogEnabled && loggerCount == 1 )
{
openlog (_appname_char, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0);
}
}
Logger::~Logger()
{
//Debug(this, "logger '%s' destroyed", QSTRING_CSTR(_name) );
loggerCount--;
if ( loggerCount == 0 )
closelog();
}
void Logger::Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...)
{
if ( (GLOBAL_MIN_LOG_LEVEL == Logger::UNSET && level < _minLevel) // no global level, use level from logger
|| (GLOBAL_MIN_LOG_LEVEL > Logger::UNSET && level < GLOBAL_MIN_LOG_LEVEL) ) // global level set, use global level
return;
const size_t max_msg_length = 1024;
char msg[max_msg_length];
va_list args;
va_start (args, fmt);
vsnprintf (msg, max_msg_length, fmt, args);
va_end (args);
Logger::T_LOG_MESSAGE logMsg;
logMsg.appName = _appname;
logMsg.loggerName = _name;
logMsg.function = QString(func);
logMsg.line = line;
logMsg.fileName = FileUtils::getBaseName(sourceFile);
time(&(logMsg.utime));
logMsg.message = QString(msg);
logMsg.level = level;
logMsg.levelString = LogLevelStrings[level];
emit newLogMessage(logMsg);
QString location;
if ( level == Logger::DEBUG )
{
location = "<" + logMsg.fileName + ":" + QString::number(line)+":"+ logMsg.function + "()> ";
}
std::cout << QString("[" + _appname + " " + _name + "] <" + LogLevelStrings[level] + "> " + location + msg).toStdString() << std::endl;
if ( _syslogEnabled && level >= Logger::WARNING )
syslog (LogLevelSysLog[level], "%s", msg);
}
LoggerManager::LoggerManager()
: QObject()
, _loggerMaxMsgBufferSize(200)
{
}
void LoggerManager::handleNewLogMessage(const Logger::T_LOG_MESSAGE &msg)
{
_logMessageBuffer.append(msg);
if (_logMessageBuffer.length() > _loggerMaxMsgBufferSize)
{
_logMessageBuffer.erase(_logMessageBuffer.begin());
}
emit newLogMessage(msg);
}
LoggerManager* LoggerManager::getInstance()
{
if ( _instance == nullptr )
_instance = new LoggerManager();
return _instance;
}