/** * @file formatter.h * @author Harold Bruintjes * * Implementation of Formatter classes */ #pragma once #include #include #include #include #include //strrchr namespace l3pp { namespace detail { /** * Internal function to get wall-time */ inline static std::chrono::system_clock::time_point GetStartTime() { static std::chrono::system_clock::time_point startTime = std::chrono::system_clock::now(); return startTime; } } inline void Formatter::initialize() { // Init wall-time detail::GetStartTime(); } inline std::string Formatter::format(EntryContext const& context, std::string const& msg) const { std::stringstream stream; stream << context.level << " - " << msg << '\n'; return stream.str(); } template inline void FieldStr::stream(std::ostream& os, EntryContext const& context, std::string const& msg) const { os << std::setw(Width); os << std::setfill(Fill); switch(j) { case Justification::LEFT: os << std::left; case Justification::RIGHT: os << std::right; } switch(field) { case Field::FileName: #ifdef _WIN32 os << strrchr(context.filename, '\\')+1; #else os << strrchr(context.filename, '/')+1; #endif break; case Field::FilePath: os << context.filename; break; case Field::Line: os << context.line; break; case Field::Function: os << context.funcname; break; case Field::LoggerName: os << context.logger->getName(); break; case Field::Message: os << msg; break; case Field::LogLevel: os << context.level; break; case Field::WallTime: auto runtime = context.timestamp - detail::GetStartTime(); os << std::chrono::duration_cast(runtime).count(); break; } } inline void TimeStr::stream(std::ostream& os, EntryContext const& context, std::string const&) const { auto time = std::chrono::system_clock::to_time_t(context.timestamp); auto timeinfo = localtime (&time); #if __GNUC__ >= 5 || __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 7) || _MSC_VER >= 1700 //TODO: Need better way to detect thing os << std::put_time(timeinfo, formatStr.c_str()); #else char buffer[1024]; if (strftime(buffer, 1024, formatStr.c_str(), timeinfo)) { os << buffer; } #endif } template inline std::string TemplateFormatter::format(EntryContext const& context, std::string const& msg) const { std::stringstream stream; formatTuple<0>(context, msg, stream); return stream.str(); } }