mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
- Moved the private part of the logging API to CLogger.h/.cpp
This commit is contained in:
parent
1bb79ed187
commit
b82f232e50
@ -14,11 +14,7 @@ set(lib_SRCS
|
||||
Filesystem/CFileInputStream.cpp
|
||||
Filesystem/CCompressedStream.cpp
|
||||
Logging/CBasicLogConfigurator.cpp
|
||||
Logging/CLogConsoleTarget.cpp
|
||||
Logging/CLogFileTarget.cpp
|
||||
Logging/CLogFormatter.cpp
|
||||
Logging/CLogger.cpp
|
||||
Logging/CLogManager.cpp
|
||||
Mapping/CCampaignHandler.cpp
|
||||
Mapping/CMap.cpp
|
||||
Mapping/CMapEditManager.cpp
|
||||
@ -66,13 +62,7 @@ set(lib_HEADERS
|
||||
Filesystem/CInputStream.h
|
||||
Filesystem/ISimpleResourceLoader.h
|
||||
Logging/CBasicLogConfigurator.h
|
||||
Logging/CLogConsoleTarget.h
|
||||
Logging/CLogFileTarget.h
|
||||
Logging/CLogFormatter.h
|
||||
Logging/CLogger.h
|
||||
Logging/CLogManager.h
|
||||
Logging/ILogTarget.h
|
||||
Logging/LogRecord.h
|
||||
Mapping/CCampaignHandler.h
|
||||
Mapping/CMap.h
|
||||
Mapping/CMapEditManager.h
|
||||
|
@ -2,8 +2,6 @@
|
||||
#include "CBasicLogConfigurator.h"
|
||||
|
||||
#include "../CConfigHandler.h"
|
||||
#include "CLogConsoleTarget.h"
|
||||
#include "CLogFileTarget.h"
|
||||
|
||||
CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console)
|
||||
{
|
||||
|
@ -1,126 +0,0 @@
|
||||
#include "StdInc.h"
|
||||
#include "CLogConsoleTarget.h"
|
||||
|
||||
#include "LogRecord.h"
|
||||
|
||||
CColorMapping::CColorMapping()
|
||||
{
|
||||
// Set default mappings
|
||||
auto & levelMap = map[""];
|
||||
levelMap[ELogLevel::TRACE] = EConsoleTextColor::GRAY;
|
||||
levelMap[ELogLevel::DEBUG] = EConsoleTextColor::WHITE;
|
||||
levelMap[ELogLevel::INFO] = EConsoleTextColor::GREEN;
|
||||
levelMap[ELogLevel::WARN] = EConsoleTextColor::YELLOW;
|
||||
levelMap[ELogLevel::ERROR] = EConsoleTextColor::RED;
|
||||
}
|
||||
|
||||
void CColorMapping::setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color)
|
||||
{
|
||||
if(level == ELogLevel::NOT_SET) throw std::runtime_error("Log level NOT_SET not allowed for configuring the color mapping.");
|
||||
map[domain.getName()][level] = color;
|
||||
}
|
||||
|
||||
EConsoleTextColor::EConsoleTextColor CColorMapping::getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const
|
||||
{
|
||||
std::string name = domain.getName();
|
||||
while(true)
|
||||
{
|
||||
const auto & loggerPair = map.find(name);
|
||||
if(loggerPair != map.end())
|
||||
{
|
||||
const auto & levelMap = loggerPair->second;
|
||||
const auto & levelPair = levelMap.find(level);
|
||||
if(levelPair != levelMap.end())
|
||||
{
|
||||
return levelPair->second;
|
||||
}
|
||||
}
|
||||
|
||||
CLoggerDomain currentDomain(name);
|
||||
if(!currentDomain.isGlobalDomain())
|
||||
{
|
||||
name = currentDomain.getParent().getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("No color mapping found. Should not happen.");
|
||||
}
|
||||
|
||||
CLogConsoleTarget::CLogConsoleTarget(CConsoleHandler * console) : console(console), threshold(ELogLevel::INFO), coloredOutputEnabled(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::write(const LogRecord & record)
|
||||
{
|
||||
if(threshold > record.level) return;
|
||||
|
||||
std::string message = formatter.format(record);
|
||||
bool printToStdErr = record.level >= ELogLevel::WARN;
|
||||
if(console)
|
||||
{
|
||||
if(coloredOutputEnabled)
|
||||
{
|
||||
console->print(message, colorMapping.getColorFor(record.domain, record.level));
|
||||
}
|
||||
else
|
||||
{
|
||||
console->print(message, EConsoleTextColor::DEFAULT, printToStdErr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TLockGuard _(mx);
|
||||
if(printToStdErr)
|
||||
{
|
||||
std::cerr << message << std::flush;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << message << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CLogConsoleTarget::isColoredOutputEnabled() const
|
||||
{
|
||||
return coloredOutputEnabled;
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::setColoredOutputEnabled(bool coloredOutputEnabled)
|
||||
{
|
||||
this->coloredOutputEnabled = coloredOutputEnabled;
|
||||
}
|
||||
|
||||
ELogLevel::ELogLevel CLogConsoleTarget::getThreshold() const
|
||||
{
|
||||
return threshold;
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::setThreshold(ELogLevel::ELogLevel threshold)
|
||||
{
|
||||
this->threshold = threshold;
|
||||
}
|
||||
|
||||
const CLogFormatter & CLogConsoleTarget::getFormatter() const
|
||||
{
|
||||
return formatter;
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::setFormatter(const CLogFormatter & formatter)
|
||||
{
|
||||
this->formatter = formatter;
|
||||
}
|
||||
|
||||
const CColorMapping & CLogConsoleTarget::getColorMapping() const
|
||||
{
|
||||
return colorMapping;
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::setColorMapping(const CColorMapping & colorMapping)
|
||||
{
|
||||
this->colorMapping = colorMapping;
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
|
||||
/*
|
||||
* CLogConsoleTarget.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ILogTarget.h"
|
||||
#include "CLogger.h"
|
||||
#include "CLogFormatter.h"
|
||||
#include "CConsoleHandler.h"
|
||||
|
||||
struct LogRecord;
|
||||
|
||||
/**
|
||||
* The color mapping maps a logger name and a level to a specific color.
|
||||
*/
|
||||
class DLL_LINKAGE CColorMapping
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor. There are default color mappings for the root logger, which child loggers inherit if not overriden.
|
||||
*/
|
||||
CColorMapping();
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Sets a console text color for a logger name and a level.
|
||||
*
|
||||
* @param domain The domain of the logger.
|
||||
* @param level The logger level.
|
||||
* @param color The console text color to use as the mapping.
|
||||
*/
|
||||
void setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color);
|
||||
|
||||
/**
|
||||
* Gets a console text color for a logger name and a level.
|
||||
*
|
||||
* @param domain The domain of the logger.
|
||||
* @param level The logger level.
|
||||
* @return the console text color which has been applied for the mapping
|
||||
*/
|
||||
EConsoleTextColor::EConsoleTextColor getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const;
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
std::map<std::string, std::map<ELogLevel::ELogLevel, EConsoleTextColor::EConsoleTextColor> > map;
|
||||
};
|
||||
|
||||
/**
|
||||
* The console target is a logging target which writes message to the console.
|
||||
*/
|
||||
class DLL_LINKAGE CLogConsoleTarget : public ILogTarget
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param console Optional. The console handler which is used to output messages to the console.
|
||||
*/
|
||||
explicit CLogConsoleTarget(CConsoleHandler * console);
|
||||
|
||||
// Accessors
|
||||
|
||||
bool isColoredOutputEnabled() const;
|
||||
void setColoredOutputEnabled(bool coloredOutputEnabled);
|
||||
|
||||
ELogLevel::ELogLevel getThreshold() const;
|
||||
void setThreshold(ELogLevel::ELogLevel threshold);
|
||||
|
||||
const CLogFormatter & getFormatter() const;
|
||||
void setFormatter(const CLogFormatter & formatter);
|
||||
|
||||
const CColorMapping & getColorMapping() const;
|
||||
void setColorMapping(const CColorMapping & colorMapping);
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Writes a log record to the console.
|
||||
*
|
||||
* @param record The log record to write.
|
||||
*/
|
||||
void write(const LogRecord & record);
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
CConsoleHandler * console;
|
||||
ELogLevel::ELogLevel threshold;
|
||||
bool coloredOutputEnabled;
|
||||
CLogFormatter formatter;
|
||||
CColorMapping colorMapping;
|
||||
mutable boost::mutex mx;
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
#include "StdInc.h"
|
||||
#include "CLogFileTarget.h"
|
||||
|
||||
CLogFileTarget::CLogFileTarget(const std::string & filePath) : file(filePath)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CLogFileTarget::~CLogFileTarget()
|
||||
{
|
||||
file.close();
|
||||
}
|
||||
|
||||
void CLogFileTarget::write(const LogRecord & record)
|
||||
{
|
||||
TLockGuard _(mx);
|
||||
file << formatter.format(record) << std::endl;
|
||||
}
|
||||
|
||||
const CLogFormatter & CLogFileTarget::getFormatter() const
|
||||
{
|
||||
return formatter;
|
||||
}
|
||||
|
||||
void CLogFileTarget::setFormatter(const CLogFormatter & formatter)
|
||||
{
|
||||
this->formatter = formatter;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
|
||||
/*
|
||||
* CLogFileTarget.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ILogTarget.h"
|
||||
#include "CLogFormatter.h"
|
||||
|
||||
/**
|
||||
* The log file target is a logging target which writes messages to a log file.
|
||||
*/
|
||||
class DLL_LINKAGE CLogFileTarget : public ILogTarget
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param filePath The file path of the log file.
|
||||
*/
|
||||
explicit CLogFileTarget(const std::string & filePath);
|
||||
~CLogFileTarget();
|
||||
|
||||
// Accessors
|
||||
|
||||
const CLogFormatter & getFormatter() const;
|
||||
void setFormatter(const CLogFormatter & formatter);
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Writes a log record to the log file.
|
||||
*
|
||||
* @param record The log record to write.
|
||||
*/
|
||||
void write(const LogRecord & record);
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
std::ofstream file;
|
||||
CLogFormatter formatter;
|
||||
mutable boost::mutex mx;
|
||||
};
|
||||
|
@ -1,65 +0,0 @@
|
||||
#include "StdInc.h"
|
||||
#include "CLogFormatter.h"
|
||||
|
||||
#include "LogRecord.h"
|
||||
|
||||
CLogFormatter::CLogFormatter() : pattern("%m")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CLogFormatter::CLogFormatter(const std::string & pattern) : pattern(pattern)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string CLogFormatter::format(const LogRecord & record) const
|
||||
{
|
||||
std::string message = pattern;
|
||||
|
||||
// Format date
|
||||
std::stringstream dateStream;
|
||||
boost::posix_time::time_facet * facet = new boost::posix_time::time_facet("%d-%b-%Y %H:%M:%S");
|
||||
dateStream.imbue(std::locale(dateStream.getloc(), facet));
|
||||
dateStream << record.timeStamp;
|
||||
boost::algorithm::replace_all(message, "%d", dateStream.str());
|
||||
|
||||
// Format log level
|
||||
std::string level;
|
||||
switch(record.level)
|
||||
{
|
||||
case ELogLevel::TRACE:
|
||||
level = "TRACE";
|
||||
break;
|
||||
case ELogLevel::DEBUG:
|
||||
level = "DEBUG";
|
||||
break;
|
||||
case ELogLevel::INFO:
|
||||
level = "INFO";
|
||||
break;
|
||||
case ELogLevel::WARN:
|
||||
level = "WARN";
|
||||
break;
|
||||
case ELogLevel::ERROR:
|
||||
level = "ERROR";
|
||||
break;
|
||||
}
|
||||
boost::algorithm::replace_all(message, "%l", level);
|
||||
|
||||
// Format name, thread id and message
|
||||
boost::algorithm::replace_all(message, "%n", record.domain.getName());
|
||||
boost::algorithm::replace_all(message, "%t", boost::lexical_cast<std::string>(record.threadId));
|
||||
boost::algorithm::replace_all(message, "%m", record.message);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
void CLogFormatter::setPattern(const std::string & pattern)
|
||||
{
|
||||
this->pattern = pattern;
|
||||
}
|
||||
|
||||
const std::string & CLogFormatter::getPattern() const
|
||||
{
|
||||
return pattern;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
|
||||
/*
|
||||
* CLogFormatter.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct LogRecord;
|
||||
|
||||
/**
|
||||
* The log formatter formats log records.
|
||||
*
|
||||
* There are several pattern characters which can be used to format a log record:
|
||||
* %d = Date/Time
|
||||
* %l = Log level
|
||||
* %n = Logger name
|
||||
* %t = Thread ID
|
||||
* %m = Message
|
||||
*/
|
||||
class DLL_LINKAGE CLogFormatter
|
||||
{
|
||||
public:
|
||||
CLogFormatter();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pattern The pattern to format the log record with.
|
||||
*/
|
||||
CLogFormatter(const std::string & pattern);
|
||||
|
||||
// Accessors
|
||||
|
||||
void setPattern(const std::string & pattern);
|
||||
const std::string & getPattern() const;
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Formats a log record.
|
||||
*
|
||||
* @param record The log record to format.
|
||||
* @return the formatted log record as a string
|
||||
*/
|
||||
std::string format(const LogRecord & record) const;
|
||||
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
std::string pattern;
|
||||
};
|
@ -1,51 +0,0 @@
|
||||
#include "StdInc.h"
|
||||
#include "CLogManager.h"
|
||||
|
||||
#include "CLogger.h"
|
||||
|
||||
CLogManager * CLogManager::instance = nullptr;
|
||||
|
||||
boost::mutex CLogManager::smx;
|
||||
|
||||
CLogManager * CLogManager::get()
|
||||
{
|
||||
TLockGuard _(smx);
|
||||
if(!instance)
|
||||
{
|
||||
instance = new CLogManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
CLogManager::CLogManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CLogManager::~CLogManager()
|
||||
{
|
||||
BOOST_FOREACH(auto & i, loggers)
|
||||
{
|
||||
delete i.second;
|
||||
}
|
||||
}
|
||||
|
||||
void CLogManager::addLogger(CGLogger * logger)
|
||||
{
|
||||
TWriteLock _(mx);
|
||||
loggers[logger->getDomain().getName()] = logger;
|
||||
}
|
||||
|
||||
CGLogger * CLogManager::getLogger(const CLoggerDomain & domain)
|
||||
{
|
||||
TReadLock _(mx);
|
||||
auto it = loggers.find(domain.getName());
|
||||
if(it != loggers.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
|
||||
/*
|
||||
* CLogManager.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class CGLogger;
|
||||
class CLoggerDomain;
|
||||
|
||||
/**
|
||||
* The log manager is a global storage of all logger objects.
|
||||
*/
|
||||
class DLL_LINKAGE CLogManager : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
~CLogManager();
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Gets an instance of the log manager.
|
||||
*
|
||||
* @return an instance of the log manager
|
||||
*/
|
||||
static CLogManager * get();
|
||||
|
||||
/**
|
||||
* Adds a logger. The log manager holds strong ownership of the logger object.
|
||||
*
|
||||
* @param logger The logger to add.
|
||||
*/
|
||||
void addLogger(CGLogger * logger);
|
||||
|
||||
/**
|
||||
* Gets a logger by domain.
|
||||
*
|
||||
* @param domain The domain of the logger.
|
||||
* @return a logger by domain or nullptr if the logger was not found
|
||||
*/
|
||||
CGLogger * getLogger(const CLoggerDomain & domain);
|
||||
|
||||
private:
|
||||
// Methods
|
||||
|
||||
CLogManager();
|
||||
|
||||
// Data members
|
||||
|
||||
static CLogManager * instance;
|
||||
std::map<std::string, CGLogger *> loggers;
|
||||
mutable boost::shared_mutex mx;
|
||||
static boost::mutex smx;
|
||||
};
|
@ -1,10 +1,5 @@
|
||||
#include "StdInc.h"
|
||||
#include "CLogger.h"
|
||||
#include "LogRecord.h"
|
||||
#include "ILogTarget.h"
|
||||
#include "CLogManager.h"
|
||||
|
||||
boost::mutex CGLogger::smx;
|
||||
|
||||
const std::string CLoggerDomain::DOMAIN_GLOBAL = "global";
|
||||
|
||||
@ -38,6 +33,8 @@ std::string CLoggerDomain::getName() const
|
||||
return name;
|
||||
}
|
||||
|
||||
boost::mutex CGLogger::smx;
|
||||
|
||||
CGLogger * CGLogger::getLogger(const CLoggerDomain & domain)
|
||||
{
|
||||
TLockGuard _(smx);
|
||||
@ -203,3 +200,259 @@ CLoggerStream::~CLoggerStream()
|
||||
sbuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CLogManager * CLogManager::instance = nullptr;
|
||||
|
||||
boost::mutex CLogManager::smx;
|
||||
|
||||
CLogManager * CLogManager::get()
|
||||
{
|
||||
TLockGuard _(smx);
|
||||
if(!instance)
|
||||
{
|
||||
instance = new CLogManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
CLogManager::CLogManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CLogManager::~CLogManager()
|
||||
{
|
||||
BOOST_FOREACH(auto & i, loggers)
|
||||
{
|
||||
delete i.second;
|
||||
}
|
||||
}
|
||||
|
||||
void CLogManager::addLogger(CGLogger * logger)
|
||||
{
|
||||
TWriteLock _(mx);
|
||||
loggers[logger->getDomain().getName()] = logger;
|
||||
}
|
||||
|
||||
CGLogger * CLogManager::getLogger(const CLoggerDomain & domain)
|
||||
{
|
||||
TReadLock _(mx);
|
||||
auto it = loggers.find(domain.getName());
|
||||
if(it != loggers.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CLogFormatter::CLogFormatter() : pattern("%m")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CLogFormatter::CLogFormatter(const std::string & pattern) : pattern(pattern)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string CLogFormatter::format(const LogRecord & record) const
|
||||
{
|
||||
std::string message = pattern;
|
||||
|
||||
// Format date
|
||||
std::stringstream dateStream;
|
||||
boost::posix_time::time_facet * facet = new boost::posix_time::time_facet("%d-%b-%Y %H:%M:%S");
|
||||
dateStream.imbue(std::locale(dateStream.getloc(), facet));
|
||||
dateStream << record.timeStamp;
|
||||
boost::algorithm::replace_all(message, "%d", dateStream.str());
|
||||
|
||||
// Format log level
|
||||
std::string level;
|
||||
switch(record.level)
|
||||
{
|
||||
case ELogLevel::TRACE:
|
||||
level = "TRACE";
|
||||
break;
|
||||
case ELogLevel::DEBUG:
|
||||
level = "DEBUG";
|
||||
break;
|
||||
case ELogLevel::INFO:
|
||||
level = "INFO";
|
||||
break;
|
||||
case ELogLevel::WARN:
|
||||
level = "WARN";
|
||||
break;
|
||||
case ELogLevel::ERROR:
|
||||
level = "ERROR";
|
||||
break;
|
||||
}
|
||||
boost::algorithm::replace_all(message, "%l", level);
|
||||
|
||||
// Format name, thread id and message
|
||||
boost::algorithm::replace_all(message, "%n", record.domain.getName());
|
||||
boost::algorithm::replace_all(message, "%t", boost::lexical_cast<std::string>(record.threadId));
|
||||
boost::algorithm::replace_all(message, "%m", record.message);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
void CLogFormatter::setPattern(const std::string & pattern)
|
||||
{
|
||||
this->pattern = pattern;
|
||||
}
|
||||
|
||||
const std::string & CLogFormatter::getPattern() const
|
||||
{
|
||||
return pattern;
|
||||
}
|
||||
|
||||
CColorMapping::CColorMapping()
|
||||
{
|
||||
// Set default mappings
|
||||
auto & levelMap = map[""];
|
||||
levelMap[ELogLevel::TRACE] = EConsoleTextColor::GRAY;
|
||||
levelMap[ELogLevel::DEBUG] = EConsoleTextColor::WHITE;
|
||||
levelMap[ELogLevel::INFO] = EConsoleTextColor::GREEN;
|
||||
levelMap[ELogLevel::WARN] = EConsoleTextColor::YELLOW;
|
||||
levelMap[ELogLevel::ERROR] = EConsoleTextColor::RED;
|
||||
}
|
||||
|
||||
void CColorMapping::setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color)
|
||||
{
|
||||
if(level == ELogLevel::NOT_SET) throw std::runtime_error("Log level NOT_SET not allowed for configuring the color mapping.");
|
||||
map[domain.getName()][level] = color;
|
||||
}
|
||||
|
||||
EConsoleTextColor::EConsoleTextColor CColorMapping::getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const
|
||||
{
|
||||
std::string name = domain.getName();
|
||||
while(true)
|
||||
{
|
||||
const auto & loggerPair = map.find(name);
|
||||
if(loggerPair != map.end())
|
||||
{
|
||||
const auto & levelMap = loggerPair->second;
|
||||
const auto & levelPair = levelMap.find(level);
|
||||
if(levelPair != levelMap.end())
|
||||
{
|
||||
return levelPair->second;
|
||||
}
|
||||
}
|
||||
|
||||
CLoggerDomain currentDomain(name);
|
||||
if(!currentDomain.isGlobalDomain())
|
||||
{
|
||||
name = currentDomain.getParent().getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("No color mapping found. Should not happen.");
|
||||
}
|
||||
|
||||
CLogConsoleTarget::CLogConsoleTarget(CConsoleHandler * console) : console(console), threshold(ELogLevel::INFO), coloredOutputEnabled(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::write(const LogRecord & record)
|
||||
{
|
||||
if(threshold > record.level) return;
|
||||
|
||||
std::string message = formatter.format(record);
|
||||
bool printToStdErr = record.level >= ELogLevel::WARN;
|
||||
if(console)
|
||||
{
|
||||
if(coloredOutputEnabled)
|
||||
{
|
||||
console->print(message, colorMapping.getColorFor(record.domain, record.level));
|
||||
}
|
||||
else
|
||||
{
|
||||
console->print(message, EConsoleTextColor::DEFAULT, printToStdErr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TLockGuard _(mx);
|
||||
if(printToStdErr)
|
||||
{
|
||||
std::cerr << message << std::flush;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << message << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CLogConsoleTarget::isColoredOutputEnabled() const
|
||||
{
|
||||
return coloredOutputEnabled;
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::setColoredOutputEnabled(bool coloredOutputEnabled)
|
||||
{
|
||||
this->coloredOutputEnabled = coloredOutputEnabled;
|
||||
}
|
||||
|
||||
ELogLevel::ELogLevel CLogConsoleTarget::getThreshold() const
|
||||
{
|
||||
return threshold;
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::setThreshold(ELogLevel::ELogLevel threshold)
|
||||
{
|
||||
this->threshold = threshold;
|
||||
}
|
||||
|
||||
const CLogFormatter & CLogConsoleTarget::getFormatter() const
|
||||
{
|
||||
return formatter;
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::setFormatter(const CLogFormatter & formatter)
|
||||
{
|
||||
this->formatter = formatter;
|
||||
}
|
||||
|
||||
const CColorMapping & CLogConsoleTarget::getColorMapping() const
|
||||
{
|
||||
return colorMapping;
|
||||
}
|
||||
|
||||
void CLogConsoleTarget::setColorMapping(const CColorMapping & colorMapping)
|
||||
{
|
||||
this->colorMapping = colorMapping;
|
||||
}
|
||||
|
||||
CLogFileTarget::CLogFileTarget(const std::string & filePath) : file(filePath)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CLogFileTarget::~CLogFileTarget()
|
||||
{
|
||||
file.close();
|
||||
}
|
||||
|
||||
void CLogFileTarget::write(const LogRecord & record)
|
||||
{
|
||||
TLockGuard _(mx);
|
||||
file << formatter.format(record) << std::endl;
|
||||
}
|
||||
|
||||
const CLogFormatter & CLogFileTarget::getFormatter() const
|
||||
{
|
||||
return formatter;
|
||||
}
|
||||
|
||||
void CLogFileTarget::setFormatter(const CLogFormatter & formatter)
|
||||
{
|
||||
this->formatter = formatter;
|
||||
}
|
||||
|
@ -70,8 +70,6 @@ private:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class CGLogger;
|
||||
|
||||
/**
|
||||
* The logger stream provides a stream-like way of logging messages.
|
||||
*/
|
||||
@ -247,3 +245,259 @@ private:
|
||||
mutable boost::shared_mutex mx;
|
||||
static boost::mutex smx;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
/* Implementation/Detail classes, Private API */
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* The log manager is a global storage of all logger objects.
|
||||
*/
|
||||
class DLL_LINKAGE CLogManager : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
~CLogManager();
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Gets an instance of the log manager.
|
||||
*
|
||||
* @return an instance of the log manager
|
||||
*/
|
||||
static CLogManager * get();
|
||||
|
||||
/**
|
||||
* Adds a logger. The log manager holds strong ownership of the logger object.
|
||||
*
|
||||
* @param logger The logger to add.
|
||||
*/
|
||||
void addLogger(CGLogger * logger);
|
||||
|
||||
/**
|
||||
* Gets a logger by domain.
|
||||
*
|
||||
* @param domain The domain of the logger.
|
||||
* @return a logger by domain or nullptr if the logger was not found
|
||||
*/
|
||||
CGLogger * getLogger(const CLoggerDomain & domain);
|
||||
|
||||
private:
|
||||
// Methods
|
||||
|
||||
CLogManager();
|
||||
|
||||
// Data members
|
||||
|
||||
static CLogManager * instance;
|
||||
std::map<std::string, CGLogger *> loggers;
|
||||
mutable boost::shared_mutex mx;
|
||||
static boost::mutex smx;
|
||||
};
|
||||
|
||||
/**
|
||||
* The log records holds the log message and additional logging information.
|
||||
*/
|
||||
struct DLL_LINKAGE LogRecord
|
||||
{
|
||||
LogRecord(const CLoggerDomain & domain, ELogLevel::ELogLevel level, const std::string & message)
|
||||
: domain(domain), level(level), message(message), timeStamp(boost::posix_time::second_clock::local_time()), threadId(boost::this_thread::get_id())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** The logger domain. */
|
||||
CLoggerDomain domain;
|
||||
|
||||
/** The log level. */
|
||||
ELogLevel::ELogLevel level;
|
||||
|
||||
/** The message. */
|
||||
std::string message;
|
||||
|
||||
/** The time when the message was created. */
|
||||
boost::posix_time::ptime timeStamp;
|
||||
|
||||
/** The thread id. */
|
||||
boost::thread::id threadId;
|
||||
};
|
||||
|
||||
/**
|
||||
* The log formatter formats log records.
|
||||
*
|
||||
* There are several pattern characters which can be used to format a log record:
|
||||
* %d = Date/Time
|
||||
* %l = Log level
|
||||
* %n = Logger name
|
||||
* %t = Thread ID
|
||||
* %m = Message
|
||||
*/
|
||||
class DLL_LINKAGE CLogFormatter
|
||||
{
|
||||
public:
|
||||
CLogFormatter();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param pattern The pattern to format the log record with.
|
||||
*/
|
||||
CLogFormatter(const std::string & pattern);
|
||||
|
||||
// Accessors
|
||||
|
||||
void setPattern(const std::string & pattern);
|
||||
const std::string & getPattern() const;
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Formats a log record.
|
||||
*
|
||||
* @param record The log record to format.
|
||||
* @return the formatted log record as a string
|
||||
*/
|
||||
std::string format(const LogRecord & record) const;
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
std::string pattern;
|
||||
};
|
||||
|
||||
/**
|
||||
* The interface log target is used by all log target implementations. It holds
|
||||
* the abstract method write which sub-classes should implement.
|
||||
*/
|
||||
class DLL_LINKAGE ILogTarget : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~ILogTarget() { };
|
||||
|
||||
/**
|
||||
* Writes a log record.
|
||||
*
|
||||
* @param record The log record to write.
|
||||
*/
|
||||
virtual void write(const LogRecord & record) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* The color mapping maps a logger name and a level to a specific color.
|
||||
*/
|
||||
class DLL_LINKAGE CColorMapping
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor. There are default color mappings for the root logger, which child loggers inherit if not overriden.
|
||||
*/
|
||||
CColorMapping();
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Sets a console text color for a logger name and a level.
|
||||
*
|
||||
* @param domain The domain of the logger.
|
||||
* @param level The logger level.
|
||||
* @param color The console text color to use as the mapping.
|
||||
*/
|
||||
void setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color);
|
||||
|
||||
/**
|
||||
* Gets a console text color for a logger name and a level.
|
||||
*
|
||||
* @param domain The domain of the logger.
|
||||
* @param level The logger level.
|
||||
* @return the console text color which has been applied for the mapping
|
||||
*/
|
||||
EConsoleTextColor::EConsoleTextColor getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const;
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
std::map<std::string, std::map<ELogLevel::ELogLevel, EConsoleTextColor::EConsoleTextColor> > map;
|
||||
};
|
||||
|
||||
/**
|
||||
* The console target is a logging target which writes message to the console.
|
||||
*/
|
||||
class DLL_LINKAGE CLogConsoleTarget : public ILogTarget
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param console Optional. The console handler which is used to output messages to the console.
|
||||
*/
|
||||
explicit CLogConsoleTarget(CConsoleHandler * console);
|
||||
|
||||
// Accessors
|
||||
|
||||
bool isColoredOutputEnabled() const;
|
||||
void setColoredOutputEnabled(bool coloredOutputEnabled);
|
||||
|
||||
ELogLevel::ELogLevel getThreshold() const;
|
||||
void setThreshold(ELogLevel::ELogLevel threshold);
|
||||
|
||||
const CLogFormatter & getFormatter() const;
|
||||
void setFormatter(const CLogFormatter & formatter);
|
||||
|
||||
const CColorMapping & getColorMapping() const;
|
||||
void setColorMapping(const CColorMapping & colorMapping);
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Writes a log record to the console.
|
||||
*
|
||||
* @param record The log record to write.
|
||||
*/
|
||||
void write(const LogRecord & record);
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
CConsoleHandler * console;
|
||||
ELogLevel::ELogLevel threshold;
|
||||
bool coloredOutputEnabled;
|
||||
CLogFormatter formatter;
|
||||
CColorMapping colorMapping;
|
||||
mutable boost::mutex mx;
|
||||
};
|
||||
|
||||
/**
|
||||
* The log file target is a logging target which writes messages to a log file.
|
||||
*/
|
||||
class DLL_LINKAGE CLogFileTarget : public ILogTarget
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param filePath The file path of the log file.
|
||||
*/
|
||||
explicit CLogFileTarget(const std::string & filePath);
|
||||
~CLogFileTarget();
|
||||
|
||||
// Accessors
|
||||
|
||||
const CLogFormatter & getFormatter() const;
|
||||
void setFormatter(const CLogFormatter & formatter);
|
||||
|
||||
// Methods
|
||||
|
||||
/**
|
||||
* Writes a log record to the log file.
|
||||
*
|
||||
* @param record The log record to write.
|
||||
*/
|
||||
void write(const LogRecord & record);
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
std::ofstream file;
|
||||
CLogFormatter formatter;
|
||||
mutable boost::mutex mx;
|
||||
};
|
||||
|
@ -1,31 +0,0 @@
|
||||
|
||||
/*
|
||||
* LogRecord.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct LogRecord;
|
||||
|
||||
/**
|
||||
* The interface log target is used by all log target implementations. It holds
|
||||
* the abstract method write which sub-classes should implement.
|
||||
*/
|
||||
class DLL_LINKAGE ILogTarget : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~ILogTarget() { };
|
||||
|
||||
/**
|
||||
* Writes a log record.
|
||||
*
|
||||
* @param record The log record to write.
|
||||
*/
|
||||
virtual void write(const LogRecord & record) = 0;
|
||||
};
|
@ -1,41 +0,0 @@
|
||||
|
||||
/*
|
||||
* LogRecord.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CLogger.h"
|
||||
|
||||
/**
|
||||
* The log records holds the log message and additional logging information.
|
||||
*/
|
||||
struct DLL_LINKAGE LogRecord
|
||||
{
|
||||
LogRecord(const CLoggerDomain & domain, ELogLevel::ELogLevel level, const std::string & message)
|
||||
: domain(domain), level(level), message(message), timeStamp(boost::posix_time::second_clock::local_time()), threadId(boost::this_thread::get_id())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** The logger domain. */
|
||||
CLoggerDomain domain;
|
||||
|
||||
/** The log level. */
|
||||
ELogLevel::ELogLevel level;
|
||||
|
||||
/** The message. */
|
||||
std::string message;
|
||||
|
||||
/** The time when the message was created. */
|
||||
boost::posix_time::ptime timeStamp;
|
||||
|
||||
/** The thread id. */
|
||||
boost::thread::id threadId;
|
||||
};
|
Loading…
Reference in New Issue
Block a user