Update easylogging++ from 9.96.7 to 9.97.0

Easylogging++ forgot to update the version number at the top of their
header files. Oops.
This commit is contained in:
Vasily Utkin
2021-01-01 23:28:19 +01:00
committed by username223
parent 5a7fe687d8
commit 3ab10ce334
2 changed files with 164 additions and 138 deletions
+89 -79
View File
@@ -4,17 +4,17 @@
// Easylogging++ v9.96.7 // Easylogging++ v9.96.7
// Cross-platform logging library for C++ applications // Cross-platform logging library for C++ applications
// //
// Copyright (c) 2012-2018 Zuhd Web Services // Copyright (c) 2012-2018 Amrayn Web Services
// Copyright (c) 2012-2018 @abumusamq // Copyright (c) 2012-2018 @abumusamq
// //
// This library is released under the MIT Licence. // This library is released under the MIT Licence.
// https://github.com/zuhd-org/easyloggingpp/blob/master/LICENSE // https://github.com/amrayn/easyloggingpp/blob/master/LICENSE
// //
// https://zuhd.org // https://amrayn.com
// http://muflihun.com // http://muflihun.com
// //
#include <easylogging++.h> #include "easylogging++.h"
#if defined(AUTO_INITIALIZE_EASYLOGGINGPP) #if defined(AUTO_INITIALIZE_EASYLOGGINGPP)
INITIALIZE_EASYLOGGINGPP INITIALIZE_EASYLOGGINGPP
@@ -64,7 +64,7 @@ static const char* kDateTimeFormatSpecifierForFilename = "%datet
// Date/time // Date/time
static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
static const char* kMonths[12] = { "January", "February", "March", "Apri", "May", "June", "July", "August", static const char* kMonths[12] = { "January", "February", "March", "April", "May", "June", "July", "August",
"September", "October", "November", "December" "September", "October", "November", "December"
}; };
static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
@@ -79,7 +79,7 @@ static const char* kNullPointer = "nullptr";
#if ELPP_VARIADIC_TEMPLATES_SUPPORTED #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
static const base::type::VerboseLevel kMaxVerboseLevel = 9; static const base::type::VerboseLevel kMaxVerboseLevel = 9;
static const char* kUnknownUser = "user"; static const char* kUnknownUser = "unknown-user";
static const char* kUnknownHost = "unknown-host"; static const char* kUnknownHost = "unknown-host";
@@ -292,7 +292,7 @@ Configurations::Configurations(const std::string& configurationFile, bool useDef
} }
bool Configurations::parseFromFile(const std::string& configurationFile, Configurations* base) { bool Configurations::parseFromFile(const std::string& configurationFile, Configurations* base) {
// We initial assertion with true because if we have assertion diabled, we want to pass this // We initial assertion with true because if we have assertion disabled, we want to pass this
// check and if assertion is enabled we will have values re-assigned any way. // check and if assertion is enabled we will have values re-assigned any way.
bool assertionPassed = true; bool assertionPassed = true;
ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(), true)) == true, ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(), true)) == true,
@@ -599,7 +599,7 @@ void LogBuilder::convertToColoredOutput(base::type::string_t* logLine, Level lev
// Logger // Logger
Logger::Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference) : Logger::Logger(const std::string& id, base::LogStreamsReferenceMapPtr logStreamsReference) :
m_id(id), m_id(id),
m_typedConfigurations(nullptr), m_typedConfigurations(nullptr),
m_parentApplicationName(std::string()), m_parentApplicationName(std::string()),
@@ -609,7 +609,7 @@ Logger::Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsRe
} }
Logger::Logger(const std::string& id, const Configurations& configurations, Logger::Logger(const std::string& id, const Configurations& configurations,
base::LogStreamsReferenceMap* logStreamsReference) : base::LogStreamsReferenceMapPtr logStreamsReference) :
m_id(id), m_id(id),
m_typedConfigurations(nullptr), m_typedConfigurations(nullptr),
m_parentApplicationName(std::string()), m_parentApplicationName(std::string()),
@@ -794,22 +794,22 @@ bool File::createPath(const std::string& path) {
if (path[0] == '/') { if (path[0] == '/') {
builtPath = "/"; builtPath = "/";
} }
currPath = STRTOK(currPath, base::consts::kFilePathSeperator, 0); currPath = STRTOK(currPath, base::consts::kFilePathSeparator, 0);
#elif ELPP_OS_WINDOWS #elif ELPP_OS_WINDOWS
// Use secure functions API // Use secure functions API
char* nextTok_ = nullptr; char* nextTok_ = nullptr;
currPath = STRTOK(currPath, base::consts::kFilePathSeperator, &nextTok_); currPath = STRTOK(currPath, base::consts::kFilePathSeparator, &nextTok_);
ELPP_UNUSED(nextTok_); ELPP_UNUSED(nextTok_);
#endif // ELPP_OS_UNIX #endif // ELPP_OS_UNIX
while (currPath != nullptr) { while (currPath != nullptr) {
builtPath.append(currPath); builtPath.append(currPath);
builtPath.append(base::consts::kFilePathSeperator); builtPath.append(base::consts::kFilePathSeparator);
#if ELPP_OS_UNIX #if ELPP_OS_UNIX
status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS); status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS);
currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, 0); currPath = STRTOK(nullptr, base::consts::kFilePathSeparator, 0);
#elif ELPP_OS_WINDOWS #elif ELPP_OS_WINDOWS
status = _mkdir(builtPath.c_str()); status = _mkdir(builtPath.c_str());
currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, &nextTok_); currPath = STRTOK(nullptr, base::consts::kFilePathSeparator, &nextTok_);
#endif // ELPP_OS_UNIX #endif // ELPP_OS_UNIX
} }
if (status == -1) { if (status == -1) {
@@ -1013,7 +1013,7 @@ char* Str::clearBuff(char buff[], std::size_t lim) {
return buff; return buff;
} }
/// @brief Converst wchar* to char* /// @brief Converts wchar* to char*
/// NOTE: Need to free return value after use! /// NOTE: Need to free return value after use!
char* Str::wcharPtrToCharPtr(const wchar_t* line) { char* Str::wcharPtrToCharPtr(const wchar_t* line) {
std::size_t len_ = wcslen(line) + 1; std::size_t len_ = wcslen(line) + 1;
@@ -1190,7 +1190,7 @@ std::string DateTime::timevalToString(struct timeval tval, const char* format,
buildTimeInfo(&tval, &timeInfo); buildTimeInfo(&tval, &timeInfo);
const int kBuffSize = 30; const int kBuffSize = 30;
char buff_[kBuffSize] = ""; char buff_[kBuffSize] = "";
parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast<size_t>(static_cast<unsigned long>(tval.tv_usec) / ssPrec->m_offset), parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast<std::size_t>(tval.tv_usec / ssPrec->m_offset),
ssPrec); ssPrec);
return std::string(buff_); return std::string(buff_);
} }
@@ -1199,7 +1199,7 @@ base::type::string_t DateTime::formatTime(unsigned long long time, base::Timesta
base::type::EnumType start = static_cast<base::type::EnumType>(timestampUnit); base::type::EnumType start = static_cast<base::type::EnumType>(timestampUnit);
const base::type::char_t* unit = base::consts::kTimeFormats[start].unit; const base::type::char_t* unit = base::consts::kTimeFormats[start].unit;
for (base::type::EnumType i = start; i < base::consts::kTimeFormatsCount - 1; ++i) { for (base::type::EnumType i = start; i < base::consts::kTimeFormatsCount - 1; ++i) {
if (static_cast<double>(time) <= base::consts::kTimeFormats[i].value) { if (time <= static_cast<decltype(time)>(base::consts::kTimeFormats[i].value)) {
break; break;
} }
if (base::consts::kTimeFormats[i].value == 1000.0 && static_cast<float>(time) / 1000.0f < 1.9f) { if (base::consts::kTimeFormats[i].value == 1000.0 && static_cast<float>(time) / 1000.0f < 1.9f) {
@@ -1264,7 +1264,7 @@ char* DateTime::parseFormat(char* buf, std::size_t bufSz, const char* format, co
--format; --format;
break; break;
case 'd': // Day case 'd': // Day
buf = base::utils::Str::convertAndAddToBuff(static_cast<size_t>(tInfo->tm_mday), 2, buf, bufLim); buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mday, 2, buf, bufLim);
continue; continue;
case 'a': // Day of week (short) case 'a': // Day of week (short)
buf = base::utils::Str::addToBuff(base::consts::kDaysAbbrev[tInfo->tm_wday], buf, bufLim); buf = base::utils::Str::addToBuff(base::consts::kDaysAbbrev[tInfo->tm_wday], buf, bufLim);
@@ -1273,7 +1273,7 @@ char* DateTime::parseFormat(char* buf, std::size_t bufSz, const char* format, co
buf = base::utils::Str::addToBuff(base::consts::kDays[tInfo->tm_wday], buf, bufLim); buf = base::utils::Str::addToBuff(base::consts::kDays[tInfo->tm_wday], buf, bufLim);
continue; continue;
case 'M': // month case 'M': // month
buf = base::utils::Str::convertAndAddToBuff(static_cast<size_t>(tInfo->tm_mon + 1), 2, buf, bufLim); buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mon + 1, 2, buf, bufLim);
continue; continue;
case 'b': // month (short) case 'b': // month (short)
buf = base::utils::Str::addToBuff(base::consts::kMonthsAbbrev[tInfo->tm_mon], buf, bufLim); buf = base::utils::Str::addToBuff(base::consts::kMonthsAbbrev[tInfo->tm_mon], buf, bufLim);
@@ -1282,22 +1282,22 @@ char* DateTime::parseFormat(char* buf, std::size_t bufSz, const char* format, co
buf = base::utils::Str::addToBuff(base::consts::kMonths[tInfo->tm_mon], buf, bufLim); buf = base::utils::Str::addToBuff(base::consts::kMonths[tInfo->tm_mon], buf, bufLim);
continue; continue;
case 'y': // year (two digits) case 'y': // year (two digits)
buf = base::utils::Str::convertAndAddToBuff(static_cast<size_t>(tInfo->tm_year + base::consts::kYearBase), 2, buf, bufLim); buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 2, buf, bufLim);
continue; continue;
case 'Y': // year (four digits) case 'Y': // year (four digits)
buf = base::utils::Str::convertAndAddToBuff(static_cast<size_t>(tInfo->tm_year + base::consts::kYearBase), 4, buf, bufLim); buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 4, buf, bufLim);
continue; continue;
case 'h': // hour (12-hour) case 'h': // hour (12-hour)
buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour % 12, 2, buf, bufLim); buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour % 12, 2, buf, bufLim);
continue; continue;
case 'H': // hour (24-hour) case 'H': // hour (24-hour)
buf = base::utils::Str::convertAndAddToBuff(static_cast<size_t>(tInfo->tm_hour), 2, buf, bufLim); buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour, 2, buf, bufLim);
continue; continue;
case 'm': // minute case 'm': // minute
buf = base::utils::Str::convertAndAddToBuff(static_cast<size_t>(tInfo->tm_min), 2, buf, bufLim); buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_min, 2, buf, bufLim);
continue; continue;
case 's': // second case 's': // second
buf = base::utils::Str::convertAndAddToBuff(static_cast<size_t>(tInfo->tm_sec), 2, buf, bufLim); buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_sec, 2, buf, bufLim);
continue; continue;
case 'z': // subsecond part case 'z': // subsecond part
case 'g': case 'g':
@@ -1524,7 +1524,7 @@ void LogFormat::parseFromFormat(const base::type::string_t& userFormat) {
// For date/time we need to extract user's date format first // For date/time we need to extract user's date format first
std::size_t dateIndex = std::string::npos; std::size_t dateIndex = std::string::npos;
if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) { if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) {
while (dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) { while (dateIndex != std::string::npos && dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) {
dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1); dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1);
} }
if (dateIndex != std::string::npos) { if (dateIndex != std::string::npos) {
@@ -1553,7 +1553,7 @@ void LogFormat::updateDateFormat(std::size_t index, base::type::string_t& currFo
} }
ss << static_cast<char>(*ptr); ss << static_cast<char>(*ptr);
} }
currFormat.erase(index, static_cast<size_t>(count)); currFormat.erase(index, count);
m_dateTimeFormat = ss.str(); m_dateTimeFormat = ss.str();
} else { } else {
// No format provided, use default // No format provided, use default
@@ -1615,7 +1615,7 @@ void LogFormat::updateFormatSpec(void) {
// TypedConfigurations // TypedConfigurations
TypedConfigurations::TypedConfigurations(Configurations* configurations, TypedConfigurations::TypedConfigurations(Configurations* configurations,
base::LogStreamsReferenceMap* logStreamsReference) { LogStreamsReferenceMapPtr logStreamsReference) {
m_configurations = configurations; m_configurations = configurations;
m_logStreamsReference = logStreamsReference; m_logStreamsReference = logStreamsReference;
build(m_configurations); build(m_configurations);
@@ -1691,7 +1691,7 @@ void TypedConfigurations::build(Configurations* configurations) {
// We do not yet configure filename but we will configure in another // We do not yet configure filename but we will configure in another
// loop. This is because if file cannot be created, we will force ToFile // loop. This is because if file cannot be created, we will force ToFile
// to be false. Because configuring logger is not necessarily performance // to be false. Because configuring logger is not necessarily performance
// sensative operation, we can live with another loop; (by the way this loop // sensitive operation, we can live with another loop; (by the way this loop
// is not very heavy either) // is not very heavy either)
} else if (conf->configurationType() == ConfigurationType::Format) { } else if (conf->configurationType() == ConfigurationType::Format) {
setValue(conf->level(), base::LogFormat(conf->level(), setValue(conf->level(), base::LogFormat(conf->level(),
@@ -1737,7 +1737,7 @@ unsigned long TypedConfigurations::getULong(std::string confVal) {
ELPP_ASSERT(valid, "Configuration value not a valid integer [" << confVal << "]"); ELPP_ASSERT(valid, "Configuration value not a valid integer [" << confVal << "]");
return 0; return 0;
} }
return static_cast<unsigned long>(atol(confVal.c_str())); return atol(confVal.c_str());
} }
std::string TypedConfigurations::resolveFilename(const std::string& filename) { std::string TypedConfigurations::resolveFilename(const std::string& filename) {
@@ -1765,7 +1765,7 @@ std::string TypedConfigurations::resolveFilename(const std::string& filename) {
} }
ss << *ptr; ss << *ptr;
} }
resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), static_cast<size_t>(count)); resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), count);
fmt = ss.str(); fmt = ss.str();
} else { } else {
fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename); fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename);
@@ -1785,34 +1785,34 @@ void TypedConfigurations::insertFile(Level level, const std::string& fullFilenam
std::cerr << "Could not load empty file for logging, please re-check your configurations for level [" std::cerr << "Could not load empty file for logging, please re-check your configurations for level ["
<< LevelHelper::convertToString(level) << "]"; << LevelHelper::convertToString(level) << "]";
} }
std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeperator); std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeparator);
if (filePath.size() < resolvedFilename.size()) { if (filePath.size() < resolvedFilename.size()) {
base::utils::File::createPath(filePath); base::utils::File::createPath(filePath);
} }
auto create = [&](Level level_var) { auto create = [&](Level var_level) {
base::LogStreamsReferenceMap::iterator filestreamIter = m_logStreamsReference->find(resolvedFilename); base::LogStreamsReferenceMap::iterator filestreamIter = m_logStreamsReference->find(resolvedFilename);
base::type::fstream_t* fs = nullptr; base::type::fstream_t* fs = nullptr;
if (filestreamIter == m_logStreamsReference->end()) { if (filestreamIter == m_logStreamsReference->end()) {
// We need a completely new stream, nothing to share with // We need a completely new stream, nothing to share with
fs = base::utils::File::newFileStream(resolvedFilename); fs = base::utils::File::newFileStream(resolvedFilename);
m_filenameMap.insert(std::make_pair(level_var, resolvedFilename)); m_filenameMap.insert(std::make_pair(var_level, resolvedFilename));
m_fileStreamMap.insert(std::make_pair(level_var, base::FileStreamPtr(fs))); m_fileStreamMap.insert(std::make_pair(var_level, base::FileStreamPtr(fs)));
m_logStreamsReference->insert(std::make_pair(resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(level_var)))); m_logStreamsReference->insert(std::make_pair(resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(var_level))));
} else { } else {
// Woops! we have an existing one, share it! // Woops! we have an existing one, share it!
m_filenameMap.insert(std::make_pair(level_var, filestreamIter->first)); m_filenameMap.insert(std::make_pair(var_level, filestreamIter->first));
m_fileStreamMap.insert(std::make_pair(level_var, base::FileStreamPtr(filestreamIter->second))); m_fileStreamMap.insert(std::make_pair(var_level, base::FileStreamPtr(filestreamIter->second)));
fs = filestreamIter->second.get(); fs = filestreamIter->second.get();
} }
if (fs == nullptr) { if (fs == nullptr) {
// We display bad file error from newFileStream() // We display bad file error from newFileStream()
ELPP_INTERNAL_ERROR("Setting [TO_FILE] of [" ELPP_INTERNAL_ERROR("Setting [TO_FILE] of ["
<< LevelHelper::convertToString(level_var) << "] to FALSE", false); << LevelHelper::convertToString(var_level) << "] to FALSE", false);
setValue(level_var, false, &m_toFileMap); setValue(var_level, false, &m_toFileMap);
} }
}; };
// If we dont have file conf for any level, create it for Level::Global first // If we dont have file conf for any var_level, create it for Level::Global first
// otherwise create for specified level // otherwise create for specified var_level
create(m_filenameMap.empty() && m_fileStreamMap.empty() ? Level::Global : level); create(m_filenameMap.empty() && m_fileStreamMap.empty() ? Level::Global : level);
} }
@@ -1885,6 +1885,7 @@ bool RegisteredHitCounters::validateNTimes(const char* filename, base::type::Lin
RegisteredLoggers::RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder) : RegisteredLoggers::RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder) :
m_defaultLogBuilder(defaultLogBuilder) { m_defaultLogBuilder(defaultLogBuilder) {
m_defaultConfigurations.setToDefault(); m_defaultConfigurations.setToDefault();
m_logStreamsReference = std::make_shared<base::LogStreamsReferenceMap>();
} }
Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) { Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) {
@@ -1896,11 +1897,11 @@ Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) {
ELPP_ASSERT(validId, "Invalid logger ID [" << id << "]. Not registering this logger."); ELPP_ASSERT(validId, "Invalid logger ID [" << id << "]. Not registering this logger.");
return nullptr; return nullptr;
} }
logger_ = new Logger(id, m_defaultConfigurations, &m_logStreamsReference); logger_ = new Logger(id, m_defaultConfigurations, m_logStreamsReference);
logger_->m_logBuilder = m_defaultLogBuilder; logger_->m_logBuilder = m_defaultLogBuilder;
registerNew(id, logger_); registerNew(id, logger_);
LoggerRegistrationCallback* callback = nullptr; LoggerRegistrationCallback* callback = nullptr;
for (const std::pair<std::string, base::type::LoggerRegistrationCallbackPtr>& h for (const std::pair<std::string, base::type::LoggerRegistrationCallbackPtr> h
: m_loggerRegistrationCallbacks) { : m_loggerRegistrationCallbacks) {
callback = h.second.get(); callback = h.second.get();
if (callback != nullptr && callback->enabled()) { if (callback != nullptr && callback->enabled()) {
@@ -1926,8 +1927,8 @@ bool RegisteredLoggers::remove(const std::string& id) {
void RegisteredLoggers::unsafeFlushAll(void) { void RegisteredLoggers::unsafeFlushAll(void) {
ELPP_INTERNAL_INFO(1, "Flushing all log files"); ELPP_INTERNAL_INFO(1, "Flushing all log files");
for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference.begin(); for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference->begin();
it != m_logStreamsReference.end(); ++it) { it != m_logStreamsReference->end(); ++it) {
if (it->second.get() == nullptr) continue; if (it->second.get() == nullptr) continue;
it->second->flush(); it->second->flush();
} }
@@ -2184,16 +2185,18 @@ void Storage::setApplicationArguments(int argc, char** argv) {
} // namespace base } // namespace base
// LogDispatchCallback // LogDispatchCallback
void LogDispatchCallback::handle(const LogDispatchData* data) {
#if defined(ELPP_THREAD_SAFE) #if defined(ELPP_THREAD_SAFE)
void LogDispatchCallback::handle(const LogDispatchData* data) {
base::threading::ScopedLock scopedLock(m_fileLocksMapLock); base::threading::ScopedLock scopedLock(m_fileLocksMapLock);
std::string filename = data->logMessage()->logger()->typedConfigurations()->filename(data->logMessage()->level()); std::string filename = data->logMessage()->logger()->typedConfigurations()->filename(data->logMessage()->level());
auto lock = m_fileLocks.find(filename); auto lock = m_fileLocks.find(filename);
if (lock == m_fileLocks.end()) { if (lock == m_fileLocks.end()) {
m_fileLocks.emplace(std::make_pair(filename, std::unique_ptr<base::threading::Mutex>(new base::threading::Mutex))); m_fileLocks.emplace(std::make_pair(filename, std::unique_ptr<base::threading::Mutex>(new base::threading::Mutex)));
} }
#endif
} }
#else
void LogDispatchCallback::handle(const LogDispatchData* /*data*/) {}
#endif
base::threading::Mutex& LogDispatchCallback::fileHandle(const LogDispatchData* data) { base::threading::Mutex& LogDispatchCallback::fileHandle(const LogDispatchData* data) {
auto it = m_fileLocks.find(data->logMessage()->logger()->typedConfigurations()->filename(data->logMessage()->level())); auto it = m_fileLocks.find(data->logMessage()->logger()->typedConfigurations()->filename(data->logMessage()->level()));
@@ -2219,7 +2222,7 @@ void DefaultLogDispatchCallback::dispatch(base::type::string_t&& logLine) {
base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream( base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream(
m_data->logMessage()->level()); m_data->logMessage()->level());
if (fs != nullptr) { if (fs != nullptr) {
fs->write(logLine.c_str(), static_cast<std::streamsize>(logLine.size())); fs->write(logLine.c_str(), logLine.size());
if (fs->fail()) { if (fs->fail()) {
ELPP_INTERNAL_ERROR("Unable to write log to file [" ELPP_INTERNAL_ERROR("Unable to write log to file ["
<< m_data->logMessage()->logger()->m_typedConfigurations->filename(m_data->logMessage()->level()) << "].\n" << m_data->logMessage()->logger()->m_typedConfigurations->filename(m_data->logMessage()->level()) << "].\n"
@@ -2480,7 +2483,7 @@ void LogDispatcher::dispatch(void) {
} }
#ifndef ELPP_NO_GLOBAL_LOCK #ifndef ELPP_NO_GLOBAL_LOCK
// see https://github.com/muflihun/easyloggingpp/issues/580 // see https://github.com/muflihun/easyloggingpp/issues/580
// global lock is turned off by default unless // global lock is turned on by default unless
// ELPP_NO_GLOBAL_LOCK is defined // ELPP_NO_GLOBAL_LOCK is defined
base::threading::ScopedLock scopedLock(ELPP->lock()); base::threading::ScopedLock scopedLock(ELPP->lock());
#endif #endif
@@ -2490,7 +2493,7 @@ void LogDispatcher::dispatch(void) {
} }
LogDispatchCallback* callback = nullptr; LogDispatchCallback* callback = nullptr;
LogDispatchData data; LogDispatchData data;
for (const std::pair<std::string, base::type::LogDispatchCallbackPtr>& h for (const std::pair<std::string, base::type::LogDispatchCallbackPtr> h
: ELPP->m_logDispatchCallbacks) { : ELPP->m_logDispatchCallbacks) {
callback = h.second.get(); callback = h.second.get();
if (callback != nullptr && callback->enabled()) { if (callback != nullptr && callback->enabled()) {
@@ -2505,7 +2508,7 @@ void LogDispatcher::dispatch(void) {
void MessageBuilder::initialize(Logger* logger) { void MessageBuilder::initialize(Logger* logger) {
m_logger = logger; m_logger = logger;
m_containerLogSeperator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ? m_containerLogSeparator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ?
ELPP_LITERAL("\n ") : ELPP_LITERAL(", "); ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");
} }
@@ -2541,7 +2544,7 @@ Writer& Writer::construct(int count, const char* loggerIds, ...) {
va_list loggersList; va_list loggersList;
va_start(loggersList, loggerIds); va_start(loggersList, loggerIds);
const char* id = loggerIds; const char* id = loggerIds;
m_loggerIds.reserve(static_cast<size_t>(count)); m_loggerIds.reserve(count);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
m_loggerIds.push_back(std::string(id)); m_loggerIds.push_back(std::string(id));
id = va_arg(loggersList, const char*); id = va_arg(loggersList, const char*);
@@ -2625,30 +2628,37 @@ void Writer::processDispatch() {
} }
void Writer::triggerDispatch(void) { void Writer::triggerDispatch(void) {
if (m_proceed) { try {
if (m_msg == nullptr) { if (m_proceed) {
LogMessage msg(m_level, m_file, m_line, m_func, m_verboseLevel, if (m_msg == nullptr) {
m_logger); LogMessage msg(m_level, m_file, m_line, m_func, m_verboseLevel,
base::LogDispatcher(m_proceed, &msg, m_dispatchAction).dispatch(); m_logger);
} else { base::LogDispatcher(m_proceed, &msg, m_dispatchAction).dispatch();
base::LogDispatcher(m_proceed, m_msg, m_dispatchAction).dispatch(); } else {
} base::LogDispatcher(m_proceed, m_msg, m_dispatchAction).dispatch();
} }
if (m_logger != nullptr) { }
m_logger->stream().str(ELPP_LITERAL("")); if (m_logger != nullptr) {
m_logger->releaseLock(); m_logger->stream().str(ELPP_LITERAL(""));
} m_logger->releaseLock();
if (m_proceed && m_level == Level::Fatal }
&& !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) { if (m_proceed && m_level == Level::Fatal
base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId) && !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) {
<< "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]"; base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
std::stringstream reasonStream; << "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]";
reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]" std::stringstream reasonStream;
<< " If you wish to disable 'abort on fatal log' please use " reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]"
<< "el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)"; << " If you wish to disable 'abort on fatal log' please use "
base::utils::abort(1, reasonStream.str()); << "el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)";
} base::utils::abort(1, reasonStream.str());
m_proceed = false; }
m_proceed = false;
}
catch(std::exception & ex){
// Unused variable. Errors on MSVC.
(void)ex;
// Extremely low memory situation; don't let exception be unhandled.
}
} }
// PErrorWriter // PErrorWriter
@@ -2677,7 +2687,7 @@ PerformanceTracker::PerformanceTracker(const std::string& blockName,
m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) { m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) {
#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
// We store it locally so that if user happen to change configuration by the end of scope // We store it locally so that if user happen to change configuration by the end of scope
// or before calling checkpoint, we still depend on state of configuraton at time of construction // or before calling checkpoint, we still depend on state of configuration at time of construction
el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false); el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false);
m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level); m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level);
if (m_enabled) { if (m_enabled) {
@@ -2786,7 +2796,7 @@ std::ostream& operator<<(std::ostream& os, const StackTrace& st) {
} }
void StackTrace::generateNew(void) { void StackTrace::generateNew(void) {
#if ELPP_STACKTRACE #ifdef HAVE_EXECINFO
m_stack.clear(); m_stack.clear();
void* stack[kMaxStack]; void* stack[kMaxStack];
unsigned int size = backtrace(stack, kMaxStack); unsigned int size = backtrace(stack, kMaxStack);
@@ -3005,7 +3015,7 @@ const Configurations* Loggers::defaultConfigurations(void) {
return ELPP->registeredLoggers()->defaultConfigurations(); return ELPP->registeredLoggers()->defaultConfigurations();
} }
const base::LogStreamsReferenceMap* Loggers::logStreamsReference(void) { const base::LogStreamsReferenceMapPtr Loggers::logStreamsReference(void) {
return ELPP->registeredLoggers()->logStreamsReference(); return ELPP->registeredLoggers()->logStreamsReference();
} }
+75 -59
View File
@@ -4,13 +4,13 @@
// Easylogging++ v9.96.7 // Easylogging++ v9.96.7
// Single-header only, cross-platform logging library for C++ applications // Single-header only, cross-platform logging library for C++ applications
// //
// Copyright (c) 2012-2018 Zuhd Web Services // Copyright (c) 2012-2018 Amrayn Web Services
// Copyright (c) 2012-2018 @abumusamq // Copyright (c) 2012-2018 @abumusamq
// //
// This library is released under the MIT Licence. // This library is released under the MIT Licence.
// https://github.com/zuhd-org/easyloggingpp/blob/master/LICENSE // https://github.com/amrayn/easyloggingpp/blob/master/LICENSE
// //
// https://zuhd.org // https://amrayn.com
// http://muflihun.com // http://muflihun.com
// //
@@ -119,8 +119,13 @@
#else #else
# define ELPP_OS_EMSCRIPTEN 0 # define ELPP_OS_EMSCRIPTEN 0
#endif #endif
#if (defined(__QNX__) || defined(__QNXNTO__))
# define ELPP_OS_QNX 1
#else
# define ELPP_OS_QNX 0
#endif
// Unix // Unix
#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_EMSCRIPTEN) && (!ELPP_OS_WINDOWS)) #if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_EMSCRIPTEN || ELPP_OS_QNX) && (!ELPP_OS_WINDOWS))
# define ELPP_OS_UNIX 1 # define ELPP_OS_UNIX 1
#else #else
# define ELPP_OS_UNIX 0 # define ELPP_OS_UNIX 0
@@ -205,7 +210,7 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre
# define ELPP_INTERNAL_INFO(lvl, msg) # define ELPP_INTERNAL_INFO(lvl, msg)
#endif // (defined(ELPP_DEBUG_INFO)) #endif // (defined(ELPP_DEBUG_INFO))
#if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG)) #if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_ANDROID && !ELPP_OS_EMSCRIPTEN) # if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_CYGWIN && !ELPP_OS_ANDROID && !ELPP_OS_EMSCRIPTEN && !ELPP_OS_QNX)
# define ELPP_STACKTRACE 1 # define ELPP_STACKTRACE 1
# else # else
# if ELPP_COMPILER_MSVC # if ELPP_COMPILER_MSVC
@@ -360,10 +365,10 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre
# include <codecvt> # include <codecvt>
# endif // ELPP_OS_WINDOWS # endif // ELPP_OS_WINDOWS
#endif // defined(ELPP_UNICODE) #endif // defined(ELPP_UNICODE)
#if ELPP_STACKTRACE #ifdef HAVE_EXECINFO
# include <cxxabi.h> # include <cxxabi.h>
# include <execinfo.h> # include <execinfo.h>
#endif // ELPP_STACKTRACE #endif // ENABLE_EXECINFO
#if ELPP_OS_ANDROID #if ELPP_OS_ANDROID
# include <sys/system_properties.h> # include <sys/system_properties.h>
#endif // ELPP_OS_ANDROID #endif // ELPP_OS_ANDROID
@@ -580,7 +585,7 @@ enum class Level : base::type::EnumType {
Fatal = 8, Fatal = 8,
/// @brief Information representing errors in application but application will keep running /// @brief Information representing errors in application but application will keep running
Error = 16, Error = 16,
/// @brief Useful when application has potentially harmful situtaions /// @brief Useful when application has potentially harmful situations
Warning = 32, Warning = 32,
/// @brief Information that can be highly useful and vary with verbose logging level. /// @brief Information that can be highly useful and vary with verbose logging level.
Verbose = 64, Verbose = 64,
@@ -640,7 +645,7 @@ enum class ConfigurationType : base::type::EnumType {
ToStandardOutput = 4, ToStandardOutput = 4,
/// @brief Determines format of logging corresponding level and logger. /// @brief Determines format of logging corresponding level and logger.
Format = 8, Format = 8,
/// @brief Determines log file (full path) to write logs to for correponding level and logger /// @brief Determines log file (full path) to write logs to for corresponding level and logger
Filename = 16, Filename = 16,
/// @brief Specifies precision of the subsecond part. It should be within range (1-6). /// @brief Specifies precision of the subsecond part. It should be within range (1-6).
SubsecondPrecision = 32, SubsecondPrecision = 32,
@@ -671,7 +676,7 @@ class ConfigurationTypeHelper : base::StaticClass {
static base::type::EnumType castToInt(ConfigurationType configurationType) { static base::type::EnumType castToInt(ConfigurationType configurationType) {
return static_cast<base::type::EnumType>(configurationType); return static_cast<base::type::EnumType>(configurationType);
} }
/// @brief Casts int(ushort) to configurationt type, useful for iterating through enum. /// @brief Casts int(ushort) to configuration type, useful for iterating through enum.
static ConfigurationType castFromInt(base::type::EnumType c) { static ConfigurationType castFromInt(base::type::EnumType c) {
return static_cast<ConfigurationType>(c); return static_cast<ConfigurationType>(c);
} }
@@ -700,7 +705,7 @@ enum class LoggingFlag : base::type::EnumType {
LogDetailedCrashReason = 4, LogDetailedCrashReason = 4,
/// @brief Allows to disable application abortion when logged using FATAL level /// @brief Allows to disable application abortion when logged using FATAL level
DisableApplicationAbortOnFatalLog = 8, DisableApplicationAbortOnFatalLog = 8,
/// @brief Flushes log with every log-entry (performance sensative) - Disabled by default /// @brief Flushes log with every log-entry (performance sensitive) - Disabled by default
ImmediateFlush = 16, ImmediateFlush = 16,
/// @brief Enables strict file rolling /// @brief Enables strict file rolling
StrictLogFileSizeCheck = 32, StrictLogFileSizeCheck = 32,
@@ -753,9 +758,9 @@ static const char* kSysLogLoggerId = "syslog";
#endif // defined(ELPP_SYSLOG) #endif // defined(ELPP_SYSLOG)
#if ELPP_OS_WINDOWS #if ELPP_OS_WINDOWS
static const char* kFilePathSeperator = "\\"; static const char* kFilePathSeparator = "\\";
#else #else
static const char* kFilePathSeperator = "/"; static const char* kFilePathSeparator = "/";
#endif // ELPP_OS_WINDOWS #endif // ELPP_OS_WINDOWS
static const std::size_t kSourceFilenameMaxLength = 100; static const std::size_t kSourceFilenameMaxLength = 100;
@@ -765,12 +770,12 @@ const struct {
double value; double value;
const base::type::char_t* unit; const base::type::char_t* unit;
} kTimeFormats[] = { } kTimeFormats[] = {
{ 1000.0f, ELPP_LITERAL("us") }, { 1000.0, ELPP_LITERAL("us") },
{ 1000.0f, ELPP_LITERAL("ms") }, { 1000.0, ELPP_LITERAL("ms") },
{ 60.0f, ELPP_LITERAL("seconds") }, { 60.0, ELPP_LITERAL("seconds") },
{ 60.0f, ELPP_LITERAL("minutes") }, { 60.0, ELPP_LITERAL("minutes") },
{ 24.0f, ELPP_LITERAL("hours") }, { 24.0, ELPP_LITERAL("hours") },
{ 7.0f, ELPP_LITERAL("days") } { 7.0, ELPP_LITERAL("days") }
}; };
static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]); static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]);
const struct { const struct {
@@ -786,7 +791,7 @@ const struct {
}, },
{ {
SIGFPE, "SIGFPE", "Erroneous arithmetic operation", SIGFPE, "SIGFPE", "Erroneous arithmetic operation",
"Arithemetic operation issue such as division by zero or operation resulting in overflow." "Arithmetic operation issue such as division by zero or operation resulting in overflow."
}, },
{ {
SIGILL, "SIGILL", "Illegal instruction", SIGILL, "SIGILL", "Illegal instruction",
@@ -1052,14 +1057,14 @@ class File : base::StaticClass {
static bool createPath(const std::string& path); static bool createPath(const std::string& path);
/// @brief Extracts path of filename with leading slash /// @brief Extracts path of filename with leading slash
static std::string extractPathFromFilename(const std::string& fullPath, static std::string extractPathFromFilename(const std::string& fullPath,
const char* seperator = base::consts::kFilePathSeperator); const char* separator = base::consts::kFilePathSeparator);
/// @brief builds stripped filename and puts it in buff /// @brief builds stripped filename and puts it in buff
static void buildStrippedFilename(const char* filename, char buff[], static void buildStrippedFilename(const char* filename, char buff[],
std::size_t limit = base::consts::kSourceFilenameMaxLength); std::size_t limit = base::consts::kSourceFilenameMaxLength);
/// @brief builds base filename and puts it in buff /// @brief builds base filename and puts it in buff
static void buildBaseFilename(const std::string& fullPath, char buff[], static void buildBaseFilename(const std::string& fullPath, char buff[],
std::size_t limit = base::consts::kSourceFilenameMaxLength, std::size_t limit = base::consts::kSourceFilenameMaxLength,
const char* seperator = base::consts::kFilePathSeperator); const char* separator = base::consts::kFilePathSeparator);
}; };
/// @brief String utilities helper class used internally. You should not use it. /// @brief String utilities helper class used internally. You should not use it.
class Str : base::StaticClass { class Str : base::StaticClass {
@@ -1128,7 +1133,7 @@ class Str : base::StaticClass {
static char* addToBuff(const char* str, char* buf, const char* bufLim); static char* addToBuff(const char* str, char* buf, const char* bufLim);
static char* clearBuff(char buff[], std::size_t lim); static char* clearBuff(char buff[], std::size_t lim);
/// @brief Converst wchar* to char* /// @brief Converts wchar* to char*
/// NOTE: Need to free return value after use! /// NOTE: Need to free return value after use!
static char* wcharPtrToCharPtr(const wchar_t* line); static char* wcharPtrToCharPtr(const wchar_t* line);
}; };
@@ -1169,7 +1174,7 @@ class OS : base::StaticClass {
/// @brief Gets current host name or computer name. /// @brief Gets current host name or computer name.
/// ///
/// @detail For android systems this is device name with its manufacturer and model seperated by hyphen /// @detail For android systems this is device name with its manufacturer and model separated by hyphen
static std::string currentHost(void); static std::string currentHost(void);
/// @brief Whether or not terminal supports colors /// @brief Whether or not terminal supports colors
static bool termSupportsColor(void); static bool termSupportsColor(void);
@@ -1179,7 +1184,7 @@ class DateTime : base::StaticClass {
public: public:
/// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond. /// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond.
/// ///
/// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a seperate implementation is provided /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a separate implementation is provided
/// @param [in,out] tv Pointer that gets updated /// @param [in,out] tv Pointer that gets updated
static void gettimeofday(struct timeval* tv); static void gettimeofday(struct timeval* tv);
@@ -1225,7 +1230,7 @@ class CommandLineArgs {
} }
/// @brief Sets arguments and parses them /// @brief Sets arguments and parses them
void setArgs(int argc, char** argv); void setArgs(int argc, char** argv);
/// @brief Returns true if arguments contain paramKey with a value (seperated by '=') /// @brief Returns true if arguments contain paramKey with a value (separated by '=')
bool hasParamWithValue(const char* paramKey) const; bool hasParamWithValue(const char* paramKey) const;
/// @brief Returns value of arguments /// @brief Returns value of arguments
/// @see hasParamWithValue(const char*) /// @see hasParamWithValue(const char*)
@@ -1381,7 +1386,7 @@ class Registry : public AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*
this->reinitDeepCopy(sr); this->reinitDeepCopy(sr);
} }
/// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element /// @brief Assignment operator that unregisters all the existing registries and deeply copies each of repo element
/// @see unregisterAll() /// @see unregisterAll()
/// @see deepCopy(const AbstractRegistry&) /// @see deepCopy(const AbstractRegistry&)
Registry& operator=(const Registry& sr) { Registry& operator=(const Registry& sr) {
@@ -1462,7 +1467,7 @@ class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
this->reinitDeepCopy(sr); this->reinitDeepCopy(sr);
} }
/// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element /// @brief Assignment operator that unregisters all the existing registries and deeply copies each of repo element
/// @see unregisterAll() /// @see unregisterAll()
/// @see deepCopy(const AbstractRegistry&) /// @see deepCopy(const AbstractRegistry&)
RegistryWithPred& operator=(const RegistryWithPred& sr) { RegistryWithPred& operator=(const RegistryWithPred& sr) {
@@ -1509,7 +1514,7 @@ class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
this->list().push_back(ptr); this->list().push_back(ptr);
} }
/// @brief Gets pointer from repository with speicifed arguments. Arguments are passed to predicate /// @brief Gets pointer from repository with specified arguments. Arguments are passed to predicate
/// in order to validate pointer. /// in order to validate pointer.
template <typename T, typename T2> template <typename T, typename T2>
T_Ptr* get(const T& arg1, const T2 arg2) { T_Ptr* get(const T& arg1, const T2 arg2) {
@@ -1893,6 +1898,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
namespace base { namespace base {
typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr; typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
typedef std::unordered_map<std::string, FileStreamPtr> LogStreamsReferenceMap; typedef std::unordered_map<std::string, FileStreamPtr> LogStreamsReferenceMap;
typedef std::shared_ptr<base::LogStreamsReferenceMap> LogStreamsReferenceMapPtr;
/// @brief Configurations with data types. /// @brief Configurations with data types.
/// ///
/// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations. /// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations.
@@ -1904,7 +1910,7 @@ class TypedConfigurations : public base::threading::ThreadSafe {
/// @brief Constructor to initialize (construct) the object off el::Configurations /// @brief Constructor to initialize (construct) the object off el::Configurations
/// @param configurations Configurations pointer/reference to base this typed configurations off. /// @param configurations Configurations pointer/reference to base this typed configurations off.
/// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference() /// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference()
TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference); TypedConfigurations(Configurations* configurations, LogStreamsReferenceMapPtr logStreamsReference);
TypedConfigurations(const TypedConfigurations& other); TypedConfigurations(const TypedConfigurations& other);
@@ -1939,7 +1945,7 @@ class TypedConfigurations : public base::threading::ThreadSafe {
std::unordered_map<Level, base::FileStreamPtr> m_fileStreamMap; std::unordered_map<Level, base::FileStreamPtr> m_fileStreamMap;
std::unordered_map<Level, std::size_t> m_maxLogFileSizeMap; std::unordered_map<Level, std::size_t> m_maxLogFileSizeMap;
std::unordered_map<Level, std::size_t> m_logFlushThresholdMap; std::unordered_map<Level, std::size_t> m_logFlushThresholdMap;
base::LogStreamsReferenceMap* m_logStreamsReference; LogStreamsReferenceMapPtr m_logStreamsReference = nullptr;
friend class el::Helpers; friend class el::Helpers;
friend class el::base::MessageBuilder; friend class el::base::MessageBuilder;
@@ -2207,11 +2213,11 @@ class LogBuilder : base::NoCopy {
typedef std::shared_ptr<LogBuilder> LogBuilderPtr; typedef std::shared_ptr<LogBuilder> LogBuilderPtr;
/// @brief Represents a logger holding ID and configurations we need to write logs /// @brief Represents a logger holding ID and configurations we need to write logs
/// ///
/// @detail This class does not write logs itself instead its used by writer to read configuations from. /// @detail This class does not write logs itself instead its used by writer to read configurations from.
class Logger : public base::threading::ThreadSafe, public Loggable { class Logger : public base::threading::ThreadSafe, public Loggable {
public: public:
Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference); Logger(const std::string& id, base::LogStreamsReferenceMapPtr logStreamsReference);
Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference); Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMapPtr logStreamsReference);
Logger(const Logger& logger); Logger(const Logger& logger);
Logger& operator=(const Logger& logger); Logger& operator=(const Logger& logger);
@@ -2257,7 +2263,16 @@ class Logger : public base::threading::ThreadSafe, public Loggable {
void flush(Level level, base::type::fstream_t* fs); void flush(Level level, base::type::fstream_t* fs);
inline bool isFlushNeeded(Level level) { inline bool isFlushNeeded(Level level) {
//If GCC, errors on MSVC.
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnull-dereference"
#endif
// Causes an error on GCC.
return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level); return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level);
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
} }
inline LogBuilder* logBuilder(void) const { inline LogBuilder* logBuilder(void) const {
@@ -2301,7 +2316,7 @@ inline void FUNCTION_NAME(const T&);
bool m_isConfigured; bool m_isConfigured;
Configurations m_configurations; Configurations m_configurations;
std::unordered_map<Level, unsigned int> m_unflushedCount; std::unordered_map<Level, unsigned int> m_unflushedCount;
base::LogStreamsReferenceMap* m_logStreamsReference; base::LogStreamsReferenceMapPtr m_logStreamsReference = nullptr;
LogBuilderPtr m_logBuilder; LogBuilderPtr m_logBuilder;
friend class el::LogMessage; friend class el::LogMessage;
@@ -2388,8 +2403,8 @@ class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
base::utils::Registry<Logger, std::string>::unregister(logger->id()); base::utils::Registry<Logger, std::string>::unregister(logger->id());
} }
inline base::LogStreamsReferenceMap* logStreamsReference(void) { inline LogStreamsReferenceMapPtr logStreamsReference(void) {
return &m_logStreamsReference; return m_logStreamsReference;
} }
inline void flushAll(void) { inline void flushAll(void) {
@@ -2405,7 +2420,7 @@ class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
private: private:
LogBuilderPtr m_defaultLogBuilder; LogBuilderPtr m_defaultLogBuilder;
Configurations m_defaultConfigurations; Configurations m_defaultConfigurations;
base::LogStreamsReferenceMap m_logStreamsReference; base::LogStreamsReferenceMapPtr m_logStreamsReference = nullptr;
std::unordered_map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks; std::unordered_map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks;
friend class el::base::Storage; friend class el::base::Storage;
@@ -2859,7 +2874,7 @@ class IterableStack : public IterableContainer<T, Container>, public std::stack<
// Log message builder // Log message builder
class MessageBuilder { class MessageBuilder {
public: public:
MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {} MessageBuilder(void) : m_logger(nullptr), m_containerLogSeparator(ELPP_LITERAL("")) {}
void initialize(Logger* logger); void initialize(Logger* logger);
# define ELPP_SIMPLE_LOG(LOG_TYPE)\ # define ELPP_SIMPLE_LOG(LOG_TYPE)\
@@ -3047,7 +3062,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s
m_logger->stream() << ELPP_LITERAL(", "); m_logger->stream() << ELPP_LITERAL(", ");
operator << (static_cast<V>(map_.value(*begin))); operator << (static_cast<V>(map_.value(*begin)));
m_logger->stream() << ELPP_LITERAL(")"); m_logger->stream() << ELPP_LITERAL(")");
m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeparator : ELPP_LITERAL(""));
} }
if (begin != end) { if (begin != end) {
m_logger->stream() << ELPP_LITERAL("..."); m_logger->stream() << ELPP_LITERAL("...");
@@ -3073,7 +3088,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s
m_logger->stream() << ELPP_LITERAL(", "); m_logger->stream() << ELPP_LITERAL(", ");
operator << (static_cast<V>(hash_.value(*begin))); operator << (static_cast<V>(hash_.value(*begin)));
m_logger->stream() << ELPP_LITERAL(")"); m_logger->stream() << ELPP_LITERAL(")");
m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeparator : ELPP_LITERAL(""));
} }
if (begin != end) { if (begin != end) {
m_logger->stream() << ELPP_LITERAL("..."); m_logger->stream() << ELPP_LITERAL("...");
@@ -3104,7 +3119,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s
/// have begin() and end() methods that return respective iterators /// have begin() and end() methods that return respective iterators
/// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets /// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets
/// @param SizeMethod Method used to get size of container. /// @param SizeMethod Method used to get size of container.
/// @param ElementInstance Instance of element to be fed out. Insance name is "elem". See WXELPP_ENABLED macro /// @param ElementInstance Instance of element to be fed out. Instance name is "elem". See WXELPP_ENABLED macro
/// for an example usage /// for an example usage
#define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \ #define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \
el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\ el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\
@@ -3146,14 +3161,14 @@ ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_L
#undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG #undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG
private: private:
Logger* m_logger; Logger* m_logger;
const base::type::char_t* m_containerLogSeperator; const base::type::char_t* m_containerLogSeparator;
template<class Iterator> template<class Iterator>
MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) { MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) {
m_logger->stream() << ELPP_LITERAL("["); m_logger->stream() << ELPP_LITERAL("[");
for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) { for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) {
operator << (*begin_); operator << (*begin_);
m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL("")); m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeparator : ELPP_LITERAL(""));
} }
if (begin_ != end_) { if (begin_ != end_) {
m_logger->stream() << ELPP_LITERAL("..."); m_logger->stream() << ELPP_LITERAL("...");
@@ -3260,7 +3275,7 @@ class PErrorWriter : public base::Writer {
// Logging from Logger class. Why this is here? Because we have Storage and Writer class available // Logging from Logger class. Why this is here? Because we have Storage and Writer class available
#if ELPP_VARIADIC_TEMPLATES_SUPPORTED #if ELPP_VARIADIC_TEMPLATES_SUPPORTED
template <typename T, typename... Args> template <typename T, typename... Args>
void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) { void Logger::log_(Level varlevel, int vlevel, const char* s, const T& value, const Args&... args) {
base::MessageBuilder b; base::MessageBuilder b;
b.initialize(this); b.initialize(this);
while (*s) { while (*s) {
@@ -3271,7 +3286,7 @@ void Logger::log_(Level level, int vlevel, const char* s, const T& value, const
if (*(s + 1) == base::consts::kFormatSpecifierCharValue) { if (*(s + 1) == base::consts::kFormatSpecifierCharValue) {
++s; ++s;
b << value; b << value;
log_(level, vlevel, ++s, args...); log_(varlevel, vlevel, ++s, args...);
return; return;
} }
} }
@@ -3281,28 +3296,28 @@ void Logger::log_(Level level, int vlevel, const char* s, const T& value, const
ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false); ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false);
} }
template <typename T> template <typename T>
void Logger::log_(Level level, int vlevel, const T& log) { void Logger::log_(Level varlevel, int vlevel, const T& vlog) {
if (level == Level::Verbose) { if (varlevel == Level::Verbose) {
if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) { if (ELPP->vRegistry()->allowed(static_cast<base::type::VerboseLevel>(vlevel), __FILE__)) {
base::Writer(Level::Verbose, "FILE", 0, "FUNCTION", base::Writer(Level::Verbose, "FILE", 0, "FUNCTION",
base::DispatchAction::NormalLog, vlevel).construct(this, false) << log; base::DispatchAction::NormalLog, vlevel).construct(this, false) << vlog;
} else { } else {
stream().str(ELPP_LITERAL("")); stream().str(ELPP_LITERAL(""));
releaseLock(); releaseLock();
} }
} else { } else {
base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log; base::Writer(varlevel, "FILE", 0, "FUNCTION").construct(this, false) << vlog;
} }
} }
template <typename T, typename... Args> template <typename T, typename... Args>
inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) { inline void Logger::log(Level varlevel, const char* s, const T& value, const Args&... args) {
acquireLock(); // released in Writer! acquireLock(); // released in Writer!
log_(level, 0, s, value, args...); log_(varlevel, 0, s, value, args...);
} }
template <typename T> template <typename T>
inline void Logger::log(Level level, const T& log) { inline void Logger::log(Level varlevel, const T& vlog) {
acquireLock(); // released in Writer! acquireLock(); // released in Writer!
log_(level, 0, log); log_(varlevel, 0, vlog);
} }
# if ELPP_VERBOSE_LOG # if ELPP_VERBOSE_LOG
template <typename T, typename... Args> template <typename T, typename... Args>
@@ -3311,9 +3326,9 @@ inline void Logger::verbose(int vlevel, const char* s, const T& value, const Arg
log_(el::Level::Verbose, vlevel, s, value, args...); log_(el::Level::Verbose, vlevel, s, value, args...);
} }
template <typename T> template <typename T>
inline void Logger::verbose(int vlevel, const T& log) { inline void Logger::verbose(int vlevel, const T& vlog) {
acquireLock(); // released in Writer! acquireLock(); // released in Writer!
log_(el::Level::Verbose, vlevel, log); log_(el::Level::Verbose, vlevel, vlog);
} }
# else # else
template <typename T, typename... Args> template <typename T, typename... Args>
@@ -3632,6 +3647,7 @@ class SysLogInitializer {
public: public:
SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) { SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) {
#if defined(ELPP_SYSLOG) #if defined(ELPP_SYSLOG)
(void)base::consts::kSysLogLoggerId;
openlog(processIdent, options, facility); openlog(processIdent, options, facility);
#else #else
ELPP_UNUSED(processIdent); ELPP_UNUSED(processIdent);
@@ -3824,7 +3840,7 @@ class Loggers : base::StaticClass {
/// @brief Returns current default /// @brief Returns current default
static const Configurations* defaultConfigurations(void); static const Configurations* defaultConfigurations(void);
/// @brief Returns log stream reference pointer if needed by user /// @brief Returns log stream reference pointer if needed by user
static const base::LogStreamsReferenceMap* logStreamsReference(void); static const base::LogStreamsReferenceMapPtr logStreamsReference(void);
/// @brief Default typed configuration based on existing defaultConf /// @brief Default typed configuration based on existing defaultConf
static base::TypedConfigurations defaultTypedConfigurations(void); static base::TypedConfigurations defaultTypedConfigurations(void);
/// @brief Populates all logger IDs in current repository. /// @brief Populates all logger IDs in current repository.
@@ -3835,7 +3851,7 @@ class Loggers : base::StaticClass {
/// @brief Configures loggers using command line arg. Ensure you have already set command line args, /// @brief Configures loggers using command line arg. Ensure you have already set command line args,
/// @return False if invalid argument or argument with no value provided, true if attempted to configure logger. /// @return False if invalid argument or argument with no value provided, true if attempted to configure logger.
/// If true is returned that does not mean it has been configured successfully, it only means that it /// If true is returned that does not mean it has been configured successfully, it only means that it
/// has attempeted to configure logger using configuration file provided in argument /// has attempted to configure logger using configuration file provided in argument
static bool configureFromArg(const char* argKey); static bool configureFromArg(const char* argKey);
/// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered /// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered
static void flushAll(void); static void flushAll(void);