2021-04-20 21:46:48 +02:00
|
|
|
#pragma once
|
|
|
|
|
2022-03-27 00:01:28 +01:00
|
|
|
#include <hex.hpp>
|
|
|
|
|
2021-04-20 21:46:48 +02:00
|
|
|
#include <fmt/core.h>
|
|
|
|
#include <fmt/color.h>
|
|
|
|
|
2023-05-22 13:24:48 +02:00
|
|
|
#include <wolv/io/file.hpp>
|
2024-03-25 20:37:19 +01:00
|
|
|
#include <wolv/utils/guards.hpp>
|
2023-05-22 13:24:48 +02:00
|
|
|
|
2021-04-20 21:46:48 +02:00
|
|
|
namespace hex::log {
|
|
|
|
|
2023-06-18 22:32:55 +02:00
|
|
|
namespace impl {
|
|
|
|
|
|
|
|
FILE *getDestination();
|
|
|
|
wolv::io::File& getFile();
|
|
|
|
bool isRedirected();
|
|
|
|
[[maybe_unused]] void redirectToFile();
|
2023-10-21 20:40:24 +02:00
|
|
|
[[maybe_unused]] void enableColorPrinting();
|
2023-06-18 22:32:55 +02:00
|
|
|
|
2024-02-11 13:46:06 +01:00
|
|
|
[[nodiscard]] bool isLoggingSuspended();
|
2024-03-10 15:22:14 +01:00
|
|
|
[[nodiscard]] bool isDebugLoggingEnabled();
|
2023-06-18 22:32:55 +02:00
|
|
|
|
2024-03-25 20:37:19 +01:00
|
|
|
void lockLoggerMutex();
|
|
|
|
void unlockLoggerMutex();
|
|
|
|
|
2023-07-23 23:37:47 +02:00
|
|
|
struct LogEntry {
|
|
|
|
std::string project;
|
|
|
|
std::string level;
|
|
|
|
std::string message;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<LogEntry>& getLogEntries();
|
2024-01-22 12:53:07 +01:00
|
|
|
void addLogEntry(std::string_view project, std::string_view level, std::string_view message);
|
2023-07-23 23:37:47 +02:00
|
|
|
|
2023-12-20 15:10:53 +01:00
|
|
|
[[maybe_unused]] void printPrefix(FILE *dest, const fmt::text_style &ts, const std::string &level, const char *projectName);
|
2022-02-02 17:19:50 +01:00
|
|
|
|
2023-10-21 20:40:24 +02:00
|
|
|
[[maybe_unused]] void print(const fmt::text_style &ts, const std::string &level, const std::string &fmt, auto && ... args) {
|
2024-02-11 13:46:06 +01:00
|
|
|
if (isLoggingSuspended()) [[unlikely]]
|
|
|
|
return;
|
|
|
|
|
2024-03-25 20:37:19 +01:00
|
|
|
lockLoggerMutex();
|
|
|
|
ON_SCOPE_EXIT { unlockLoggerMutex(); };
|
2023-06-12 08:24:36 +02:00
|
|
|
|
2024-01-04 00:37:56 +01:00
|
|
|
auto dest = getDestination();
|
2024-03-15 21:06:47 +01:00
|
|
|
try {
|
|
|
|
printPrefix(dest, ts, level, IMHEX_PROJECT_NAME);
|
2023-07-23 23:37:47 +02:00
|
|
|
|
2024-03-15 21:06:47 +01:00
|
|
|
auto message = fmt::format(fmt::runtime(fmt), args...);
|
|
|
|
fmt::print(dest, "{}\n", message);
|
|
|
|
fflush(dest);
|
2023-07-23 23:37:47 +02:00
|
|
|
|
2024-03-15 21:06:47 +01:00
|
|
|
addLogEntry(IMHEX_PROJECT_NAME, level, std::move(message));
|
|
|
|
} catch (const std::exception&) { }
|
2022-02-06 00:42:38 +01:00
|
|
|
}
|
|
|
|
|
2024-02-24 11:28:47 +01:00
|
|
|
namespace color {
|
|
|
|
|
|
|
|
fmt::color debug();
|
|
|
|
fmt::color info();
|
|
|
|
fmt::color warn();
|
|
|
|
fmt::color error();
|
|
|
|
fmt::color fatal();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-01-17 20:06:00 +01:00
|
|
|
}
|
|
|
|
|
2024-02-11 13:46:06 +01:00
|
|
|
void suspendLogging();
|
|
|
|
void resumeLogging();
|
2024-03-10 15:22:14 +01:00
|
|
|
void enableDebugLogging();
|
2024-02-11 13:46:06 +01:00
|
|
|
|
2023-10-21 20:40:24 +02:00
|
|
|
[[maybe_unused]] void debug(const std::string &fmt, auto && ... args) {
|
2024-03-10 15:22:14 +01:00
|
|
|
if (impl::isDebugLoggingEnabled()) [[unlikely]] {
|
2024-02-24 11:28:47 +01:00
|
|
|
hex::log::impl::print(fg(impl::color::debug()) | fmt::emphasis::bold, "[DEBUG]", fmt, args...);
|
2024-03-10 15:22:14 +01:00
|
|
|
} else {
|
2024-01-22 12:53:07 +01:00
|
|
|
impl::addLogEntry(IMHEX_PROJECT_NAME, "[DEBUG]", fmt::format(fmt::runtime(fmt), args...));
|
2024-03-10 15:22:14 +01:00
|
|
|
}
|
2021-04-20 21:46:48 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 20:40:24 +02:00
|
|
|
[[maybe_unused]] void info(const std::string &fmt, auto && ... args) {
|
2024-02-24 11:28:47 +01:00
|
|
|
hex::log::impl::print(fg(impl::color::info()) | fmt::emphasis::bold, "[INFO] ", fmt, args...);
|
2021-04-20 21:46:48 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 20:40:24 +02:00
|
|
|
[[maybe_unused]] void warn(const std::string &fmt, auto && ... args) {
|
2024-02-24 11:28:47 +01:00
|
|
|
hex::log::impl::print(fg(impl::color::warn()) | fmt::emphasis::bold, "[WARN] ", fmt, args...);
|
2021-04-20 21:46:48 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 20:40:24 +02:00
|
|
|
[[maybe_unused]] void error(const std::string &fmt, auto && ... args) {
|
2024-02-24 11:28:47 +01:00
|
|
|
hex::log::impl::print(fg(impl::color::error()) | fmt::emphasis::bold, "[ERROR]", fmt, args...);
|
2021-04-20 21:46:48 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 20:40:24 +02:00
|
|
|
[[maybe_unused]] void fatal(const std::string &fmt, auto && ... args) {
|
2024-02-24 11:28:47 +01:00
|
|
|
hex::log::impl::print(fg(impl::color::fatal()) | fmt::emphasis::bold, "[FATAL]", fmt, args...);
|
2021-04-20 21:46:48 +02:00
|
|
|
}
|
|
|
|
|
2023-10-21 20:40:24 +02:00
|
|
|
[[maybe_unused]] void print(const std::string &fmt, auto && ... args) {
|
2024-03-25 20:37:19 +01:00
|
|
|
impl::lockLoggerMutex();
|
|
|
|
ON_SCOPE_EXIT { impl::unlockLoggerMutex(); };
|
2023-10-21 20:40:24 +02:00
|
|
|
|
2024-03-15 21:06:47 +01:00
|
|
|
try {
|
|
|
|
auto dest = impl::getDestination();
|
|
|
|
auto message = fmt::format(fmt::runtime(fmt), args...);
|
|
|
|
fmt::print(dest, "{}", message);
|
|
|
|
fflush(dest);
|
|
|
|
} catch (const std::exception&) { }
|
2023-10-21 20:40:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
[[maybe_unused]] void println(const std::string &fmt, auto && ... args) {
|
2024-03-25 20:37:19 +01:00
|
|
|
impl::lockLoggerMutex();
|
|
|
|
ON_SCOPE_EXIT { impl::unlockLoggerMutex(); };
|
2023-10-21 20:40:24 +02:00
|
|
|
|
2024-03-15 21:06:47 +01:00
|
|
|
try {
|
|
|
|
auto dest = impl::getDestination();
|
|
|
|
auto message = fmt::format(fmt::runtime(fmt), args...);
|
|
|
|
fmt::print(dest, "{}\n", message);
|
|
|
|
fflush(dest);
|
|
|
|
} catch (const std::exception&) { }
|
2023-10-21 20:40:24 +02:00
|
|
|
}
|
|
|
|
|
2024-03-25 20:37:19 +01:00
|
|
|
}
|