You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

106 lines
2.6 KiB

/**
* @file formatter.h
* @author Harold Bruintjes <h.bruintjes@cs.rwth-aachen.de>
*
* Implementation of Formatter classes
*/
#pragma once
#include <chrono>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <cstring> //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<Field field, int Width, Justification j, char Fill>
inline void FieldStr<field, Width, j, Fill>::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<std::chrono::milliseconds>(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<typename ... Formatters>
inline std::string TemplateFormatter<Formatters...>::format(EntryContext const& context, std::string const& msg) const {
std::stringstream stream;
formatTuple<0>(context, msg, stream);
return stream.str();
}
}