Files
imhex/lib/libimhex/source/helpers/logger.cpp
iTrooz e5d9d9ec9e chore: apply more complicated lints (#2576)
<!--
Please provide as much information as possible about what your PR aims
to do.
PRs with no description will most likely be closed until more
information is provided.
If you're planing on changing fundamental behaviour or add big new
features, please open a GitHub Issue first before starting to work on
it.
If it's not something big and you still want to contact us about it,
feel free to do so !
-->

### Problem description
<!-- Describe the bug that you fixed/feature request that you
implemented, or link to an existing issue describing it -->

### Implementation description
<!-- Explain what you did to correct the problem -->

### Screenshots
<!-- If your change is visual, take a screenshot showing it. Ideally,
make before/after sceenshots -->

### Additional things
<!-- Anything else you would like to say -->
2025-12-21 20:55:50 +01:00

165 lines
4.8 KiB
C++

#include <hex/helpers/logger.hpp>
#include <hex/api/task_manager.hpp>
#include <hex/helpers/fs.hpp>
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/default_paths.hpp>
#include <hex/helpers/auto_reset.hpp>
#include <wolv/io/file.hpp>
#include <mutex>
#include <chrono>
#include <fmt/chrono.h>
#include <hex/helpers/debugging.hpp>
#if defined(OS_WINDOWS)
#include <Windows.h>
#endif
namespace hex::log {
namespace {
wolv::io::File s_loggerFile;
bool s_colorOutputEnabled = false;
std::recursive_mutex s_loggerMutex;
bool s_loggingSuspended = false;
bool s_debugLoggingEnabled = false;
}
void suspendLogging() {
s_loggingSuspended = true;
}
void resumeLogging() {
s_loggingSuspended = false;
}
void enableDebugLogging() {
s_debugLoggingEnabled = true;
}
namespace impl {
void lockLoggerMutex() {
s_loggerMutex.lock();
}
void unlockLoggerMutex() {
s_loggerMutex.unlock();
}
bool isLoggingSuspended() {
return s_loggingSuspended;
}
bool isDebugLoggingEnabled() {
#if defined(DEBUG)
return true;
#else
return s_debugLoggingEnabled;
#endif
}
FILE *getDestination() {
if (s_loggerFile.isValid())
return s_loggerFile.getHandle();
else
return stdout;
}
wolv::io::File& getFile() {
return s_loggerFile;
}
bool isRedirected() {
return s_loggerFile.isValid();
}
void redirectToFile() {
if (s_loggerFile.isValid()) return;
for (const auto &path : paths::Logs.all()) {
wolv::io::fs::createDirectories(path);
time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
s_loggerFile = wolv::io::File(path / fmt::format("{0:%Y%m%d_%H%M%S}.log", *std::localtime(&time)), wolv::io::File::Mode::Create);
s_loggerFile.disableBuffering();
if (s_loggerFile.isValid()) {
s_colorOutputEnabled = false;
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
}
static AutoReset<std::vector<LogEntry>> s_logEntries;
const std::vector<LogEntry>& getLogEntries() {
return s_logEntries;
}
void addLogEntry(std::string_view project, std::string_view level, std::string message) {
s_logEntries->emplace_back(
project,
level,
std::move(message)
);
}
void printPrefix(FILE *dest, fmt::text_style ts, std::string_view level, std::string_view projectName) {
const auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
const auto now = *std::localtime(&time);
auto threadName = TaskManager::getCurrentThreadName();
if (threadName.empty()) [[unlikely]] {
threadName = "???";
}
constexpr static auto MaxTagLength = 25;
const auto totalLength = std::min(static_cast<size_t>(MaxTagLength),
projectName.length() + (threadName.empty() ? 0 : 3 + threadName.length()));
const auto remainingSpace = MaxTagLength - projectName.length() - 3;
fmt::print(dest, "[{0:%H:%M:%S}] {1} [{2} | {3}] {4: <{5}} ",
now,
s_colorOutputEnabled ? fmt::format(ts, "{}", level) : level,
projectName.substr(0, std::min(projectName.length(), static_cast<size_t>(MaxTagLength))),
threadName.substr(0, remainingSpace),
"",
MaxTagLength - totalLength
);
}
namespace color {
fmt::color debug() { return fmt::color::medium_sea_green; }
fmt::color info() { return fmt::color::steel_blue; }
fmt::color warn() { return fmt::color::orange; }
fmt::color error() { return fmt::color::indian_red; }
fmt::color fatal() { return fmt::color::medium_purple; }
}
}
}