118 lines
4.0 KiB
C++
118 lines
4.0 KiB
C++
#include "LogUtils.h"
|
|
#include "LogSinks.h"
|
|
#include <iomanip>
|
|
#include <fstream>
|
|
#include <spdlog/spdlog.h>
|
|
#include <experimental/filesystem>
|
|
|
|
using namespace std;
|
|
using namespace spdlog;
|
|
namespace fs = std::experimental::filesystem;
|
|
|
|
namespace logger {
|
|
void TerminalSink::log(const spdlog::details::log_msg &msg) {
|
|
#ifdef HAVE_CXX_TERMINAL
|
|
if (terminal::active()) {
|
|
auto strMsg = msg.formatted.str();
|
|
size_t index = 0;
|
|
do {
|
|
auto eIndex = strMsg.find('\n', index);
|
|
auto str = terminal::parseCharacterCodes(strMsg.substr(index, eIndex - index));
|
|
terminal::instance()->writeMessage(str);
|
|
index = eIndex + 1;
|
|
} while (index != 0 && index < strMsg.length()); //if eindex == npos and we add the 1 we get 0 :)
|
|
} else
|
|
#endif
|
|
cout << msg.formatted.str();
|
|
}
|
|
|
|
void TerminalSink::flush() {}
|
|
|
|
bool TerminalSink::should_log_(const details::log_msg &msg) const {
|
|
auto _force_message = dynamic_cast<const ::logger::force_log_msg*>(&msg);
|
|
if(_force_message && _force_message->force)
|
|
return true;
|
|
return sink::should_log_(msg);
|
|
}
|
|
|
|
ColoredFileSink::ColoredFileSink(const filename_t &base_filename, size_t max_size, size_t max_files)
|
|
: rotating_file_sink(
|
|
base_filename, max_size, max_files) {}
|
|
|
|
void ColoredFileSink::_sink_it(const details::log_msg &msg) {
|
|
details::log_msg _clone;
|
|
|
|
#ifdef HAVE_CXX_TERMINAL
|
|
if (::logger::currentConfig()->file_colored)
|
|
_clone.formatted << ANSI_RESET << terminal::parseCharacterCodes(msg.formatted.str());
|
|
else
|
|
_clone.formatted << terminal::stripCharacterCodes(msg.formatted.str());
|
|
#else
|
|
_clone.formatted << msg.formatted.str();
|
|
#endif
|
|
sinks::rotating_file_sink_mt::_sink_it(_clone);
|
|
}
|
|
|
|
void CostumeFormatter::format(spdlog::details::log_msg &msg) {
|
|
msg.formatted.clear();
|
|
|
|
string lvlName = level::to_str(msg.level);
|
|
transform(lvlName.begin(), lvlName.end(), lvlName.begin(), ::toupper);
|
|
auto org_length = lvlName.length();
|
|
|
|
string msgColor;
|
|
string msgSuffix;
|
|
#ifdef HAVE_CXX_TERMINAL
|
|
switch (msg.level) {
|
|
case level::trace:
|
|
lvlName = "§9" + lvlName;
|
|
break;
|
|
case level::info:
|
|
lvlName = "§e" + lvlName;
|
|
break;
|
|
case level::warn:
|
|
lvlName = "§6" + lvlName;
|
|
break;
|
|
case level::err:
|
|
lvlName = "§4" + lvlName;
|
|
break;
|
|
case level::critical:
|
|
lvlName = ANSI_BOLD ANSI_REVERSE ANSI_RED + lvlName;
|
|
msgColor = ANSI_BOLD ANSI_REVERSE ANSI_RED;
|
|
msgSuffix = ANSI_RESET;
|
|
break;
|
|
case level::debug:
|
|
lvlName = "§9" + lvlName;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
auto strMsg = msg.raw.str();
|
|
|
|
auto tp = std::chrono::system_clock::to_time_t(msg.time);
|
|
|
|
stringstream prefix;
|
|
prefix << "[" << std::put_time(std::localtime(&tp), "%F %T") << "] [" << lvlName << "§r] ";
|
|
for(size_t i = org_length; i < 5; i++)
|
|
prefix << " ";
|
|
prefix << msgColor;
|
|
|
|
size_t index = 0;
|
|
do {
|
|
auto eIndex = strMsg.find('\n', index);
|
|
auto m = strMsg.substr(index, eIndex - index);
|
|
msg.formatted << "§r" << prefix.str() << m << msgSuffix << "\n";
|
|
index = eIndex + 1; //if eindex == npos and we add the 1 we get 0 :)
|
|
} while (index != 0 && index < strMsg.length());
|
|
}
|
|
|
|
inline std::string CostumeFormatter::time(chrono::time_point<log_clock> point) {
|
|
std::time_t time = log_clock::to_time_t(point);
|
|
std::tm timetm = *std::localtime(&time);
|
|
char buffer[9];
|
|
strftime(buffer, 9, "%H:%M:%S", &timetm);
|
|
return string(buffer, 8);
|
|
}
|
|
} |