TeaSpeakLibrary/src/log/LogSinks.cpp

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);
}
}