2016-09-03 15:54:33 +02:00
|
|
|
#include <utils/Logger.h>
|
|
|
|
#include <utils/FileUtils.h>
|
2016-06-05 16:08:55 +02:00
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <syslog.h>
|
|
|
|
#include <QFileInfo>
|
2016-11-26 22:34:46 +01:00
|
|
|
#include <time.h>
|
2016-06-05 16:08:55 +02:00
|
|
|
|
2016-11-26 22:34:46 +01:00
|
|
|
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;
|
|
|
|
static const int loggerMaxMsgBufferSize = 50;
|
2016-06-21 21:41:26 +02:00
|
|
|
|
2016-06-05 16:08:55 +02:00
|
|
|
std::map<std::string,Logger*> *Logger::LoggerMap = nullptr;
|
2016-06-21 21:41:26 +02:00
|
|
|
Logger::LogLevel Logger::GLOBAL_MIN_LOG_LEVEL = Logger::UNSET;
|
2016-11-26 22:46:16 +01:00
|
|
|
LoggerManager* LoggerManager::_instance = nullptr;
|
2016-06-05 16:08:55 +02:00
|
|
|
|
2017-01-10 19:58:41 +01:00
|
|
|
Logger* Logger::getInstance(QString name, Logger::LogLevel minLevel)
|
2016-06-05 16:08:55 +02:00
|
|
|
{
|
2017-01-10 19:58:41 +01:00
|
|
|
std::string loggerName = name.toStdString();
|
2016-11-26 22:34:46 +01:00
|
|
|
Logger* log = nullptr;
|
2016-06-21 21:41:26 +02:00
|
|
|
if (LoggerMap == nullptr)
|
2016-06-05 16:08:55 +02:00
|
|
|
{
|
2016-06-21 21:41:26 +02:00
|
|
|
LoggerMap = new std::map<std::string,Logger*>;
|
2016-06-05 16:08:55 +02:00
|
|
|
}
|
|
|
|
|
2017-01-10 19:58:41 +01:00
|
|
|
if ( LoggerMap->find(loggerName) == LoggerMap->end() )
|
2016-06-05 16:08:55 +02:00
|
|
|
{
|
2017-01-10 19:58:41 +01:00
|
|
|
log = new Logger(loggerName,minLevel);
|
|
|
|
LoggerMap->insert(std::pair<std::string,Logger*>(loggerName,log)); // compat version, replace it with following line if we have 100% c++11
|
|
|
|
//LoggerMap->emplace(loggerName,log); // not compat with older linux distro's e.g. wheezy
|
2016-11-26 22:46:16 +01:00
|
|
|
connect(log, SIGNAL(newLogMessage(Logger::T_LOG_MESSAGE)), LoggerManager::getInstance(), SLOT(handleNewLogMessage(Logger::T_LOG_MESSAGE)));
|
2016-11-26 22:34:46 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-10 19:58:41 +01:00
|
|
|
log = LoggerMap->at(loggerName);
|
2016-11-26 22:34:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return log;
|
2016-06-05 16:08:55 +02:00
|
|
|
}
|
|
|
|
|
2016-06-21 21:41:26 +02:00
|
|
|
void Logger::deleteInstance(std::string name)
|
|
|
|
{
|
|
|
|
if (LoggerMap == nullptr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( name.empty() )
|
|
|
|
{
|
|
|
|
std::map<std::string,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,std::string name)
|
|
|
|
{
|
|
|
|
if ( name.empty() )
|
|
|
|
{
|
|
|
|
GLOBAL_MIN_LOG_LEVEL = level;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-10 19:58:41 +01:00
|
|
|
Logger* log = Logger::getInstance(QString::fromStdString(name),level);
|
2016-06-21 21:41:26 +02:00
|
|
|
log->setMinLevel(level);
|
|
|
|
}
|
|
|
|
}
|
2016-06-05 16:08:55 +02:00
|
|
|
|
2016-06-27 23:56:21 +02:00
|
|
|
Logger::LogLevel Logger::getLogLevel(std::string name)
|
|
|
|
{
|
|
|
|
if ( name.empty() )
|
|
|
|
{
|
|
|
|
return GLOBAL_MIN_LOG_LEVEL;
|
|
|
|
}
|
|
|
|
|
2017-01-10 19:58:41 +01:00
|
|
|
Logger* log = Logger::getInstance(QString::fromStdString(name));
|
2016-06-27 23:56:21 +02:00
|
|
|
return log->getMinLevel();
|
|
|
|
}
|
2016-06-05 16:08:55 +02:00
|
|
|
|
2016-11-26 22:34:46 +01:00
|
|
|
Logger::Logger ( std::string name, LogLevel minLevel )
|
|
|
|
: QObject()
|
|
|
|
, _name(name)
|
|
|
|
, _minLevel(minLevel)
|
|
|
|
, _syslogEnabled(true)
|
|
|
|
, _loggerId(loggerId++)
|
2016-06-05 16:08:55 +02:00
|
|
|
{
|
2016-06-14 20:14:06 +02:00
|
|
|
#ifdef __GLIBC__
|
2016-08-07 18:39:45 +02:00
|
|
|
const char* _appname_char = program_invocation_short_name;
|
2016-06-12 22:27:34 +02:00
|
|
|
#else
|
2016-08-07 18:39:45 +02:00
|
|
|
const char* _appname_char = getprogname();
|
2016-06-12 22:27:34 +02:00
|
|
|
#endif
|
2016-08-07 18:39:45 +02:00
|
|
|
_appname = std::string(_appname_char);
|
2016-06-05 16:08:55 +02:00
|
|
|
std::transform(_appname.begin(), _appname.end(),_appname.begin(), ::toupper);
|
|
|
|
|
|
|
|
loggerCount++;
|
2016-06-21 21:41:26 +02:00
|
|
|
|
2016-06-05 16:08:55 +02:00
|
|
|
if (_syslogEnabled && loggerCount == 1 )
|
|
|
|
{
|
2016-08-07 18:39:45 +02:00
|
|
|
openlog (_appname_char, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0);
|
2016-06-05 16:08:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger::~Logger()
|
|
|
|
{
|
2016-06-21 21:41:26 +02:00
|
|
|
Debug(this, "logger '%s' destroyed", _name.c_str() );
|
2016-06-05 16:08:55 +02:00
|
|
|
loggerCount--;
|
|
|
|
if ( loggerCount == 0 )
|
|
|
|
closelog();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Logger::Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...)
|
|
|
|
{
|
2016-06-21 21:41:26 +02:00
|
|
|
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
|
2016-06-05 16:08:55 +02:00
|
|
|
return;
|
|
|
|
|
2016-07-21 20:12:51 +02:00
|
|
|
const size_t max_msg_length = 1024;
|
|
|
|
char msg[max_msg_length];
|
2016-06-05 16:08:55 +02:00
|
|
|
va_list args;
|
|
|
|
va_start (args, fmt);
|
2016-07-21 20:12:51 +02:00
|
|
|
vsnprintf (msg, max_msg_length, fmt, args);
|
2016-06-05 16:08:55 +02:00
|
|
|
va_end (args);
|
|
|
|
|
2016-11-26 22:34:46 +01:00
|
|
|
Logger::T_LOG_MESSAGE logMsg;
|
|
|
|
|
|
|
|
logMsg.appName = QString::fromStdString(_appname);
|
|
|
|
logMsg.loggerName = QString::fromStdString(_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 = QString::fromStdString(LogLevelStrings[level]);
|
|
|
|
|
|
|
|
emit newLogMessage(logMsg);
|
|
|
|
|
2016-10-13 21:59:10 +02:00
|
|
|
QString location;
|
2016-06-05 16:08:55 +02:00
|
|
|
if ( level == Logger::DEBUG )
|
|
|
|
{
|
2016-11-26 22:34:46 +01:00
|
|
|
location = "<" + logMsg.fileName + ":" + QString::number(line)+":"+ logMsg.function + "()> ";
|
2016-06-05 16:08:55 +02:00
|
|
|
}
|
2016-11-26 22:34:46 +01:00
|
|
|
|
2016-06-05 16:08:55 +02:00
|
|
|
std::cout
|
|
|
|
<< "[" << _appname << " " << _name << "] <"
|
2016-10-13 21:59:10 +02:00
|
|
|
<< LogLevelStrings[level] << "> " << location.toStdString() << msg
|
2016-06-05 16:08:55 +02:00
|
|
|
<< std::endl;
|
|
|
|
|
|
|
|
if ( _syslogEnabled && level >= Logger::WARNING )
|
|
|
|
syslog (LogLevelSysLog[level], "%s", msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-11-26 22:46:16 +01:00
|
|
|
LoggerManager::LoggerManager()
|
2016-11-26 22:34:46 +01:00
|
|
|
: QObject()
|
2016-11-26 22:46:16 +01:00
|
|
|
, _loggerMaxMsgBufferSize(200)
|
2016-11-26 22:34:46 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-11-26 22:46:16 +01:00
|
|
|
void LoggerManager::handleNewLogMessage(Logger::T_LOG_MESSAGE msg)
|
2016-11-26 22:34:46 +01:00
|
|
|
{
|
2016-11-26 22:46:16 +01:00
|
|
|
_logMessageBuffer.append(msg);
|
|
|
|
if (_logMessageBuffer.length() > _loggerMaxMsgBufferSize)
|
|
|
|
{
|
|
|
|
_logMessageBuffer.erase(_logMessageBuffer.begin());
|
|
|
|
}
|
2016-11-26 22:34:46 +01:00
|
|
|
|
|
|
|
emit newLogMessage(msg);
|
|
|
|
}
|
|
|
|
|
2016-11-26 22:46:16 +01:00
|
|
|
LoggerManager* LoggerManager::getInstance()
|
2016-11-26 22:34:46 +01:00
|
|
|
{
|
2016-11-26 22:46:16 +01:00
|
|
|
if ( _instance == nullptr )
|
|
|
|
_instance = new LoggerManager();
|
|
|
|
return _instance;
|
2016-11-26 22:34:46 +01:00
|
|
|
}
|