#include "LogUtils.h" #include "LogSinks.h" #include #include #include #include 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(&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 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); } }