1
0
mirror of synced 2024-12-14 00:32:52 +01:00
ImHex/lib/libimhex/source/helpers/logger.cpp

111 lines
3.4 KiB
C++
Raw Normal View History

#include <hex/helpers/logger.hpp>
#include <hex/helpers/fs.hpp>
#include <hex/helpers/fmt.hpp>
#include <wolv/io/file.hpp>
2023-11-30 14:40:07 +01:00
#include <chrono>
#include <fmt/chrono.h>
2024-01-09 10:39:06 +01:00
#include <hex/api/task_manager.hpp>
2023-11-30 14:40:07 +01:00
#if defined(OS_WINDOWS)
#include <Windows.h>
#endif
2023-06-18 22:32:55 +02:00
namespace hex::log::impl {
2023-06-18 22:32:55 +02:00
static wolv::io::File s_loggerFile;
static bool s_colorOutputEnabled = false;
2023-07-23 23:37:47 +02:00
std::mutex g_loggerMutex;
FILE *getDestination() {
2023-06-18 22:32:55 +02:00
if (s_loggerFile.isValid())
return s_loggerFile.getHandle();
else
return stdout;
}
wolv::io::File& getFile() {
2023-06-18 22:32:55 +02:00
return s_loggerFile;
}
bool isRedirected() {
2023-06-18 22:32:55 +02:00
return s_loggerFile.isValid();
}
void redirectToFile() {
2023-06-18 22:32:55 +02:00
if (s_loggerFile.isValid()) return;
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Logs, true)) {
wolv::io::fs::createDirectories(path);
2023-06-18 22:32:55 +02:00
s_loggerFile = wolv::io::File(path / hex::format("{0:%Y%m%d_%H%M%S}.log", fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()))), wolv::io::File::Mode::Create);
s_loggerFile.disableBuffering();
if (s_loggerFile.isValid()) {
s_colorOutputEnabled = true;
break;
}
}
}
void enableColorPrinting() {
s_colorOutputEnabled = true;
#if defined(OS_WINDOWS)
auto hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole != INVALID_HANDLE_VALUE) {
DWORD mode = 0;
if (::GetConsoleMode(hConsole, &mode) == TRUE) {
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT;
::SetConsoleMode(hConsole, mode);
}
}
#endif
}
2023-07-23 23:37:47 +02:00
std::vector<LogEntry>& getLogEntries() {
static std::vector<LogEntry> logEntries;
return logEntries;
}
void addLogEntry(std::string_view project, std::string_view level, std::string_view message) {
getLogEntries().emplace_back(project.data(), level.data(), message.data());
}
void printPrefix(FILE *dest, const fmt::text_style &ts, const std::string &level, const char *projectName) {
2023-11-30 14:40:07 +01:00
const auto now = fmt::localtime(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
fmt::print(dest, "[{0:%H:%M:%S}] ", now);
if (s_colorOutputEnabled)
2023-11-30 14:40:07 +01:00
fmt::print(dest, ts, "{0} ", level);
else
fmt::print(dest, "{0} ", level);
2023-11-30 14:40:07 +01:00
2024-01-09 10:39:06 +01:00
std::string projectThreadTag = projectName;
if (auto threadName = TaskManager::getCurrentThreadName(); !threadName.empty())
projectThreadTag += fmt::format(" | {0}", threadName);
2023-11-30 14:40:07 +01:00
2024-01-09 10:39:06 +01:00
constexpr static auto MaxTagLength = 25;
if (projectThreadTag.length() > MaxTagLength)
projectThreadTag.resize(MaxTagLength);
fmt::print(dest, "[{0}] ", projectThreadTag);
const auto projectNameLength = projectThreadTag.length();
fmt::print(dest, "{0}", std::string(projectNameLength > MaxTagLength ? 0 : MaxTagLength - projectNameLength, ' '));
2023-11-30 14:40:07 +01:00
}
2023-11-10 20:47:08 +01:00
void assertionHandler(bool expr, const char* exprString, const char* file, int line) {
2023-07-23 23:39:00 +02:00
if (!expr) {
2023-11-10 20:47:08 +01:00
log::error("Assertion failed: {} at {}:{}", exprString, file, line);
2023-07-23 23:39:00 +02:00
#if defined (DEBUG)
std::abort();
#endif
}
}
}