Use fmt::localtime instead of std one for thread safety

This commit is contained in:
Alexey Rybalchenko 2019-08-20 17:29:50 +02:00
parent 0b8936aeaf
commit f91643b9fa
2 changed files with 18 additions and 28 deletions

View File

@ -7,9 +7,9 @@
********************************************************************************/ ********************************************************************************/
#include "Logger.h" #include "Logger.h"
#include <fmt/time.h>
#include <cstdio> // printf #include <cstdio> // printf
#include <ctime> // strftime
#include <iomanip> // setw, setfill
#include <iostream> #include <iostream>
using namespace std; using namespace std;
@ -172,15 +172,15 @@ const array<string, 9> Logger::fVerbosityNames =
map<Verbosity, VerbositySpec> Logger::fVerbosities = map<Verbosity, VerbositySpec> Logger::fVerbosities =
{ {
{ Verbosity::verylow, VerbositySpec::Make() }, { Verbosity::verylow, VerbositySpec::Make() },
{ Verbosity::low, VerbositySpec::Make(VerbositySpec::Info::severity) }, { Verbosity::low, VerbositySpec::Make(VerbositySpec::Info::severity) },
{ Verbosity::medium, VerbositySpec::Make(VerbositySpec::Info::timestamp_s, VerbositySpec::Info::severity) }, { Verbosity::medium, VerbositySpec::Make(VerbositySpec::Info::timestamp_s, VerbositySpec::Info::severity) },
{ Verbosity::high, VerbositySpec::Make(VerbositySpec::Info::process_name, VerbositySpec::Info::timestamp_s, VerbositySpec::Info::severity) }, { Verbosity::high, VerbositySpec::Make(VerbositySpec::Info::process_name, VerbositySpec::Info::timestamp_s, VerbositySpec::Info::severity) },
{ Verbosity::veryhigh, VerbositySpec::Make(VerbositySpec::Info::process_name, VerbositySpec::Info::timestamp_s, VerbositySpec::Info::severity, VerbositySpec::Info::file_line_function) }, { Verbosity::veryhigh, VerbositySpec::Make(VerbositySpec::Info::process_name, VerbositySpec::Info::timestamp_us, VerbositySpec::Info::severity, VerbositySpec::Info::file_line_function) },
{ Verbosity::user1, VerbositySpec::Make(VerbositySpec::Info::severity) }, { Verbosity::user1, VerbositySpec::Make(VerbositySpec::Info::severity) },
{ Verbosity::user2, VerbositySpec::Make(VerbositySpec::Info::severity) }, { Verbosity::user2, VerbositySpec::Make(VerbositySpec::Info::severity) },
{ Verbosity::user3, VerbositySpec::Make(VerbositySpec::Info::severity) }, { Verbosity::user3, VerbositySpec::Make(VerbositySpec::Info::severity) },
{ Verbosity::user4, VerbositySpec::Make(VerbositySpec::Info::severity) } { Verbosity::user4, VerbositySpec::Make(VerbositySpec::Info::severity) }
}; };
string Logger::SeverityName(Severity severity) string Logger::SeverityName(Severity severity)
@ -212,14 +212,6 @@ Logger::Logger(Severity severity, Verbosity verbosity, const string& file, const
fMetaData.severity_name = fSeverityNames.at(static_cast<size_t>(severity)); fMetaData.severity_name = fSeverityNames.at(static_cast<size_t>(severity));
fMetaData.severity = severity; fMetaData.severity = severity;
char tsstr[32];
{
lock_guard<mutex> lock(fMtx); // localtime is not threadsafe, guard it
if (!strftime(tsstr, sizeof(tsstr), "%H:%M:%S", localtime(&(fMetaData.timestamp)))) {
tsstr[0] = 'u';
}
}
auto spec = fVerbosities[verbosity]; auto spec = fVerbosities[verbosity];
if ((!fColored && LoggingToConsole()) || LoggingToFile()) { if ((!fColored && LoggingToConsole()) || LoggingToFile()) {
@ -231,11 +223,11 @@ Logger::Logger(Severity severity, Verbosity verbosity, const string& file, const
appendSpace = true; appendSpace = true;
break; break;
case VerbositySpec::Info::timestamp_us: case VerbositySpec::Info::timestamp_us:
fBWOut << "[" << tsstr << "." << setw(6) << setfill('0') << fMetaData.us.count() << "]"; fBWOut << fmt::format("[{:%H:%M:%S}.{:06}]", fmt::localtime(fMetaData.timestamp), fMetaData.us.count());
appendSpace = true; appendSpace = true;
break; break;
case VerbositySpec::Info::timestamp_s: case VerbositySpec::Info::timestamp_s:
fBWOut << "[" << tsstr << "]"; fBWOut << fmt::format("[{:%H:%M:%S}]", fmt::localtime(fMetaData.timestamp));
appendSpace = true; appendSpace = true;
break; break;
case VerbositySpec::Info::severity: case VerbositySpec::Info::severity:
@ -273,12 +265,11 @@ Logger::Logger(Severity severity, Verbosity verbosity, const string& file, const
appendSpace = true; appendSpace = true;
break; break;
case VerbositySpec::Info::timestamp_us: case VerbositySpec::Info::timestamp_us:
fColorOut << "[" << startColor(Color::fgCyan) << tsstr << "." fColorOut << fmt::format("[{}{:%H:%M:%S}.{:06}{}]", startColor(Color::fgCyan), fmt::localtime(fMetaData.timestamp), fMetaData.us.count(), endColor());
<< setw(6) << setfill('0') << fMetaData.us.count() << endColor() << "]";
appendSpace = true; appendSpace = true;
break; break;
case VerbositySpec::Info::timestamp_s: case VerbositySpec::Info::timestamp_s:
fColorOut << "[" << startColor(Color::fgCyan) << tsstr << endColor() << "]"; fColorOut << fmt::format("[{}{:%H:%M:%S}{}]", startColor(Color::fgCyan), fmt::localtime(fMetaData.timestamp), endColor());
appendSpace = true; appendSpace = true;
break; break;
case VerbositySpec::Info::severity: case VerbositySpec::Info::severity:

View File

@ -134,8 +134,7 @@ int main()
cout << "cout: is logging fatal: " << fair::Logger::Logging(Severity::fatal) << endl; cout << "cout: is logging fatal: " << fair::Logger::Logging(Severity::fatal) << endl;
cout << "cout: is logging nolog: " << fair::Logger::Logging(Severity::nolog) << endl; cout << "cout: is logging nolog: " << fair::Logger::Logging(Severity::nolog) << endl;
for (int i = 0; i < 1000000; ++i) for (int i = 0; i < 1000000; ++i) {
{
silentlyPrintAllVerbositiesWithSeverity(Severity::nolog); silentlyPrintAllVerbositiesWithSeverity(Severity::nolog);
} }
cout << endl; cout << endl;
@ -198,8 +197,8 @@ int main()
LOGF(info, "Hello {} {}!", "world", ":-)"); LOGF(info, "Hello {} {}!", "world", ":-)");
LOGP(info, "Hello %s %s!", "world", ":-)"); LOGP(info, "Hello %s %s!", "world", ":-)");
cout << "cout: setting verbosity to 'veryhigh'" << endl; cout << "cout: setting verbosity to 'high'" << endl;
Logger::SetVerbosity(Verbosity::veryhigh); Logger::SetVerbosity(Verbosity::high);
LOGV(info, verylow) << "I should be printed with very low verbosity"; LOGV(info, verylow) << "I should be printed with very low verbosity";