20 #include <android/log.h> 23 #if defined(AUTO_INITIALIZE_EASYLOGGINGPP) 69 static const char*
kDays[7] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday" };
70 static const char*
kDaysAbbrev[7] = {
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat" };
71 static const char*
kMonths[12] = {
"January",
"February",
"March",
"Apri",
"May",
"June",
"July",
"August",
72 "September",
"October",
"November",
"December" 74 static const char*
kMonthsAbbrev[12] = {
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec" };
78 static const char*
kAm =
"AM";
79 static const char*
kPm =
"PM";
83 #if ELPP_VARIADIC_TEMPLATES_SUPPORTED 84 #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED 92 #if defined(ELPP_NO_DEFAULT_LOG_FILE) 95 # elif ELPP_OS_WINDOWS 96 static const char* kDefaultLogFile =
"nul";
97 # endif // ELPP_OS_UNIX 98 #elif defined(ELPP_DEFAULT_LOG_FILE) 99 static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE;
101 static const char* kDefaultLogFile =
"myeasylog.log";
102 #endif // defined(ELPP_NO_DEFAULT_LOG_FILE) 105 #if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) 107 #endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) 108 #if defined(ELPP_LOGGING_FLAGS_FROM_ARG) 109 static const char* kLoggingFlagsParam =
"--logging-flags";
110 #endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) 112 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._";
125 #if defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG) 130 #endif // defined(ELPP_COMPILER_MSVC) && defined(_M_IX86) && defined(_DEBUG) 170 for (
auto& item : stringToLevelMap) {
185 }
while (*startIndex <= lIndexMax);
223 for (
auto& item : configStringToTypeMap) {
225 return item.configType;
238 }
while (*startIndex <= cIndexMax);
245 m_configurationType(c.m_configurationType),
285 m_isFromFile(false) {
293 if (useDefaultsForRemaining) {
301 bool assertionPassed =
true;
303 "Configuration file [" << configurationFile <<
"] does not exist!");
304 if (!assertionPassed) {
321 if (base ==
nullptr || base ==
this) {
344 #if ELPP_COMPILER_INTEL 350 #endif // ELPP_COMPILER_INTEL 355 unsafeSet(level, configurationType, value);
362 if (conf ==
nullptr) {
371 #if defined(ELPP_NO_LOG_TO_FILE) 375 #endif // defined(ELPP_NO_LOG_TO_FILE) 384 std::string(
"%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg"));
394 #if defined(ELPP_NO_LOG_TO_FILE) 398 #endif // defined(ELPP_NO_LOG_TO_FILE) 406 std::string(
"%datetime %level [%logger] [%user@%host] [%func] [%loc] %msg"));
412 std::string(
"%datetime %level [%logger] [%func] [%loc] %msg"));
419 ELPP_ASSERT(fileStream_.is_open(),
"Unable to open configuration file [" << configurationFile <<
"] for parsing.");
420 bool parsedSuccessfully =
false;
425 while (fileStream_.good()) {
426 std::getline(fileStream_, line);
427 parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender);
428 ELPP_ASSERT(parsedSuccessfully,
"Unable to parse configuration line: " << line);
430 return parsedSuccessfully;
436 bool parsedSuccessfully =
false;
437 std::stringstream ss(configurationsString);
442 while (std::getline(ss, line)) {
443 parsedSuccessfully = parseLine(&line, &currConfigStr, &currLevelStr, &currLevel, sender);
444 ELPP_ASSERT(parsedSuccessfully,
"Unable to parse configuration line: " << line);
446 return parsedSuccessfully;
450 std::size_t foundAt = 0;
451 std::size_t quotesStart = line->find(
"\"");
452 std::size_t quotesEnd = std::string::npos;
453 if (quotesStart != std::string::npos) {
454 quotesEnd = line->find(
"\"", quotesStart + 1);
455 while (quotesEnd != std::string::npos && line->at(quotesEnd - 1) ==
'\\') {
457 quotesEnd = line->find(
"\"", quotesEnd + 2);
461 if (foundAt < quotesEnd) {
464 *line = line->substr(0, foundAt);
477 std::size_t assignment = line.find(
'=');
479 ((line[0] >=
'A' && line[0] <=
'Z') || (line[0] >=
'a' && line[0] <=
'z')) &&
480 (assignment != std::string::npos) &&
481 (line.size() > assignment);
490 if (isComment(*line))
return true;
491 ignoreComments(line);
497 if (isLevel(*line)) {
498 if (line->size() <= 2) {
501 *currLevelStr = line->substr(1, line->size() - 2);
507 if (isConfig(*line)) {
508 std::size_t assignment = line->find(
'=');
509 *currConfigStr = line->substr(0, assignment);
513 currValue = line->substr(assignment + 1);
515 std::size_t quotesStart = currValue.find(
"\"", 0);
516 std::size_t quotesEnd = std::string::npos;
517 if (quotesStart != std::string::npos) {
518 quotesEnd = currValue.find(
"\"", quotesStart + 1);
519 while (quotesEnd != std::string::npos && currValue.at(quotesEnd - 1) ==
'\\') {
520 currValue = currValue.erase(quotesEnd - 1, 1);
521 quotesEnd = currValue.find(
"\"", quotesEnd + 2);
524 if (quotesStart != std::string::npos && quotesEnd != std::string::npos) {
526 ELPP_ASSERT((quotesStart < quotesEnd),
"Configuration error - No ending quote found in [" 527 << currConfigStr <<
"]");
528 ELPP_ASSERT((quotesStart + 1 != quotesEnd),
"Empty configuration value for [" << currConfigStr <<
"]");
529 if ((quotesStart != quotesEnd) && (quotesStart + 1 != quotesEnd)) {
531 currValue = currValue.substr(quotesStart + 1, quotesEnd - 1);
540 conf->
set(*currLevel, currConfig, currValue);
546 if (conf ==
nullptr) {
547 unsafeSet(level, configurationType, value);
553 if (conf ==
nullptr) {
564 bool includeGlobalLevel) {
565 if (includeGlobalLevel) {
576 bool includeGlobalLevel) {
577 if (includeGlobalLevel) {
590 if (!m_termSupportsColor)
return;
593 *logLine =
ELPP_LITERAL(
"\x1b[31m") + *logLine + resetColor;
595 *logLine =
ELPP_LITERAL(
"\x1b[33m") + *logLine + resetColor;
597 *logLine =
ELPP_LITERAL(
"\x1b[32m") + *logLine + resetColor;
599 *logLine =
ELPP_LITERAL(
"\x1b[36m") + *logLine + resetColor;
601 *logLine =
ELPP_LITERAL(
"\x1b[35m") + *logLine + resetColor;
608 m_typedConfigurations(nullptr),
610 m_isConfigured(false),
611 m_logStreamsReference(logStreamsReference) {
638 if (&logger !=
this) {
652 #if ELPP_ASYNC_LOGGING 661 #endif // ELPP_ASYNC_LOGGING 689 for (std::string::const_iterator
it =
id.
begin();
it !=
id.end(); ++
it) {
713 std::unordered_map<Level, unsigned int>::iterator iter =
m_unflushedCount.find(level);
751 #if !defined(ELPP_FRESH_LOG_FILE) 752 | base::type::fstream_t::app
755 #if defined(ELPP_UNICODE) 756 std::locale elppUnicodeLocale(
"");
758 std::locale elppUnicodeLocaleWindows(elppUnicodeLocale,
new std::codecvt_utf8_utf16<wchar_t>);
759 elppUnicodeLocale = elppUnicodeLocaleWindows;
760 # endif // ELPP_OS_WINDOWS 761 fs->imbue(elppUnicodeLocale);
762 #endif // defined(ELPP_UNICODE) 778 std::size_t
size =
static_cast<std::size_t
>(fs->tellg());
782 bool File::pathExists(
const char*
path,
bool considerFile) {
783 if (path ==
nullptr) {
789 return (stat(path, &st) == 0);
790 #elif ELPP_OS_WINDOWS 791 DWORD fileType = GetFileAttributesA(path);
792 if (fileType == INVALID_FILE_ATTRIBUTES) {
795 return considerFile ?
true : ((fileType & FILE_ATTRIBUTE_DIRECTORY) == 0 ?
false :
true);
796 #endif // ELPP_OS_UNIX 808 char* currPath =
const_cast<char*
>(path.c_str());
811 if (path[0] ==
'/') {
815 #elif ELPP_OS_WINDOWS 817 char* nextTok_ =
nullptr;
820 #endif // ELPP_OS_UNIX 821 while (currPath !=
nullptr) {
822 builtPath.append(currPath);
825 status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS);
827 #elif ELPP_OS_WINDOWS 828 status = _mkdir(builtPath.c_str());
830 #endif // ELPP_OS_UNIX 840 if ((fullPath ==
"") || (fullPath.find(separator) == std::string::npos)) {
843 std::size_t lastSlashAt = fullPath.find_last_of(separator);
844 if (lastSlashAt == 0) {
847 return fullPath.substr(0, lastSlashAt + 1);
850 void File::buildStrippedFilename(
const char*
filename,
char buff[], std::size_t
limit) {
851 std::size_t sizeOfFilename = strlen(filename);
852 if (sizeOfFilename >= limit) {
853 filename += (sizeOfFilename -
limit);
854 if (filename[0] !=
'.' && filename[1] !=
'.') {
856 STRCAT(buff,
"..", limit);
859 STRCAT(buff, filename, limit);
862 void File::buildBaseFilename(
const std::string& fullPath,
char buff[], std::size_t
limit,
const char* separator) {
863 const char *
filename = fullPath.c_str();
864 std::size_t lastSlashAt = fullPath.find_last_of(separator);
865 filename += lastSlashAt ? lastSlashAt+1 : 0;
866 std::size_t sizeOfFilename = strlen(filename);
867 if (sizeOfFilename >= limit) {
868 filename += (sizeOfFilename -
limit);
869 if (filename[0] !=
'.' && filename[1] !=
'.') {
871 STRCAT(buff,
"..", limit);
874 STRCAT(buff, filename, limit);
879 bool Str::wildCardMatch(
const char*
str,
const char*
pattern) {
889 if (wildCardMatch(str, pattern + 1))
891 if (*str && wildCardMatch(str + 1, pattern))
895 if (*str++ != *pattern++)
904 str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](
char c) {
905 return !std::isspace(
c);
911 str.erase(std::find_if(str.rbegin(), str.rend(), [](
char c) {
912 return !std::isspace(
c);
913 }).base(), str.end());
918 return ltrim(rtrim(str));
922 return (str.length() >= start.length()) && (str.compare(0, start.length(),
start) == 0);
926 return (str.length() >= end.length()) && (str.compare(str.length() - end.length(), end.length(),
end) == 0);
930 std::replace(str.begin(), str.end(), replaceWhat, replaceWith);
936 if (replaceWhat == replaceWith)
938 std::size_t foundAt = std::string::npos;
939 while ((foundAt = str.find(replaceWhat, foundAt + 1)) != std::string::npos) {
940 str.replace(foundAt, replaceWhat.length(), replaceWith);
947 std::size_t foundAt = base::type::string_t::npos;
948 while ((foundAt = str.find(replaceWhat, foundAt + 1)) != base::type::string_t::npos) {
950 str.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
953 str.replace(foundAt, replaceWhat.length(), replaceWith);
958 #if defined(ELPP_UNICODE) 961 replaceFirstWithEscape(str, replaceWhat,
base::type::string_t(replaceWith.begin(), replaceWith.end()));
963 #endif // defined(ELPP_UNICODE) 968 return static_cast<char>(::toupper(
c));
973 bool Str::cStringEq(
const char*
s1,
const char* s2) {
974 if (s1 ==
nullptr && s2 ==
nullptr)
return true;
975 if (s1 ==
nullptr || s2 ==
nullptr)
return false;
976 return strcmp(s1, s2) == 0;
979 bool Str::cStringCaseEq(
const char*
s1,
const char* s2) {
980 if (s1 ==
nullptr && s2 ==
nullptr)
return true;
981 if (s1 ==
nullptr || s2 ==
nullptr)
return false;
987 const int c1 = toupper(*s1++);
988 const int c2 = toupper(*s2++);
990 if (((d = c1 - c2) != 0) || (c2 ==
'\0')) {
1006 char* Str::convertAndAddToBuff(std::size_t
n,
int len,
char*
buf,
const char* bufLim,
bool zeroPadded) {
1007 char localBuff[10] =
"";
1008 char*
p = localBuff +
sizeof(localBuff) - 2;
1010 for (; n > 0 && p > localBuff && len > 0; n /= 10, --
len)
1011 *--p = static_cast<char>(n % 10 +
'0');
1017 while (p > localBuff && len-- > 0) *--p =
static_cast<char>(
'0');
1018 return addToBuff(p, buf, bufLim);
1021 char* Str::addToBuff(
const char* str,
char*
buf,
const char* bufLim) {
1022 while ((buf < bufLim) && ((*buf = *str++) !=
'\0'))
1027 char* Str::clearBuff(
char buff[], std::size_t lim) {
1035 char* Str::wcharPtrToCharPtr(
const wchar_t*
line) {
1036 std::size_t len_ = wcslen(line) + 1;
1037 char* buff_ =
static_cast<char*
>(malloc(len_ + 1));
1038 # if ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS) 1039 std::wcstombs(buff_, line, len_);
1040 # elif ELPP_OS_WINDOWS 1041 std::size_t convCount_ = 0;
1043 ::memset(static_cast<void*>(&mbState_), 0,
sizeof(mbState_));
1044 wcsrtombs_s(&convCount_, buff_, len_, &line, len_, &mbState_);
1045 # endif // ELPP_OS_UNIX || (ELPP_OS_WINDOWS && !ELPP_CRT_DBG_WARNINGS) 1052 const char* OS::getWindowsEnvironmentVariable(
const char* varname) {
1057 const DWORD bufferLen = 50;
1058 static char buffer[bufferLen];
1059 if (GetEnvironmentVariableA(varname, buffer, bufferLen)) {
1064 #endif // ELPP_OS_WINDOWS 1067 char propVal[PROP_VALUE_MAX + 1];
1068 int ret = __system_property_get(prop, propVal);
1073 std::stringstream ss;
1074 std::string manufacturer = getProperty(
"ro.product.manufacturer");
1076 if (manufacturer.empty() || model.empty()) {
1079 ss << manufacturer <<
"-" <<
model;
1082 #endif // ELPP_OS_ANDROID 1085 #if (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN) 1086 if (command ==
nullptr) {
1089 FILE* proc =
nullptr;
1090 if ((proc = popen(command,
"r")) ==
nullptr) {
1095 if (fgets(hBuff,
sizeof(hBuff), proc) !=
nullptr) {
1097 const std::size_t buffLen = strlen(hBuff);
1098 if (buffLen > 0 && hBuff[buffLen - 1] ==
'\n') {
1099 hBuff[buffLen - 1] =
'\0';
1109 #endif // (ELPP_OS_UNIX && !ELPP_OS_ANDROID && !ELPP_CYGWIN) 1112 std::string OS::getEnvironmentVariable(
const char* variableName,
const char* defaultVal,
1113 const char* alternativeBashCommand) {
1115 const char*
val = getenv(variableName);
1116 #elif ELPP_OS_WINDOWS 1117 const char* val = getWindowsEnvironmentVariable(variableName);
1118 #endif // ELPP_OS_UNIX 1119 if ((val ==
nullptr) || ((strcmp(val,
"") == 0))) {
1120 #if ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH) 1123 if (valBash.empty()) {
1128 #elif ELPP_OS_WINDOWS || ELPP_OS_UNIX 1131 #endif // ELPP_OS_UNIX && defined(ELPP_FORCE_ENV_VAR_FROM_BASH) 1137 #if ELPP_OS_UNIX && !ELPP_OS_ANDROID 1139 #elif ELPP_OS_WINDOWS 1141 #elif ELPP_OS_ANDROID 1146 #endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID 1150 #if ELPP_OS_UNIX && !ELPP_OS_ANDROID 1152 #elif ELPP_OS_WINDOWS 1154 #elif ELPP_OS_ANDROID 1156 return getDeviceName();
1159 #endif // ELPP_OS_UNIX && !ELPP_OS_ANDROID 1162 bool OS::termSupportsColor(
void) {
1163 std::string term = getEnvironmentVariable(
"TERM",
"");
1164 return term ==
"xterm" || term ==
"xterm-color" || term ==
"xterm-256color" 1165 || term ==
"screen" || term ==
"linux" || term ==
"cygwin" 1166 || term ==
"screen-256color";
1171 void DateTime::gettimeofday(
struct timeval* tv) {
1173 if (tv !=
nullptr) {
1174 # if ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS) 1175 const unsigned __int64 delta_ = 11644473600000000Ui64;
1177 const unsigned __int64 delta_ = 11644473600000000ULL;
1178 # endif // ELPP_COMPILER_MSVC || defined(_MSC_EXTENSIONS) 1179 const double secOffSet = 0.000001;
1180 const unsigned long usecOffSet = 1000000;
1182 GetSystemTimeAsFileTime(&fileTime);
1183 unsigned __int64 present = 0;
1184 present |= fileTime.dwHighDateTime;
1185 present = present << 32;
1186 present |= fileTime.dwLowDateTime;
1190 tv->tv_sec =
static_cast<long>(present * secOffSet);
1191 tv->tv_usec =
static_cast<long>(present % usecOffSet);
1194 ::gettimeofday(tv,
nullptr);
1195 #endif // ELPP_OS_WINDOWS 1199 struct timeval currTime;
1200 gettimeofday(&currTime);
1201 return timevalToString(currTime, format, ssPrec);
1206 struct ::tm timeInfo;
1207 buildTimeInfo(&tval, &timeInfo);
1208 const int kBuffSize = 30;
1209 char buff_[kBuffSize] =
"";
1210 parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast<std::size_t>(tval.tv_usec / ssPrec->
m_offset),
1229 ss << time <<
" " <<
unit;
1233 unsigned long long DateTime::getTimeDifference(
const struct timeval& endTime,
const struct timeval& startTime,
1236 return static_cast<unsigned long long>(
static_cast<unsigned long long>(1000000 * endTime.tv_sec + endTime.tv_usec) -
1237 static_cast<unsigned long long>(1000000 * startTime.tv_sec + startTime.tv_usec));
1240 auto conv = [](
const struct timeval& tim) {
1241 return static_cast<unsigned long long>((tim.tv_sec * 1000) + (tim.tv_usec / 1000));
1243 return static_cast<unsigned long long>(conv(endTime) - conv(startTime));
1246 struct ::tm* DateTime::buildTimeInfo(
struct timeval* currTime, struct ::tm* timeInfo) {
1248 time_t rawTime = currTime->tv_sec;
1252 # if ELPP_COMPILER_MSVC 1255 # if defined(_USE_32BIT_TIME_T) 1264 time_t rawTime = currTime->tv_sec;
1265 struct tm* tmInf =
elpptime(&rawTime);
1268 # endif // ELPP_COMPILER_MSVC 1269 #endif // ELPP_OS_UNIX 1272 char* DateTime::parseFormat(
char*
buf, std::size_t bufSz,
const char*
format,
const struct tm* tInfo,
1274 const char* bufLim = buf + bufSz;
1277 switch (*++format) {
1330 if (buf == bufLim)
break;
1338 void CommandLineArgs::setArgs(
int argc,
char** argv) {
1340 m_paramsWithValue.clear();
1341 if (argc == 0 || argv ==
nullptr) {
1346 for (
int i = 1;
i < m_argc; ++
i) {
1347 const char*
v = (strstr(m_argv[
i],
"="));
1348 if (v !=
nullptr && strlen(v) > 0) {
1350 key = key.substr(0, key.find_first_of(
'='));
1351 if (hasParamWithValue(key.c_str())) {
1353 << getParamValue(key.c_str()) <<
"]");
1355 m_paramsWithValue.insert(std::make_pair(key,
std::string(v + 1)));
1359 if (hasParam(m_argv[i])) {
1368 bool CommandLineArgs::hasParamWithValue(
const char* paramKey)
const {
1369 return m_paramsWithValue.find(
std::string(paramKey)) != m_paramsWithValue.end();
1372 const char* CommandLineArgs::getParamValue(
const char* paramKey)
const {
1373 std::unordered_map<std::string, std::string>::const_iterator iter = m_paramsWithValue.find(
std::string(paramKey));
1374 return iter != m_paramsWithValue.end() ? iter->second.c_str() :
"";
1377 bool CommandLineArgs::hasParam(
const char* paramKey)
const {
1381 bool CommandLineArgs::empty(
void)
const {
1382 return m_params.empty() && m_paramsWithValue.empty();
1386 return m_params.size() + m_paramsWithValue.size();
1402 namespace threading {
1404 #if ELPP_THREADING_ENABLED 1405 # if ELPP_USE_STD_THREADING 1406 # if ELPP_ASYNC_LOGGING 1407 static void msleep(
int ms) {
1409 # if defined(ELPP_NO_SLEEP_FOR) 1412 std::this_thread::sleep_for(std::chrono::milliseconds(ms));
1413 # endif // defined(ELPP_NO_SLEEP_FOR) 1415 # endif // ELPP_ASYNC_LOGGING 1416 # endif // !ELPP_USE_STD_THREADING 1417 #endif // ELPP_THREADING_ENABLED 1451 LogFormat::LogFormat(
void) :
1457 m_currentUser(base::utils::OS::currentUser()),
1458 m_currentHost(base::utils::OS::currentHost()) {
1488 if (&logFormat !=
this) {
1513 std::size_t foundAt = base::type::string_t::npos;
1514 while ((foundAt = formatCopy.find(specifier, foundAt + 1)) != base::type::string_t::npos) {
1519 formatCopy.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
1542 std::size_t dateIndex = std::string::npos;
1547 if (dateIndex != std::string::npos) {
1561 if ((currFormat.size() >
index) && (ptr[0] ==
'{')) {
1565 std::stringstream ss;
1566 for (; *ptr; ++ptr, ++
count) {
1571 ss << static_cast<char>(*ptr);
1573 currFormat.erase(index, count);
1637 m_logStreamsReference = logStreamsReference;
1638 build(m_configurations);
1644 build(m_configurations);
1648 return getConfigByVal<bool>(
level, &m_enabledMap,
"enabled");
1652 return getConfigByVal<bool>(
level, &m_toFileMap,
"toFile");
1656 return getConfigByRef<std::string>(
level, &m_filenameMap,
"filename");
1660 return getConfigByVal<bool>(
level, &m_toStandardOutputMap,
"toStandardOutput");
1664 return getConfigByRef<base::LogFormat>(
level, &m_logFormatMap,
"logFormat");
1668 return getConfigByRef<base::SubsecondPrecision>(
level, &m_subsecondPrecisionMap,
"subsecondPrecision");
1672 return getConfigByRef<base::MillisecondsWidth>(
level, &m_subsecondPrecisionMap,
"millisecondsWidth");
1676 return getConfigByVal<bool>(
level, &m_performanceTrackingMap,
"performanceTracking");
1680 return getConfigByRef<base::FileStreamPtr>(
level, &m_fileStreamMap,
"fileStream").
get();
1684 return getConfigByVal<std::size_t>(
level, &m_maxLogFileSizeMap,
"maxLogFileSize");
1688 return getConfigByVal<std::size_t>(
level, &m_logFlushThresholdMap,
"logFlushThreshold");
1695 return (boolStr ==
"TRUE" || boolStr ==
"true" || boolStr ==
"1");
1697 std::vector<Configuration*> withFileSizeLimit;
1702 setValue(conf->
level(), getBool(conf->
value()), &m_enabledMap);
1704 setValue(conf->
level(), getBool(conf->
value()), &m_toFileMap);
1706 setValue(conf->
level(), getBool(conf->
value()), &m_toStandardOutputMap);
1722 auto v = getULong(conf->
value());
1723 setValue(conf->
level(),
static_cast<std::size_t
>(
v), &m_maxLogFileSizeMap);
1725 withFileSizeLimit.push_back(conf);
1728 setValue(conf->
level(),
static_cast<std::size_t
>(getULong(conf->
value())), &m_logFlushThresholdMap);
1738 for (std::vector<Configuration*>::iterator conf = withFileSizeLimit.begin();
1739 conf != withFileSizeLimit.end(); ++conf) {
1748 valid = !confVal.empty() && std::find_if(confVal.begin(), confVal.end(),
1751 }) == confVal.end();
1754 ELPP_ASSERT(valid,
"Configuration value not a valid integer [" << confVal <<
"]");
1757 return atol(confVal.c_str());
1762 std::size_t dateIndex = std::string::npos;
1764 if ((dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str())) != std::string::npos) {
1766 dateIndex = resultingFilename.find(dateTimeFormatSpecifierStr.c_str(), dateIndex + 1);
1768 if (dateIndex != std::string::npos) {
1769 const char* ptr = resultingFilename.c_str() + dateIndex;
1771 ptr += dateTimeFormatSpecifierStr.size();
1773 if ((resultingFilename.size() > dateIndex) && (ptr[0] ==
'{')) {
1777 std::stringstream ss;
1778 for (; *ptr; ++ptr, ++
count) {
1785 resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(),
count);
1796 return resultingFilename;
1800 std::string resolvedFilename = resolveFilename(fullFilename);
1801 if (resolvedFilename.empty()) {
1802 std::cerr <<
"Could not load empty file for logging, please re-check your configurations for level [" 1806 if (filePath.size() < resolvedFilename.size()) {
1810 base::LogStreamsReferenceMap::iterator filestreamIter = m_logStreamsReference->find(resolvedFilename);
1812 if (filestreamIter == m_logStreamsReference->end()) {
1815 m_filenameMap.insert(std::make_pair(level, resolvedFilename));
1817 m_logStreamsReference->insert(std::make_pair(resolvedFilename,
base::FileStreamPtr(m_fileStreamMap.at(level))));
1820 m_filenameMap.insert(std::make_pair(level, filestreamIter->first));
1821 m_fileStreamMap.insert(std::make_pair(level,
base::FileStreamPtr(filestreamIter->second)));
1822 fs = filestreamIter->second.get();
1824 if (fs ==
nullptr) {
1828 setValue(level,
false, &m_toFileMap);
1838 if (fs ==
nullptr) {
1841 std::size_t maxLogFileSize = unsafeGetConfigByVal(level, &m_maxLogFileSizeMap,
"maxLogFileSize");
1843 if (maxLogFileSize != 0 && currFileSize >= maxLogFileSize) {
1844 std::string fname = unsafeGetConfigByRef(level, &m_filenameMap,
"filename");
1845 ELPP_INTERNAL_INFO(1,
"Truncating log file [" << fname <<
"] as a result of configurations for level [" 1848 preRollOutCallback(fname.c_str(), currFileSize);
1860 if (counter ==
nullptr) {
1873 if (counter ==
nullptr) {
1890 if (counter ==
nullptr) {
1903 m_defaultLogBuilder(defaultLogBuilder) {
1910 if (logger_ ==
nullptr && forceCreation) {
1913 ELPP_ASSERT(validId,
"Invalid logger ID [" <<
id <<
"]. Not registering this logger.");
1920 for (
const std::pair<std::string, base::type::LoggerRegistrationCallbackPtr>&
h 1922 callback =
h.second.get();
1923 if (callback !=
nullptr && callback->
enabled()) {
1924 callback->
handle(logger_);
1937 if (logger !=
nullptr) {
1948 if (
it->second.get() ==
nullptr)
continue;
1949 it->second->flush();
1969 auto addSuffix = [](std::stringstream& ss,
const char* sfx,
const char* prev) {
1971 std::string chr(ss.str().substr(0, ss.str().size() - strlen(prev)));
1976 std::string chr(ss.str().substr(0, ss.str().size() - strlen(sfx)));
1984 addSuffix(ss,
".h",
nullptr);
1986 addSuffix(ss,
".c",
".h");
1988 addSuffix(ss,
".cpp",
".c");
1990 addSuffix(ss,
".cc",
".cpp");
1992 addSuffix(ss,
".cxx",
".cc");
1994 addSuffix(ss,
".-inl.h",
".cxx");
1996 addSuffix(ss,
".hxx",
".-inl.h");
1998 addSuffix(ss,
".hpp",
".hxx");
2000 addSuffix(ss,
".hh",
".hpp");
2005 bool isLevel =
false;
2006 std::stringstream ss;
2017 if (!ss.str().empty() && level != -1) {
2018 insert(ss, static_cast<base::type::VerboseLevel>(level));
2026 }
else if (isLevel) {
2027 if (isdigit(*modules)) {
2034 if (!ss.str().empty() && level != -1) {
2035 insert(ss, static_cast<base::type::VerboseLevel>(level));
2041 if (
m_modules.empty() || file ==
nullptr) {
2046 std::unordered_map<std::string, base::type::VerboseLevel>::iterator
it =
m_modules.begin();
2049 return vlevel <= it->second;
2060 if (commandLineArgs->
hasParam(
"-v") || commandLineArgs->
hasParam(
"--verbose") ||
2061 commandLineArgs->
hasParam(
"-V") || commandLineArgs->
hasParam(
"--VERBOSE")) {
2074 #if !defined(ELPP_DEFAULT_LOGGING_FLAGS) 2075 # define ELPP_DEFAULT_LOGGING_FLAGS 0x0 2076 #endif // !defined(ELPP_DEFAULT_LOGGING_FLAGS) 2078 #if ELPP_ASYNC_LOGGING 2086 m_vRegistry(new base::
VRegistry(0, &m_flags)),
2088 m_asyncLogWriteQueue(new base::AsyncLogQueue()),
2089 m_asyncLogReadQueue(new base::AsyncLogQueue()),
2090 m_asyncDispatchWorker(asyncDispatchWorker),
2096 m_registeredLoggers->get(
"default");
2099 m_registeredLoggers->get(
"performance");
2102 #if defined(ELPP_SYSLOG) 2104 Logger* sysLogLogger = m_registeredLoggers->get(
std::string(base::consts::kSysLogLoggerId));
2107 #endif // defined(ELPP_SYSLOG) 2109 #if ELPP_ASYNC_LOGGING 2110 installLogDispatchCallback<base::AsyncLogDispatchCallback>(
std::string(
"AsyncLogDispatchCallback"));
2113 installLogDispatchCallback<base::DefaultLogDispatchCallback>(
std::string(
"DefaultLogDispatchCallback"));
2115 #endif // ELPP_ASYNC_LOGGING 2116 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) 2117 installPerformanceTrackingCallback<base::DefaultPerformanceTrackingCallback>
2118 (
std::string(
"DefaultPerformanceTrackingCallback"));
2119 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) 2121 #if ELPP_ASYNC_LOGGING 2122 m_asyncDispatchWorker->start();
2123 #endif // ELPP_ASYNC_LOGGING 2128 #if ELPP_ASYNC_LOGGING 2130 uninstallLogDispatchCallback<base::AsyncLogDispatchCallback>(
std::string(
"AsyncLogDispatchCallback"));
2131 installLogDispatchCallback<base::DefaultLogDispatchCallback>(
std::string(
"DefaultLogDispatchCallback"));
2137 #endif // ELPP_ASYNC_LOGGING 2148 return std::find(m_customFormatSpecifiers.begin(), m_customFormatSpecifiers.end(),
2149 formatSpecifier) != m_customFormatSpecifiers.end();
2153 if (hasCustomFormatSpecifier(customFormatSpecifier.
formatSpecifier())) {
2157 m_customFormatSpecifiers.push_back(customFormatSpecifier);
2162 std::vector<CustomFormatSpecifier>::iterator
it =
std::find(m_customFormatSpecifiers.begin(),
2163 m_customFormatSpecifiers.end(), formatSpecifier);
2164 if (it != m_customFormatSpecifiers.end() && strcmp(formatSpecifier, it->formatSpecifier()) == 0) {
2165 m_customFormatSpecifiers.erase(it);
2172 m_commandLineArgs.setArgs(argc, argv);
2173 m_vRegistry->setFromArgs(commandLineArgs());
2175 #if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) 2180 registeredLoggers()->setDefaultConfigurations(c);
2182 it != registeredLoggers()->end(); ++
it) {
2183 it->second->configure(c);
2186 #endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG) 2187 #if defined(ELPP_LOGGING_FLAGS_FROM_ARG) 2188 if (m_commandLineArgs.hasParamWithValue(base::consts::kLoggingFlagsParam)) {
2189 int userInput = atoi(m_commandLineArgs.getParamValue(base::consts::kLoggingFlagsParam));
2193 base::utils::addFlag<base::type::EnumType>(
userInput, &m_flags);
2196 #endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG) 2203 #if defined(ELPP_THREAD_SAFE) 2206 auto lock = m_fileLocks.find(filename);
2207 if (
lock == m_fileLocks.end()) {
2208 m_fileLocks.emplace(std::make_pair(filename, std::unique_ptr<base::threading::Mutex>(
new base::threading::Mutex)));
2215 return *(
it->second.get());
2222 #if defined(ELPP_THREAD_SAFE) 2227 dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
2233 if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput(m_data->logMessage()->level())) {
2234 int androidLogPriority = ANDROID_LOG_FATAL;
2236 androidLogPriority = ANDROID_LOG_FATAL;
2237 else if (m_data->logMessage()->level() ==
Level::Error)
2238 androidLogPriority = ANDROID_LOG_ERROR;
2240 androidLogPriority = ANDROID_LOG_WARN;
2241 else if (m_data->logMessage()->level() ==
Level::Info)
2242 androidLogPriority = ANDROID_LOG_INFO;
2243 else if (m_data->logMessage()->level() ==
Level::Debug)
2244 androidLogPriority = ANDROID_LOG_DEBUG;
2246 androidLogPriority = ANDROID_LOG_FATAL;
2248 __android_log_print(androidLogPriority,
"librealsense",
"%s", logLine.c_str());
2253 if (m_data->logMessage()->logger()->m_typedConfigurations->toFile(m_data->logMessage()->level())) {
2255 m_data->logMessage()->level());
2256 if (fs !=
nullptr) {
2257 fs->write(logLine.c_str(), logLine.size());
2260 << m_data->logMessage()->logger()->m_typedConfigurations->filename(m_data->logMessage()->level()) <<
"].\n" 2261 <<
"Few possible reasons (could be something else):\n" <<
" * Permission denied\n" 2262 <<
" * Disk full\n" <<
" * Disk is not writable",
true);
2265 || (m_data->logMessage()->logger()->isFlushNeeded(m_data->logMessage()->level()))) {
2266 m_data->logMessage()->logger()->flush(m_data->logMessage()->level(), fs);
2271 <<
"has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: " 2272 << m_data->logMessage()->logger()->id() <<
"]",
false);
2275 if (m_data->logMessage()->logger()->m_typedConfigurations->toStandardOutput(m_data->logMessage()->level())) {
2277 m_data->logMessage()->logger()->logBuilder()->convertToColoredOutput(&logLine, m_data->logMessage()->level());
2281 #if defined(ELPP_SYSLOG) 2284 int sysLogPriority = 0;
2286 sysLogPriority = LOG_EMERG;
2287 else if (m_data->logMessage()->level() ==
Level::Error)
2291 else if (m_data->logMessage()->level() ==
Level::Info)
2293 else if (m_data->logMessage()->level() ==
Level::Debug)
2296 sysLogPriority = LOG_NOTICE;
2297 # if defined(ELPP_UNICODE) 2299 syslog(sysLogPriority,
"%s", line);
2302 syslog(sysLogPriority,
"%s", logLine.c_str());
2305 #endif // defined(ELPP_SYSLOG) 2308 #if ELPP_ASYNC_LOGGING 2319 ELPP->asyncLogWriteQueue()->push(AsyncLogItem(*(data->
logMessage()), *data, logLine));
2324 AsyncDispatchWorker::AsyncDispatchWorker() {
2325 setContinueRunning(
false);
2328 AsyncDispatchWorker::~AsyncDispatchWorker() {
2329 setContinueRunning(
false);
2331 if (m_asyncWorkerThread.joinable())
2332 m_asyncWorkerThread.join();
2339 bool AsyncDispatchWorker::clean(
void) {
2340 std::unique_lock<std::mutex> lk(_mtx);
2349 return (
ELPP &&
ELPP->asyncLogWriteQueue() &&
ELPP->asyncLogWriteQueue()->empty() &&
ELPP->asyncLogReadQueue() &&
ELPP->asyncLogReadQueue()->empty());
2352 void AsyncDispatchWorker::emptyQueue(
void) {
2353 if (
ELPP &&
ELPP->asyncLogReadQueue()) {
2354 for (
auto i=0UL;
i <
ELPP->asyncLogReadQueue()->size();
i++) {
2355 AsyncLogItem data =
ELPP->asyncLogReadQueue()->next();
2362 setContinueRunning(
true);
2368 LogMessage* logMessage = logItem->logMessage();
2377 if (fs !=
nullptr) {
2378 fs->write(logLine.c_str(), logLine.size());
2382 <<
"Few possible reasons (could be something else):\n" <<
" * Permission denied\n" 2383 <<
" * Disk full\n" <<
" * Disk is not writable",
true);
2394 <<
"has not been configured but [TO_FILE] is configured to TRUE. [Logger ID: " << logger->
id() <<
"]",
false);
2402 # if defined(ELPP_SYSLOG) 2405 int sysLogPriority = 0;
2407 sysLogPriority = LOG_EMERG;
2417 sysLogPriority = LOG_NOTICE;
2418 # if defined(ELPP_UNICODE) 2420 syslog(sysLogPriority,
"%s", line);
2423 syslog(sysLogPriority,
"%s", logLine.c_str());
2426 # endif // defined(ELPP_SYSLOG) 2434 void AsyncDispatchWorker::fetchLogQueue()
2436 if (
ELPP &&
ELPP->asyncLogWriteQueue() &&
ELPP->asyncLogWriteQueue()->size()) {
2439 ELPP->asyncLogWriteQueue()->appendTo(
ELPP->asyncLogReadQueue());
2440 ELPP->asyncLogWriteQueue()->clear();
2445 while (continueRunning()) {
2450 std::this_thread::sleep_for(std::chrono::milliseconds(5));
2454 #endif // ELPP_ASYNC_LOGGING 2463 const char* bufLim = buff +
sizeof(buff);
2523 #if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) 2526 for (std::vector<CustomFormatSpecifier>::const_iterator
it =
ELPP->customFormatSpecifiers()->begin();
2527 it !=
ELPP->customFormatSpecifiers()->end(); ++
it) {
2532 #endif // !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) 2546 #ifndef ELPP_NO_GLOBAL_LOCK 2558 for (
const std::pair<std::string, base::type::LogDispatchCallbackPtr>&
h 2559 :
ELPP->m_logDispatchCallbacks) {
2560 callback = h.second.get();
2561 if (callback !=
nullptr && callback->
enabled()) {
2578 if (msg ==
nullptr) {
2582 # if defined(ELPP_UNICODE) 2583 m_logger->stream() << msg;
2586 m_logger->stream() << buff_;
2590 m_logger->stream() <<
" ";
2598 if (!
ELPP)
return *
this;
2600 initializeLogger(logger->
id(),
false, needLock);
2601 m_messageBuilder.initialize(m_logger);
2606 if (!
ELPP)
return *
this;
2608 va_list loggersList;
2609 va_start(loggersList, loggerIds);
2610 const char*
id = loggerIds;
2611 m_loggerIds.reserve(count);
2614 id = va_arg(loggersList,
const char*);
2616 va_end(loggersList);
2617 initializeLogger(m_loggerIds.at(0));
2621 m_messageBuilder.initialize(m_logger);
2629 if (m_logger ==
nullptr) {
2637 <<
"Logger [" << loggerId <<
"] is not registered yet!";
2641 m_logger->acquireLock();
2648 m_proceed = m_logger->enabled(
m_level);
2655 #if ELPP_LOGGING_ENABLED 2657 bool firstDispatched =
false;
2662 if (firstDispatched) {
2663 m_logger->stream() << logMessage;
2665 firstDispatched =
true;
2666 if (m_loggerIds.size() > 1) {
2667 logMessage = m_logger->stream().str();
2671 }
else if (m_logger !=
nullptr) {
2673 m_logger->releaseLock();
2675 if (i + 1 < m_loggerIds.size()) {
2676 initializeLogger(m_loggerIds.at(i + 1));
2678 }
while (++i < m_loggerIds.size());
2682 }
else if (m_logger !=
nullptr) {
2684 m_logger->releaseLock();
2688 if (m_logger !=
nullptr) {
2690 m_logger->releaseLock();
2692 #endif // ELPP_LOGGING_ENABLED 2697 if (m_msg ==
nullptr) {
2705 if (m_logger !=
nullptr) {
2707 m_logger->releaseLock();
2712 <<
"Aborting application. Reason: Fatal log at [" << m_file <<
":" << m_line <<
"]";
2713 std::stringstream reasonStream;
2714 reasonStream <<
"Fatal log at [" << m_file <<
":" << m_line <<
"]" 2715 <<
" If you wish to disable 'abort on fatal log' please use " 2716 <<
"el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)";
2726 #if ELPP_COMPILER_MSVC 2728 strerror_s(buff, 256, errno);
2729 m_logger->stream() <<
": " << buff <<
" [" << errno <<
"]";
2731 m_logger->stream() <<
": " << strerror(errno) <<
" [" << errno <<
"]";
2738 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) 2740 PerformanceTracker::PerformanceTracker(
const std::string& blockName,
2744 m_blockName(blockName), m_timestampUnit(timestampUnit), m_loggerId(loggerId), m_scopedLog(scopedLog),
2745 m_level(level), m_hasChecked(
false), m_lastCheckpointId(
std::string()), m_enabled(
false) {
2746 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED 2749 el::Logger* loggerPtr =
ELPP->registeredLoggers()->get(loggerId,
false);
2754 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED 2757 PerformanceTracker::~PerformanceTracker(
void) {
2758 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED 2764 PerformanceTrackingData
data(PerformanceTrackingData::DataType::Complete);
2766 data.m_formattedTimeTaken = formattedTime;
2768 for (
const std::pair<std::string, base::type::PerformanceTrackingCallbackPtr>&
h 2769 :
ELPP->m_performanceTrackingCallbacks) {
2770 callback = h.second.get();
2771 if (callback !=
nullptr && callback->
enabled()) {
2777 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) 2782 #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED 2787 PerformanceTrackingData
data(PerformanceTrackingData::DataType::Checkpoint);
2789 data.m_checkpointId =
id;
2793 data.m_formattedTimeTaken = formattedTime;
2795 for (
const std::pair<std::string, base::type::PerformanceTrackingCallbackPtr>&
h 2796 :
ELPP->m_performanceTrackingCallbacks) {
2797 callback = h.second.get();
2798 if (callback !=
nullptr && callback->
enabled()) {
2803 m_hasChecked =
true;
2804 m_lastCheckpointId =
id;
2806 #endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED 2813 const base::type::string_t PerformanceTracker::getFormattedTimeTaken(
struct timeval startTime)
const {
2818 (m_timestampUnit)].
unit;
2822 startTime, m_timestampUnit), m_timestampUnit);
2825 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING) 2828 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) 2837 m_demangled(demang),
2842 std::ostream&
operator<<(std::ostream& ss,
const StackTrace::StackTraceEntry& si) {
2843 ss <<
"[" << si.m_index <<
"] " << si.m_location << (si.m_hex.empty() ?
"" :
"+") << si.m_hex <<
" " << si.m_addr <<
2844 (si.m_demangled.empty() ?
"" :
":") << si.m_demangled;
2848 std::ostream&
operator<<(std::ostream& os,
const StackTrace&
st) {
2849 std::vector<StackTrace::StackTraceEntry>::const_iterator
it = st.m_stack.begin();
2850 while (it != st.m_stack.end()) {
2851 os <<
" " << *it++ <<
"\n";
2856 void StackTrace::generateNew(
void) {
2859 void* stack[kMaxStack];
2860 unsigned int size = backtrace(stack, kMaxStack);
2861 char**
strings = backtrace_symbols(stack, size);
2862 if (size > kStackStart) {
2863 for (std::size_t
i = kStackStart;
i <
size; ++
i) {
2871 auto p = line.find(
"_");
2872 if (
p != std::string::npos) {
2873 mangName = line.substr(
p);
2874 mangName = mangName.substr(0, mangName.find(
" +"));
2876 p = line.find(
"0x");
2877 if (
p != std::string::npos) {
2878 addr = line.substr(
p);
2879 addr = addr.substr(0, addr.find(
"_"));
2882 if (!mangName.empty()) {
2884 char* demangName = abi::__cxa_demangle(mangName.data(), 0, 0, &
status);
2888 StackTraceEntry
entry(i - 1, location, demangName, hex, addr);
2889 m_stack.push_back(entry);
2892 StackTraceEntry
entry(i - 1, location, mangName, hex, addr);
2893 m_stack.push_back(entry);
2897 StackTraceEntry
entry(i - 1, line);
2898 m_stack.push_back(entry);
2905 #endif // ELPP_STACKTRACE 2911 std::stringstream ss;
2912 bool foundReason =
false;
2925 ss <<
"Application has crashed due to unknown signal [" << sig <<
"]";
2930 static void logCrashReason(
int sig,
bool stackTraceIfAvailable,
Level level,
const char* logger) {
2934 std::stringstream ss;
2935 ss <<
"CRASH HANDLED; ";
2936 ss << crashReason(sig);
2938 if (stackTraceIfAvailable) {
2939 ss << std::endl <<
" ======= Backtrace: =========" << std::endl << base::debug::StackTrace();
2943 #endif // ELPP_STACKTRACE 2947 static inline void crashAbort(
int sig) {
2954 static inline void defaultCrashHandler(
int sig) {
2956 base::debug::crashAbort(sig);
2963 setHandler(defaultCrashHandler);
2967 void CrashHandler::setHandler(
const Handler& cHandler) {
2968 m_handler = cHandler;
2969 #if defined(ELPP_HANDLE_SIGABRT) 2973 #endif // defined(ELPP_HANDLE_SIGABRT) 2979 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) 2987 #if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) 2989 void Helpers::crashAbort(
int sig,
const char* sourceFile,
unsigned int long line) {
2990 std::stringstream ss;
2991 ss << base::debug::crashReason(sig).c_str();
2992 ss <<
" - [Called el::Helpers::crashAbort(" << sig <<
")]";
2993 if (sourceFile !=
nullptr && strlen(sourceFile) > 0) {
2994 ss <<
" - Source: " << sourceFile;
2998 ss <<
" (line number not specified)";
3003 void Helpers::logCrashReason(
int sig,
bool stackTraceIfAvailable,
Level level,
const char* logger) {
3004 el::base::debug::logCrashReason(sig, stackTraceIfAvailable, level, logger);
3007 #endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_CRASH_LOG) 3012 return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable);
3016 ELPP->registeredLoggers()->setDefaultLogBuilder(logBuilderPtr);
3020 return ELPP->registeredLoggers()->remove(identity);
3024 return ELPP->registeredLoggers()->has(identity);
3028 if (!logger)
return nullptr;
3040 if (logger ==
nullptr) {
3050 it !=
ELPP->registeredLoggers()->end(); ++
it) {
3058 it !=
ELPP->registeredLoggers()->end(); ++
it) {
3066 ELPP->registeredLoggers()->setDefaultConfigurations(configurations);
3067 if (reconfigureExistingLoggers) {
3073 return ELPP->registeredLoggers()->defaultConfigurations();
3077 return ELPP->registeredLoggers()->logStreamsReference();
3082 ELPP->registeredLoggers()->defaultConfigurations(),
3083 ELPP->registeredLoggers()->logStreamsReference());
3087 targetList->clear();
3089 it !=
ELPP->registeredLoggers()->list().end(); ++
it) {
3090 targetList->push_back(
it->first);
3097 ELPP_ASSERT(gcfStream.is_open(),
"Unable to open global configuration file [" << globalConfigurationFilePath
3098 <<
"] for parsing.");
3100 std::stringstream ss;
3101 Logger* logger =
nullptr;
3102 auto configure = [&](
void) {
3103 ELPP_INTERNAL_INFO(8,
"Configuring logger: '" << logger->
id() <<
"' with configurations \n" << ss.str()
3104 <<
"\n--------------");
3106 c.parseFromText(ss.str());
3109 while (gcfStream.good()) {
3110 std::getline(gcfStream, line);
3117 if (!ss.str().empty() && logger !=
nullptr) {
3121 line = line.substr(2);
3123 if (line.size() > 1) {
3125 logger = getLogger(line);
3131 if (!ss.str().empty() && logger !=
nullptr) {
3137 #if defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS) 3144 #endif // defined(ELPP_DISABLE_CONFIGURATION_FROM_PROGRAM_ARGS) 3149 #if ELPP_ASYNC_LOGGING 3150 ELPP->asyncDispatchWorker()->clean();
3152 ELPP->registeredLoggers()->flushAll();
3156 ELPP->vRegistry()->setLevel(level);
3160 return ELPP->vRegistry()->level();
3164 if (
ELPP->vRegistry()->vModulesEnabled()) {
3165 ELPP->vRegistry()->setModules(modules);
3170 ELPP->vRegistry()->clearModules();
void convertToColoredOutput(base::type::string_t *logLine, Level level)
static void buildBaseFilename(const std::string &fullPath, char buff[], std::size_t limit=base::consts::kSourceFilenameMaxLength, const char *seperator=base::consts::kFilePathSeperator)
builds base filename and puts it in buff
static const textual_icon lock
const base::type::string_t & message(void) const
static const base::type::EnumType kMinValid
Represents minimum valid level. Useful when iterating through enum.
std::shared_ptr< base::type::fstream_t > FileStreamPtr
Specifies precision of the subsecond part. It should be within range (1-6).
const std::string & configurationFile(void) const
Gets configuration file used in parsing this configurations.
static bool hasLogger(const std::string &identity)
Whether or not logger with id is registered.
bool validateNTimes(const char *filename, base::type::LineNumber lineNumber, std::size_t n)
Validates counter for hits are <= n, i.e, registers new if does not exist otherwise updates original ...
void flush(void)
Flushes logger to sync all log files for all levels.
void setModules(const char *modules)
const std::string & value(void) const
Gets string based configuration value.
static const char * kDefaultDateTimeFormat
bool validateEveryN(const char *filename, base::type::LineNumber lineNumber, std::size_t n)
Validates counter for every N, i.e, registers new if does not exist otherwise updates original one...
Determines whether or not corresponding level and logger of logging is enabled You may disable all lo...
Mutex wrapper used when multi-threading is disabled.
const base::LogFormat & logFormat(Level level)
static Logger * reconfigureLogger(Logger *logger, const Configurations &configurations)
Reconfigures specified logger with new configurations.
Configuration(const Configuration &c)
virtual base::type::string_t build(const LogMessage *logMessage, bool appendNewLine) const =0
typedef void(APIENTRY *GLDEBUGPROC)(GLenum source
Determines whether or not performance tracking is enabled.
static const char * convertToString(ConfigurationType configurationType)
Converts configuration type to associated const char*.
bool hasParamWithValue(const char *paramKey) const
Returns true if arguments contain paramKey with a value (seperated by '=')
Creates logger automatically when not available.
static std::vector< std::string > * populateAllLoggerIds(std::vector< std::string > *targetList)
Populates all logger IDs in current repository.
unsigned long getULong(std::string confVal)
static const char * kFilePathSeperator
bool hasParam(const char *paramKey) const
Return true if arguments has a param (not having a value) i,e without '='.
const std::string & filename(Level level)
static std::string extractPathFromFilename(const std::string &fullPath, const char *seperator=base::consts::kFilePathSeperator)
Extracts path of filename with leading slash.
std::vector< Configuration * >::const_iterator const_iterator
Information representing errors in application but application will keep running. ...
base::threading::Mutex & fileHandle(const LogDispatchData *data)
void dispatch(base::type::string_t &&logLine)
const std::unordered_map< std::string, base::type::VerboseLevel > & modules(void) const
virtual void handle(const LogDispatchData *data)
T_Ptr * get(const T_Key &uniqKey)
Gets pointer from repository. If none found, nullptr is returned.
static const base::type::char_t * kCurrentUserFormatSpecifier
static const char * kValidLoggerIdSymbols
static const base::type::EnumType kMaxValid
Represents maximum valid configuration type. This is used internally and you should not need it...
static void setDefaultLogBuilder(el::LogBuilderPtr &logBuilderPtr)
Changes default log builder for future loggers.
static const base::type::char_t * kFatalLevelShortLogValue
static base::type::EnumType castToInt(Level level)
Casts level to int, useful for iterating through enum.
std::size_t hitCounts(void) const
bool allowed(base::type::VerboseLevel vlevel, const char *file)
GLuint64 GLenum void * handle
static bool pathExists(const char *path, bool considerFile=false)
Determines whether or not provided path exist in current file system.
static const base::type::char_t * kTraceLevelLogValue
static const base::type::char_t * kAppNameFormatSpecifier
GLsizei const GLchar *const * path
void build(Configurations *configurations)
static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit)
Formats time to get unit accordingly, units like second if > 1000 or minutes if > 60000 etc...
Predicate(Level level, ConfigurationType configurationType)
Used to find configuration from configuration (pointers) repository. Avoid using it.
static char * convertAndAddToBuff(std::size_t n, int len, char *buf, const char *bufLim, bool zeroPadded=true)
const char * configString
static bool createPath(const std::string &path)
Creates specified path on file system.
static void setVerboseLevel(base::type::VerboseLevel level)
Sets verbose level on the fly.
Informational events most useful for developers to debug application.
base::type::VerboseLevel m_level
void set(Level level, ConfigurationType configurationType, const std::string &value)
Sets value of configuration for specified level.
const base::MillisecondsWidth & millisecondsWidth(Level level=Level::Global)
Represents unknown configuration.
Severe error information that will presumably abort application.
Main entry point of each logging.
static const char * kMonthsAbbrev[12]
ConfigurationType m_configurationType
static Level castFromInt(base::type::EnumType l)
Casts int(ushort) to level, useful for iterating through enum.
bool parseFromFile(const std::string &configurationFile, Configurations *base=nullptr)
Parses configuration from file.
void insertFile(Level level, const std::string &fullFilename)
ConfigurationType m_configurationType
static void setDefaultConfigurations(const Configurations &configurations, bool reconfigureExistingLoggers=false)
Sets default configurations. This configuration is used for future (and conditionally for existing) l...
void setGlobally(ConfigurationType configurationType, const std::string &value)
Sets configuration for all levels.
base::type::fstream_t * fileStream(Level level)
bool remove(const std::string &id)
Easylogging++ entry namespace.
Makes sure we have new line for each container log entry.
static const base::type::char_t * kTraceLevelShortLogValue
unsigned long int LineNumber
GLsizei const GLchar *const * string
static std::string getCurrentThreadId(void)
base::DispatchAction dispatchAction(void) const
static const char * kNullPointer
static bool isComment(const std::string &line)
const struct el::base::consts::@14 kCrashSignals[]
#define ELPP_INTERNAL_INFO(lvl, msg)
static char * clearBuff(char buff[], std::size_t lim)
static const char * convertToString(Level level)
Converts level to associated const char*.
virtual void registerNew(Configuration *ptr) ELPP_FINAL
static const char * kDefaultLogFile
virtual iterator end(void) ELPP_FINAL
GLfloat GLfloat GLfloat GLfloat h
Represents unknown level.
static const base::type::char_t * kInfoLevelLogValue
bool toStandardOutput(Level level)
Level
Represents enumeration for severity level used to determine level of logging.
static char * wcharPtrToCharPtr(const wchar_t *line)
Converst wchar* to char* NOTE: Need to free return value after use!
static const base::type::char_t * kVerboseLevelShortLogValue
static char * addToBuff(const char *str, char *buf, const char *bufLim)
static const base::type::char_t * kVerboseLevelLogValue
bool uninstallCustomFormatSpecifier(const char *formatSpecifier)
static std::size_t getSizeOfFile(base::type::fstream_t *fs)
Gets size of file provided in stream.
const LogMessage * logMessage(void) const
FormatFlags
Format flags used to determine specifiers that are active for performance improvements.
LogBuilderPtr m_logBuilder
status
Defines return codes that SDK interfaces use. Negative values indicate errors, a zero value indicates...
static void setVModules(const char *modules)
Sets vmodules as specified (on the fly)
Determines log file (full path) to write logs to for correponding level and logger.
base::TypedConfigurations * m_typedConfigurations
void installCustomFormatSpecifier(const CustomFormatSpecifier &customFormatSpecifier)
GLenum GLuint GLenum GLsizei const GLchar * buf
std::unordered_map< std::string, Logger * >::iterator iterator
static const unsigned int kDefaultSubsecondPrecision
static const char * kDefaultDateTimeFormatInFilename
static const base::type::char_t * kLogLocationFormatSpecifier
#define ELPP_INTERNAL_ERROR(msg, pe)
void setFromArgs(const base::utils::CommandLineArgs *commandLineArgs)
Adds spaces b/w logs that separated by left-shift operator.
static const base::type::char_t * kSeverityLevelShortFormatSpecifier
bool hasConfiguration(ConfigurationType configurationType)
Determines whether or not specified configuration type exists in the repository.
static void defaultPreRollOutCallback(const char *, std::size_t)
static const int kCrashSignalsCount
const struct el::base::consts::@13 kTimeFormats[]
Makes sure if -vmodule is used and does not specifies a module, then verbose logging is allowed via t...
void initialize(Logger *logger)
ConfigurationType configType
Information that can be highly useful and vary with verbose logging level.
static const char * kUnknownHost
void setDispatchAction(base::DispatchAction dispatchAction)
Determines format of logging corresponding level and logger.
RegisteredLoggers(const LogBuilderPtr &defaultLogBuilder)
Disable VModules extensions.
LogBuilderPtr m_defaultLogBuilder
static std::string & replaceAll(std::string &str, char replaceWhat, char replaceWith)
Replaces all instances of replaceWhat with 'replaceWith'. Original variable is changed for performanc...
bool contains(const std::shared_ptr< librealsense::device_info > &first, const std::shared_ptr< librealsense::device_info > &second)
#define STRCPY(a, b, len)
static bool contains(const char *str, char c)
Returns true if c exist in str.
const base::SubsecondPrecision & subsecondPrecision(Level level=Level::Global)
friend el::base::type::ostream_t & operator<<(el::base::type::ostream_t &os, const Loggable &loggable)
static base::TypedConfigurations defaultTypedConfigurations(void)
Default typed configuration based on existing defaultConf.
bool parseFromText(const std::string &configurationsString, Configurations *base=nullptr)
Parse configurations from configuration string.
#define INITIALIZE_EASYLOGGINGPP
base::TypedConfigurations * typedConfigurations(void)
static bool isValidId(const std::string &id)
static std::enable_if< std::is_pointer< T * >::value, void >::type safeDelete(T *&pointer)
Deletes memory safely and points to null.
std::unordered_map< Level, unsigned int > m_unflushedCount
static std::string & trim(std::string &str)
void initUnflushedCount(void)
TypedConfigurations(Configurations *configurations, base::LogStreamsReferenceMap *logStreamsReference)
Constructor to initialize (construct) the object off el::Configurations.
static const base::type::char_t * kWarningLevelShortLogValue
static struct StringToLevelItem stringToLevelMap[]
std::unordered_map< std::string, FileStreamPtr > LogStreamsReferenceMap
bool hasCustomFormatSpecifier(const char *formatSpecifier)
std::string resolveFilename(const std::string &filename)
#define STRCAT(a, b, len)
static void forEachLevel(base::type::EnumType *startIndex, const std::function< bool(void)> &fn)
Applies specified function to each level starting from startIndex.
static bool cStringCaseEq(const char *s1, const char *s2)
Compares cstring equality (case-insensitive) - uses toupper(char) Dont use strcasecmp because of CRT ...
base::LogStreamsReferenceMap m_logStreamsReference
virtual void handle(const T *handlePtr)=0
static bool isConfig(const std::string &line)
Preserves time format and does not convert it to sec, hour etc (performance tracking only) ...
void initializeLogger(const std::string &loggerId, bool lookup=true, bool needLock=true)
base::LogStreamsReferenceMap * m_logStreamsReference
bool validateFileRolling(Level level, const PreRollOutCallback &preRollOutCallback)
static const char * kDefaultLoggerId
void setLevel(base::type::VerboseLevel level)
Sets verbose level. Accepted range is 0-9.
bool isFlushNeeded(Level level)
static void forEachConfigType(base::type::EnumType *startIndex, const std::function< bool(void)> &fn)
Applies specified function to each configuration type starting from startIndex.
static ConfigurationType convertFromString(const char *configStr)
Converts from configStr to ConfigurationType.
GLint GLint GLsizei GLint GLenum format
void unsafeSet(Level level, ConfigurationType configurationType, const std::string &value)
Thread unsafe set.
static void addFlag(Enum e, base::type::EnumType *flag)
static const base::type::char_t * kLoggerIdFormatSpecifier
Logger * get(const std::string &id, bool forceCreation=true)
def run(include_folder_path, addon_folder_path)
std::string trim(std::string const &str)
Returns a new string without whitespace at the start/end.
Storage(const LogBuilderPtr &defaultLogBuilder)
bool endsWith(std::string const &s, std::string const &suffix)
static std::string & toUpper(std::string &str)
Converts string to uppercase.
static bool isDigit(char c)
Checks if character is digit. Dont use libc implementation of it to prevent locale issues...
void performConfig(const Configurations &configurations)
static const char * kPerformanceLoggerId
void reconfigure(void)
Reconfigures logger using existing configurations.
static const std::string releaseDate(void)
Release date of current version.
unsigned short VerboseLevel
void unregister(Logger *&logger)
static void flushAll(void)
Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered...
static const std::size_t kSourceFilenameMaxLength
static void abort(int status, const std::string &reason)
Aborts application due with user-defined status.
static void reconfigureAllLoggers(const Configurations &configurations)
Reconfigures all the existing loggers with new configurations.
static bool hasFlag(Enum e, base::type::EnumType flag)
Configurations(void)
Default constructor with empty repository.
static const base::type::char_t * kLogFunctionFormatSpecifier
base::type::ostream_t & operator<<(base::type::ostream_t &os, const CommandLineArgs &c)
void unsafeSetGlobally(ConfigurationType configurationType, const std::string &value, bool includeGlobalLevel)
Sets configurations (Unsafely) for all levels including Level::Global if includeGlobalLevel is true...
BOOST_DEDUCED_TYPENAME optional< T >::reference_const_type get(optional< T > const &opt)
static const char * kDateTimeFormatSpecifierForFilename
const std::string & parentApplicationName(void) const
bool unsafeValidateFileRolling(Level level, const PreRollOutCallback &preRollOutCallback)
Configurations with data types.
bool performanceTracking(Level level=Level::Global)
base::type::VerboseLevel verboseLevel(void) const
#define ELPP_ASYNC_LOGGING
Configurations * m_configurations
static const base::type::char_t * kLogFileFormatSpecifier
static const base::type::char_t * kLogLineFormatSpecifier
const base::type::char_t * unit
std::shared_ptr< LogBuilder > LogBuilderPtr
static const char * kDefaultLogFileParam
Alias of SubsecondPrecision (for backward compatibility)
Make terminal output colorful for supported terminals.
#define ELPP_LITERAL(txt)
Repository for hit counters used across the application.
Configurations m_defaultConfigurations
static void replaceFirstWithEscape(base::type::string_t &str, const base::type::string_t &replaceWhat, const base::type::string_t &replaceWith)
static const int kTimeFormatsCount
ConfigurationType configurationType(void) const
Gets configuration type of current configuration.
static void configureFromGlobal(const char *globalConfigurationFilePath)
Sets configurations from global configuration file.
static const std::string getBashOutput(const char *command)
Runs command on terminal and returns the output.
GLsizei const GLchar *const * strings
void validateHitCounts(std::size_t n)
Validates hit counts and resets it if necessary.
Useful when application has potentially harmful situtaions.
static const char * kDays[7]
void handle(const LogDispatchData *data)
static bool wildCardMatch(const char *str, const char *pattern)
Matches wildcards, '*' and '?' only supported.
When handling crashes by default, detailed crash reason will be logged as well.
Enables strict file rolling.
std::size_t maxLogFileSize(Level level)
static const base::type::char_t * kSeverityLevelFormatSpecifier
void unsafeFlushAll(void)
void setApplicationArguments(int argc, char **argv)
std::string m_parentApplicationName
void setRemainingToDefault(void)
Lets you set the remaining configurations to default.
virtual Container & list(void) ELPP_FINAL
Returns underlying container by reference.
LONG WINAPI CrashHandler(EXCEPTION_POINTERS *ep)
static const base::type::char_t * kErrorLevelLogValue
Level level(void) const
Gets level of current configuration.
MessageBuilder & operator<<(const std::string &msg)
static const base::type::char_t * kInfoLevelShortLogValue
Writer & construct(Logger *logger, bool needLock=true)
static const char * kConfigurationComment
LogBuilder * logBuilder(void) const
Flushes log with every log-entry (performance sensative) - Disabled by default.
const Configurations * configurations(void) const
void resolveLoggerFormatSpec(void) const
static bool unregisterLogger(const std::string &identity)
Unregisters logger - use it only when you know what you are doing, you may unregister loggers initial...
void configure(const Configurations &configurations)
Configures the logger using specified configurations.
LOG_INFO("Log message using LOG_INFO()")
Thread-safe Configuration repository.
Mainly useful to represent current progress of application.
void setValue(const std::string &value)
Set string based configuration value.
static const base::type::char_t * kFatalLevelLogValue
bool enabled(Level level)
static const base::LogStreamsReferenceMap * logStreamsReference(void)
Returns log stream reference pointer if needed by user.
static const base::type::char_t * kDebugLevelShortLogValue
static bool parseFromText(const std::string &configurationsString, Configurations *sender, Configurations *base=nullptr)
Parse configurations from configuration string.
std::function< void(const char *, std::size_t)> PreRollOutCallback
static bool parseFromFile(const std::string &configurationFile, Configurations *sender, Configurations *base=nullptr)
Parses configuration from file.
virtual ~PErrorWriter(void)
Configurations * configurations(void)
static const std::string version(void)
Current version number.
TimestampUnit
Enum to represent timestamp unit.
Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGI...
void triggerDispatch(void)
static bool endsWith(const std::string &str, const std::string &end)
Determines whether or not str ends with specified string.
const char * getParamValue(const char *paramKey) const
Returns value of arguments.
static const char kFormatSpecifierChar
static const base::type::char_t * kVerboseLevelFormatSpecifier
static const base::type::VerboseLevel kMaxVerboseLevel
Specifies number of log entries to hold until we flush pending log data.
static bool parseLine(std::string *line, std::string *currConfigStr, std::string *currLevelStr, Level *currLevel, Configurations *conf)
std::string m_configurationFile
static bool configureFromArg(const char *argKey)
Configures loggers using command line arg. Ensure you have already set command line args...
std::unordered_map< std::string, base::type::LoggerRegistrationCallbackPtr > m_loggerRegistrationCallbacks
static const base::type::char_t * kDateTimeFormatSpecifier
static void validateFileRolling(Logger *logger, Level level)
Configurations m_configurations
static Logger * getLogger(const std::string &identity, bool registerIfNotAvailable=true)
Gets existing or registers new logger.
static void gettimeofday(struct timeval *tv)
Cross platform gettimeofday for Windows and unix platform. This can be used to determine current micr...
static const base::type::char_t * kDebugLevelLogValue
static const base::type::char_t * kErrorLevelShortLogValue
static const el::base::utils::CommandLineArgs * commandLineArgs(void)
Returns command line arguments (pointer) provided to easylogging++.
bool vModulesEnabled(void)
Whether or not vModules enabled.
void setFromBase(Configurations *base)
Sets configuration based-off an existing configurations.
A subsecond precision class containing actual width and offset of the subsecond part.
static const int kYearBase
static const base::type::char_t * kMessageFormatSpecifier
static void buildStrippedFilename(const char *filename, char buff[], std::size_t limit=base::consts::kSourceFilenameMaxLength)
builds stripped filename and puts it in buff
const std::string & func(void) const
static const base::type::char_t * kCurrentHostFormatSpecifier
virtual iterator begin(void) ELPP_FINAL
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
Configuration & operator=(const Configuration &c)
#define ELPP_WRITE_LOG(writer, level, dispatchAction,...)
static const std::size_t kSourceLineMaxLength
void unsafeSetIfNotExist(Level level, ConfigurationType configurationType, const std::string &value)
Unsafely sets configuration if does not already exist.
std::unordered_map< std::string, base::type::VerboseLevel > m_modules
#define ELPP_ASSERT(expr, msg)
base::type::VerboseLevel level(void) const
static const base::type::char_t * kLogFileBaseFormatSpecifier
VRegistry(base::type::VerboseLevel level, base::type::EnumType *pFlags)
base::type::LineNumber line(void) const
Logger & operator=(const Logger &logger)
static const char * kConfigurationLoggerId
Generic level that represents all the levels. Useful when setting global configuration for all levels...
virtual void registerNew(const std::string &uniqKey, Logger *ptr) ELPP_FINAL
Registers new registry to repository.
static void ignoreComments(std::string *line)
static const char * kMonths[12]
Whether or not to write corresponding log to log file.
static const Configurations * defaultConfigurations(void)
Returns current default.
Represents single configuration that has representing level, configuration type and a string based va...
static const char * kDaysAbbrev[7]
void setLogMessage(LogMessage *logMessage)
static std::string getDateTime(const char *format, const base::SubsecondPrecision *ssPrec)
Gets current date and time with a subsecond part.
static bool isLevel(const std::string &line)
static base::type::fstream_t * newFileStream(const std::string &filename)
Creates new out file stream for specified filename.
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Whether or not to write corresponding level and logger log to standard output. By standard output mea...
Class that keeps record of current line hit for occasional logging.
GLuint GLenum GLenum transform
Represents a logger holding ID and configurations we need to write logs.
ConfigurationType
Represents enumeration of ConfigurationType used to configure or access certain aspect of logging...
base::type::string_t build(const LogMessage *logMessage, bool appendNewLine) const
#define ELPP_COUT_LINE(logLine)
Logger * logger(void) const
static const base::type::char_t * kWarningLevelLogValue
static const base::type::EnumType kMaxValid
Represents maximum valid level. This is used internally and you should not need it.
Lock guard wrapper used when multi-threading is disabled.
static Level convertFromString(const char *levelStr)
Converts from levelStr to Level.
std::stringstream stringstream_t
static bool startsWith(const std::string &str, const std::string &start)
Determines whether or not str starts with specified string.
const std::string & file(void) const
const std::string & id(void) const
base::LogStreamsReferenceMap * m_logStreamsReference
bool validateAfterN(const char *filename, base::type::LineNumber lineNumber, std::size_t n)
Validates counter for hits >= N, i.e, registers new if does not exist otherwise updates original one...
static const char * kUnknownUser
Enables hierarchical logging.
virtual void log(el::base::type::ostream_t &os) const
static struct ConfigurationStringToTypeItem configStringToTypeMap[]
Supports use of multiple logging in same macro, e.g, CLOG(INFO, "default", "network") ...
#define ELPP_DEFAULT_LOGGING_FLAGS
std::size_t logFlushThreshold(Level level)
static const char * kConfigurationLevel
bool operator()(const Configuration *conf) const
static const base::type::char_t * kThreadIdFormatSpecifier
static void clearVModules(void)
Clears vmodules.
Information that can be useful to back-trace certain events - mostly useful than debug logs...
virtual base::threading::Mutex & lock(void) ELPP_FINAL
Specifies log file max size.
static unsigned long long getTimeDifference(const struct timeval &endTime, const struct timeval &startTime, base::TimestampUnit timestampUnit)
Gets time difference in milli/micro second depending on timestampUnit.
Represents registries for verbose logging.
void setToDefault(void)
Sets configurations to "factory based" configurations.
static base::type::VerboseLevel verboseLevel(void)
Gets current verbose level.
base::type::EnumType * m_pFlags
bool startsWith(std::string const &s, std::string const &prefix)
Easylogging++ management storage.
Allows to disable application abortion when logged using FATAL level.