163 lines
4.6 KiB
C++
163 lines
4.6 KiB
C++
#include "logger.hpp"
|
|
|
|
#include "util/is_proton.hpp"
|
|
|
|
namespace big
|
|
{
|
|
template<typename TP>
|
|
std::time_t to_time_t(TP tp)
|
|
{
|
|
using namespace std::chrono;
|
|
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now() + system_clock::now());
|
|
return system_clock::to_time_t(sctp);
|
|
}
|
|
|
|
void logger::initialize(const std::string_view console_title, file file, bool attach_console)
|
|
{
|
|
m_console_title = console_title;
|
|
m_file = file;
|
|
if (is_proton())
|
|
{
|
|
LOG(VERBOSE) << "Using simple logger.";
|
|
m_console_logger = &logger::format_console_simple;
|
|
}
|
|
|
|
toggle_external_console(attach_console);
|
|
create_backup();
|
|
m_file_out.open(m_file.get_path(), std::ios_base::out | std::ios_base::trunc);
|
|
|
|
Logger::Init();
|
|
Logger::AddSink([this](LogMessagePtr msg) {
|
|
(this->*m_console_logger)(std::move(msg));
|
|
});
|
|
Logger::AddSink([this](LogMessagePtr msg) {
|
|
format_file(std::move(msg));
|
|
});
|
|
}
|
|
|
|
void logger::destroy()
|
|
{
|
|
Logger::Destroy();
|
|
m_file_out.close();
|
|
toggle_external_console(false);
|
|
}
|
|
|
|
void logger::toggle_external_console(bool toggle)
|
|
{
|
|
if (toggle)
|
|
{
|
|
if (m_did_console_exist = ::AttachConsole(GetCurrentProcessId()); !m_did_console_exist)
|
|
AllocConsole();
|
|
|
|
if (m_console_handle = GetStdHandle(STD_OUTPUT_HANDLE); m_console_handle != nullptr)
|
|
{
|
|
SetConsoleTitleA(m_console_title.data());
|
|
SetConsoleOutputCP(CP_UTF8);
|
|
|
|
DWORD console_mode;
|
|
GetConsoleMode(m_console_handle, &console_mode);
|
|
m_original_console_mode = console_mode;
|
|
|
|
// terminal like behaviour enable full color support
|
|
console_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
|
|
// prevent clicking in terminal from suspending our main thread
|
|
console_mode &= ~(ENABLE_QUICK_EDIT_MODE);
|
|
|
|
SetConsoleMode(m_console_handle, console_mode);
|
|
}
|
|
|
|
m_console_out.open("CONOUT$", std::ios_base::out | std::ios_base::app);
|
|
|
|
return;
|
|
}
|
|
|
|
m_console_out.close();
|
|
if (m_did_console_exist)
|
|
SetConsoleMode(m_console_handle, m_original_console_mode);
|
|
|
|
if (!m_did_console_exist)
|
|
FreeConsole();
|
|
}
|
|
|
|
void logger::create_backup()
|
|
{
|
|
if (m_file.exists())
|
|
{
|
|
auto file_time = std::filesystem::last_write_time(m_file.get_path());
|
|
auto time_t = to_time_t(file_time);
|
|
auto local_time = std::localtime(&time_t);
|
|
|
|
m_file.move(std::format("./backup/{:0>2}-{:0>2}-{}-{:0>2}-{:0>2}-{:0>2}_{}",
|
|
local_time->tm_mon + 1,
|
|
local_time->tm_mday,
|
|
local_time->tm_year + 1900,
|
|
local_time->tm_hour,
|
|
local_time->tm_min,
|
|
local_time->tm_sec,
|
|
m_file.get_path().filename().string().c_str()));
|
|
}
|
|
}
|
|
|
|
const LogColor get_color(const eLogLevel level)
|
|
{
|
|
switch (level)
|
|
{
|
|
case VERBOSE: return LogColor::BLUE;
|
|
case INFO: return LogColor::GREEN;
|
|
case WARNING: return LogColor::YELLOW;
|
|
case FATAL: return LogColor::RED;
|
|
}
|
|
return LogColor::WHITE;
|
|
}
|
|
|
|
const char* get_level_string(const eLogLevel level)
|
|
{
|
|
constexpr std::array<const char*, 4> levelStrings = {{{"DEBUG"}, {"INFO"}, {"WARN"}, {"FATAL"}}};
|
|
|
|
return levelStrings[level];
|
|
}
|
|
|
|
void logger::format_console(const LogMessagePtr msg)
|
|
{
|
|
const auto color = get_color(msg->Level());
|
|
|
|
const auto timestamp = std::format("{0:%H:%M:%S}", msg->Timestamp());
|
|
const auto& location = msg->Location();
|
|
const auto level = msg->Level();
|
|
|
|
const auto file = std::filesystem::path(location.file_name()).filename().string();
|
|
|
|
m_console_out << "[" << timestamp << "]" << ADD_COLOR_TO_STREAM(color) << "[" << get_level_string(level) << "/" << file << ":"
|
|
<< location.line() << "] " << RESET_STREAM_COLOR << msg->Message() << std::flush;
|
|
}
|
|
|
|
void logger::format_console_simple(const LogMessagePtr msg)
|
|
{
|
|
const auto color = get_color(msg->Level());
|
|
|
|
const auto timestamp = std::format("{0:%H:%M:%S}", msg->Timestamp());
|
|
const auto& location = msg->Location();
|
|
const auto level = msg->Level();
|
|
|
|
const auto file = std::filesystem::path(location.file_name()).filename().string();
|
|
|
|
m_console_out << "[" << timestamp << "]"
|
|
<< "[" << get_level_string(level) << "/" << file << ":" << location.line() << "] " << msg->Message() << std::flush;
|
|
}
|
|
|
|
void logger::format_file(const LogMessagePtr msg)
|
|
{
|
|
if (!m_file_out.is_open())
|
|
return;
|
|
|
|
const auto timestamp = std::format("{0:%H:%M:%S}", msg->Timestamp());
|
|
const auto& location = msg->Location();
|
|
const auto level = msg->Level();
|
|
|
|
const auto file = std::filesystem::path(location.file_name()).filename().string();
|
|
|
|
m_file_out << "[" << timestamp << "]"
|
|
<< "[" << get_level_string(level) << "/" << file << ":" << location.line() << "] " << msg->Message() << std::flush;
|
|
}
|
|
}
|