2016-06-05 16:08:55 +02:00
|
|
|
#include "utils/Logger.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <syslog.h>
|
|
|
|
#include <map>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QString>
|
|
|
|
|
|
|
|
std::string getBaseName( std::string sourceFile)
|
|
|
|
{
|
|
|
|
QFileInfo fi( sourceFile.c_str() );
|
|
|
|
return fi.fileName().toStdString();
|
|
|
|
}
|
|
|
|
|
2016-06-21 21:41:26 +02:00
|
|
|
static const char * LogLevelStrings[] = { "", "DEBUG", "INFO", "WARNING", "ERROR" };
|
|
|
|
static const int LogLevelSysLog[] = { LOG_DEBUG, LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERR };
|
2016-06-05 16:08:55 +02:00
|
|
|
static unsigned int loggerCount = 0;
|
|
|
|
static unsigned int loggerId = 0;
|
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-06-05 16:08:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
Logger* Logger::getInstance(std::string name, Logger::LogLevel minLevel)
|
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
|
|
|
if ( LoggerMap->find(name) == LoggerMap->end() )
|
|
|
|
{
|
|
|
|
Logger* log = new Logger(name,minLevel);
|
2016-06-21 21:41:26 +02:00
|
|
|
LoggerMap->insert(std::pair<std::string,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
|
2016-06-05 16:08:55 +02:00
|
|
|
return log;
|
|
|
|
}
|
|
|
|
|
2016-06-21 21:41:26 +02:00
|
|
|
return LoggerMap->at(name);
|
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
|
|
|
|
{
|
|
|
|
Logger* log = Logger::getInstance(name,level);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger* log = Logger::getInstance(name);
|
|
|
|
return log->getMinLevel();
|
|
|
|
}
|
2016-06-05 16:08:55 +02:00
|
|
|
|
|
|
|
Logger::Logger ( std::string name, LogLevel minLevel ):
|
|
|
|
_name(name),
|
|
|
|
_minLevel(minLevel),
|
|
|
|
_syslogEnabled(true),
|
|
|
|
_loggerId(loggerId++)
|
|
|
|
{
|
2016-06-14 20:14:06 +02:00
|
|
|
#ifdef __GLIBC__
|
2016-06-05 16:08:55 +02:00
|
|
|
_appname = std::string(program_invocation_short_name);
|
2016-06-12 22:27:34 +02:00
|
|
|
#else
|
|
|
|
_appname = std::string(getprogname());
|
|
|
|
#endif
|
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 )
|
|
|
|
{
|
|
|
|
openlog (program_invocation_short_name, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
std::string location;
|
|
|
|
std::string function(func);
|
|
|
|
if ( level == Logger::DEBUG )
|
|
|
|
{
|
|
|
|
location = "<" + getBaseName(sourceFile) + ":" + QString::number(line).toStdString()+":"+ function + "()> ";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout
|
|
|
|
<< "[" << _appname << " " << _name << "] <"
|
|
|
|
<< LogLevelStrings[level] << "> " << location << msg
|
|
|
|
<< std::endl;
|
|
|
|
|
|
|
|
if ( _syslogEnabled && level >= Logger::WARNING )
|
|
|
|
syslog (LogLevelSysLog[level], "%s", msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|