mirror of https://github.com/AxioDL/logvisor.git
Integrate libfmt for format strings
This commit is contained in:
parent
a0ef17d895
commit
3bedd268e8
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "fmt"]
|
||||||
|
path = fmt
|
||||||
|
url = https://github.com/fmtlib/fmt
|
|
@ -7,15 +7,18 @@ endif()
|
||||||
|
|
||||||
include (CMakePackageConfigHelpers)
|
include (CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
add_subdirectory(fmt)
|
||||||
|
|
||||||
add_library(logvisor
|
add_library(logvisor
|
||||||
lib/logvisor.cpp
|
lib/logvisor.cpp
|
||||||
include/logvisor/logvisor.hpp)
|
include/logvisor/logvisor.hpp)
|
||||||
|
|
||||||
target_link_libraries(logvisor PUBLIC ${CMAKE_DL_LIBS})
|
target_link_libraries(logvisor PUBLIC ${CMAKE_DL_LIBS} fmt)
|
||||||
|
|
||||||
target_include_directories(logvisor PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
target_include_directories(logvisor PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
||||||
|
|
||||||
install(DIRECTORY include/logvisor DESTINATION include)
|
install(DIRECTORY include/logvisor DESTINATION include)
|
||||||
|
install(DIRECTORY fmt/include/fmt DESTINATION include)
|
||||||
|
|
||||||
set(version_config_file "${PROJECT_BINARY_DIR}/logvisorConfigVersion.cmake")
|
set(version_config_file "${PROJECT_BINARY_DIR}/logvisorConfigVersion.cmake")
|
||||||
set(config_file "${PROJECT_BINARY_DIR}/logvisorConfig.cmake")
|
set(config_file "${PROJECT_BINARY_DIR}/logvisorConfig.cmake")
|
||||||
|
@ -23,7 +26,7 @@ set(config_install_dir "lib/cmake/logvisor")
|
||||||
|
|
||||||
# Associate target with export
|
# Associate target with export
|
||||||
install(
|
install(
|
||||||
TARGETS logvisor
|
TARGETS logvisor fmt
|
||||||
EXPORT logvisorTargets
|
EXPORT logvisorTargets
|
||||||
ARCHIVE DESTINATION "lib"
|
ARCHIVE DESTINATION "lib"
|
||||||
INCLUDES DESTINATION include # This sets the INTERFACE_INCLUDE_DIRECTORIES property of the target.
|
INCLUDES DESTINATION include # This sets the INTERFACE_INCLUDE_DIRECTORIES property of the target.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 6bcc3fd21694b5634cc006915bd049cf460a9a8d
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdarg>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -9,6 +8,11 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#define FMT_STRING_ALIAS 1
|
||||||
|
#define FMT_ENFORCE_COMPILE_STRING 1
|
||||||
|
#define FMT_USE_GRISU 0
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#ifdef __SWITCH__
|
#ifdef __SWITCH__
|
||||||
#include "nxstl/mutex"
|
#include "nxstl/mutex"
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,13 +44,13 @@ enum Level {
|
||||||
* @brief Backend interface for receiving app-wide log events
|
* @brief Backend interface for receiving app-wide log events
|
||||||
*/
|
*/
|
||||||
struct ILogger {
|
struct ILogger {
|
||||||
virtual ~ILogger() {}
|
virtual ~ILogger() = default;
|
||||||
virtual void report(const char* modName, Level severity, const char* format, va_list ap) = 0;
|
virtual void report(const char* modName, Level severity, fmt::string_view format, fmt::format_args args) = 0;
|
||||||
virtual void report(const char* modName, Level severity, const wchar_t* format, va_list ap) = 0;
|
virtual void report(const char* modName, Level severity, fmt::wstring_view format, fmt::wformat_args args) = 0;
|
||||||
virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const char* format,
|
|
||||||
va_list ap) = 0;
|
|
||||||
virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
|
virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
|
||||||
const wchar_t* format, va_list ap) = 0;
|
fmt::string_view format, fmt::format_args args) = 0;
|
||||||
|
virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
|
||||||
|
fmt::wstring_view format, fmt::wformat_args args) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -107,7 +111,7 @@ extern LogMutex _LogMutex;
|
||||||
* @brief Take a centralized lock for the logging output stream(s)
|
* @brief Take a centralized lock for the logging output stream(s)
|
||||||
* @return RAII mutex lock
|
* @return RAII mutex lock
|
||||||
*/
|
*/
|
||||||
static inline std::unique_lock<std::recursive_mutex> LockLog() { return _LogMutex.lock(); }
|
inline std::unique_lock<std::recursive_mutex> LockLog() { return _LogMutex.lock(); }
|
||||||
|
|
||||||
extern uint64_t _LogCounter;
|
extern uint64_t _LogCounter;
|
||||||
|
|
||||||
|
@ -115,12 +119,12 @@ extern uint64_t _LogCounter;
|
||||||
* @brief Get current count of logging events
|
* @brief Get current count of logging events
|
||||||
* @return Log Count
|
* @return Log Count
|
||||||
*/
|
*/
|
||||||
static inline uint64_t GetLogCounter() { return _LogCounter; }
|
inline uint64_t GetLogCounter() { return _LogCounter; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Restore centralized logger vector to default state (silent operation)
|
* @brief Restore centralized logger vector to default state (silent operation)
|
||||||
*/
|
*/
|
||||||
static inline void UnregisterLoggers() { MainLoggers.clear(); }
|
inline void UnregisterLoggers() { MainLoggers.clear(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct and register a real-time console logger singleton
|
* @brief Construct and register a real-time console logger singleton
|
||||||
|
@ -168,6 +172,40 @@ void RegisterFileLogger(const wchar_t* filepath);
|
||||||
class Module {
|
class Module {
|
||||||
const char* m_modName;
|
const char* m_modName;
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
void _vreport(Level severity, fmt::basic_string_view<Char> format,
|
||||||
|
fmt::basic_format_args<fmt::buffer_context<Char>> args) {
|
||||||
|
auto lk = LockLog();
|
||||||
|
++_LogCounter;
|
||||||
|
if (severity == Fatal)
|
||||||
|
RegisterConsoleLogger();
|
||||||
|
for (auto& logger : MainLoggers)
|
||||||
|
logger->report(m_modName, severity, format, args);
|
||||||
|
if (severity == Error || severity == Fatal)
|
||||||
|
logvisorBp();
|
||||||
|
if (severity == Fatal)
|
||||||
|
logvisorAbort();
|
||||||
|
else if (severity == Error)
|
||||||
|
++ErrorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
void _vreportSource(Level severity, const char* file, unsigned linenum, fmt::basic_string_view<Char> format,
|
||||||
|
fmt::basic_format_args<fmt::buffer_context<Char>> args) {
|
||||||
|
auto lk = LockLog();
|
||||||
|
++_LogCounter;
|
||||||
|
if (severity == Fatal)
|
||||||
|
RegisterConsoleLogger();
|
||||||
|
for (auto& logger : MainLoggers)
|
||||||
|
logger->reportSource(m_modName, severity, file, linenum, format, args);
|
||||||
|
if (severity == Error || severity == Fatal)
|
||||||
|
logvisorBp();
|
||||||
|
if (severity == Fatal)
|
||||||
|
logvisorAbort();
|
||||||
|
else if (severity == Error)
|
||||||
|
++ErrorCount;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Module(const char* modName) : m_modName(modName) {}
|
Module(const char* modName) : m_modName(modName) {}
|
||||||
|
|
||||||
|
@ -176,34 +214,21 @@ public:
|
||||||
* @param severity Level of log report severity
|
* @param severity Level of log report severity
|
||||||
* @param format Standard printf-style format string
|
* @param format Standard printf-style format string
|
||||||
*/
|
*/
|
||||||
template <typename CharType>
|
template <typename S, typename... Args, typename Char = fmt::char_t<S>>
|
||||||
inline void report(Level severity, const CharType* format, ...) {
|
void report(Level severity, const S& format, Args&&... args) {
|
||||||
if (MainLoggers.empty() && severity != Level::Fatal)
|
if (MainLoggers.empty() && severity != Level::Fatal)
|
||||||
return;
|
return;
|
||||||
va_list ap;
|
_vreport(severity, fmt::to_string_view<Char>(format),
|
||||||
va_start(ap, format);
|
fmt::basic_format_args<fmt::buffer_context<Char>>(
|
||||||
report(severity, format, ap);
|
fmt::internal::make_args_checked<Args...>(format, args...)));
|
||||||
va_end(ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharType>
|
template <typename Char>
|
||||||
inline void report(Level severity, const CharType* format, va_list ap) {
|
void vreport(Level severity, fmt::basic_string_view<Char> format,
|
||||||
auto lk = LockLog();
|
fmt::basic_format_args<fmt::buffer_context<Char>> args) {
|
||||||
++_LogCounter;
|
if (MainLoggers.empty() && severity != Level::Fatal)
|
||||||
if (severity == Fatal)
|
return;
|
||||||
RegisterConsoleLogger();
|
_vreport(severity, format, args);
|
||||||
for (auto& logger : MainLoggers) {
|
|
||||||
va_list apc;
|
|
||||||
va_copy(apc, ap);
|
|
||||||
logger->report(m_modName, severity, format, apc);
|
|
||||||
va_end(apc);
|
|
||||||
}
|
|
||||||
if (severity == Error || severity == Fatal)
|
|
||||||
logvisorBp();
|
|
||||||
if (severity == Fatal)
|
|
||||||
logvisorAbort();
|
|
||||||
else if (severity == Error)
|
|
||||||
++ErrorCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,34 +238,66 @@ public:
|
||||||
* @param linenum Source line number from __LINE__ macro
|
* @param linenum Source line number from __LINE__ macro
|
||||||
* @param format Standard printf-style format string
|
* @param format Standard printf-style format string
|
||||||
*/
|
*/
|
||||||
template <typename CharType>
|
template <typename S, typename... Args, typename Char = fmt::char_t<S>>
|
||||||
inline void reportSource(Level severity, const char* file, unsigned linenum, const CharType* format, ...) {
|
void reportSource(Level severity, const char* file, unsigned linenum, const S& format, Args&&... args) {
|
||||||
if (MainLoggers.empty() && severity != Level::Fatal)
|
if (MainLoggers.empty() && severity != Level::Fatal)
|
||||||
return;
|
return;
|
||||||
va_list ap;
|
_vreportSource(
|
||||||
va_start(ap, format);
|
severity, file, linenum, fmt::to_string_view<Char>(format),
|
||||||
reportSource(severity, file, linenum, format, ap);
|
fmt::basic_format_args<fmt::buffer_context<Char>>(
|
||||||
va_end(ap);
|
fmt::internal::make_args_checked<Args...>(format, args...)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharType>
|
template <typename Char>
|
||||||
inline void reportSource(Level severity, const char* file, unsigned linenum, const CharType* format, va_list ap) {
|
void vreportSource(Level severity, const char* file, unsigned linenum, fmt::basic_string_view<Char> format,
|
||||||
auto lk = LockLog();
|
fmt::basic_format_args<fmt::buffer_context<Char>> args) {
|
||||||
++_LogCounter;
|
if (MainLoggers.empty() && severity != Level::Fatal)
|
||||||
if (severity == Fatal)
|
return;
|
||||||
RegisterConsoleLogger();
|
_vreportSource(severity, file, linenum, format, args);
|
||||||
for (auto& logger : MainLoggers) {
|
|
||||||
va_list apc;
|
|
||||||
va_copy(apc, ap);
|
|
||||||
logger->reportSource(m_modName, severity, file, linenum, format, apc);
|
|
||||||
va_end(apc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (severity == Fatal)
|
|
||||||
logvisorAbort();
|
|
||||||
else if (severity == Error)
|
|
||||||
++ErrorCount;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define Lfmt(str) fmt(L##str)
|
||||||
|
#define ufmt(str) fmt(u##str)
|
||||||
|
#define Ufmt(str) fmt(U##str)
|
||||||
|
#define FMT_CUSTOM_FORMATTER(tp, ...) \
|
||||||
|
namespace fmt { \
|
||||||
|
template <> \
|
||||||
|
struct formatter<tp, char> { \
|
||||||
|
template <typename ParseContext> \
|
||||||
|
constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
|
||||||
|
template <typename FormatContext> \
|
||||||
|
auto format(const tp &obj, FormatContext &ctx) { \
|
||||||
|
return format_to(ctx.out(), __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
template <> \
|
||||||
|
struct formatter<tp, wchar_t> { \
|
||||||
|
template <typename ParseContext> \
|
||||||
|
constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
|
||||||
|
template <typename FormatContext> \
|
||||||
|
auto format(const tp &obj, FormatContext &ctx) { \
|
||||||
|
return format_to(ctx.out(), L##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
template <> \
|
||||||
|
struct formatter<tp, char16_t> { \
|
||||||
|
template <typename ParseContext> \
|
||||||
|
constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
|
||||||
|
template <typename FormatContext> \
|
||||||
|
auto format(const tp &obj, FormatContext &ctx) { \
|
||||||
|
return format_to(ctx.out(), u##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
template <> \
|
||||||
|
struct formatter<tp, char32_t> { \
|
||||||
|
template <typename ParseContext> \
|
||||||
|
constexpr auto parse(ParseContext &ctx) { return ctx.begin(); } \
|
||||||
|
template <typename FormatContext> \
|
||||||
|
auto format(const tp &obj, FormatContext &ctx) { \
|
||||||
|
return format_to(ctx.out(), U##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace logvisor
|
} // namespace logvisor
|
||||||
|
|
195
lib/logvisor.cpp
195
lib/logvisor.cpp
|
@ -184,25 +184,22 @@ void logvisorAbort() {
|
||||||
readlink("/proc/self/exe", exeNameBuffer, exeBufSize);
|
readlink("/proc/self/exe", exeNameBuffer, exeBufSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char cmdLine[1024];
|
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
snprintf(cmdLine, 1024, "atos -p %d", getpid());
|
std::string cmdLineStr = fmt::format(fmt("atos -p {}"), getpid());
|
||||||
#else
|
#else
|
||||||
snprintf(cmdLine, 1024, "2>/dev/null addr2line -C -f -e \"%s\"", exeNameBuffer);
|
std::string cmdLineStr = fmt::format(fmt("2>/dev/null addr2line -C -f -e \"{}\""), exeNameBuffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string cmdLineStr = cmdLine;
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
#if __linux__
|
#if __linux__
|
||||||
Dl_info dlip;
|
Dl_info dlip;
|
||||||
if (dladdr(array[i], &dlip))
|
if (dladdr(array[i], &dlip))
|
||||||
snprintf(cmdLine, 128, " %p", (void*)((uint8_t*)array[i] - (uint8_t*)dlip.dli_fbase));
|
cmdLineStr += fmt::format(fmt(" 0x{:016X}"), (uintptr_t)((uint8_t*)array[i] - (uint8_t*)dlip.dli_fbase));
|
||||||
else
|
else
|
||||||
snprintf(cmdLine, 128, " %p", array[i]);
|
cmdLineStr += fmt::format(fmt(" 0x{:016X}"), (uintptr_t)array[i]);
|
||||||
#else
|
#else
|
||||||
snprintf(cmdLine, 128, " %p", array[i]);
|
cmdLineStr += fmt::format(fmt(" 0x{:016X}"), (uintptr_t)array[i]);
|
||||||
#endif
|
#endif
|
||||||
cmdLineStr += cmdLine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* fp = popen(cmdLineStr.c_str(), "r");
|
FILE* fp = popen(cmdLineStr.c_str(), "r");
|
||||||
|
@ -210,26 +207,26 @@ void logvisorAbort() {
|
||||||
char readBuf[256];
|
char readBuf[256];
|
||||||
size_t readSz;
|
size_t readSz;
|
||||||
while ((readSz = fread(readBuf, 1, 256, fp)))
|
while ((readSz = fread(readBuf, 1, 256, fp)))
|
||||||
fwrite(readBuf, 1, readSz, stderr);
|
std::fwrite(readBuf, 1, readSz, stderr);
|
||||||
pclose(fp);
|
pclose(fp);
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
fprintf(stderr, "- ");
|
std::fputs("- ", stderr);
|
||||||
Dl_info dlip;
|
Dl_info dlip;
|
||||||
if (dladdr(array[i], &dlip)) {
|
if (dladdr(array[i], &dlip)) {
|
||||||
int status;
|
int status;
|
||||||
char* demangledName = abi::__cxa_demangle(dlip.dli_sname, nullptr, nullptr, &status);
|
char* demangledName = abi::__cxa_demangle(dlip.dli_sname, nullptr, nullptr, &status);
|
||||||
fprintf(stderr, "%p(%s+%p)\n", dlip.dli_saddr, demangledName ? demangledName : dlip.dli_sname,
|
std::fprintf(stderr, "%p(%s+%p)\n", dlip.dli_saddr, demangledName ? demangledName : dlip.dli_sname,
|
||||||
(void*)((uint8_t*)array[i] - (uint8_t*)dlip.dli_fbase));
|
(void*)((uint8_t*)array[i] - (uint8_t*)dlip.dli_fbase));
|
||||||
free(demangledName);
|
std::free(demangledName);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%p\n", array[i]);
|
std::fprintf(stderr, "%p\n", array[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush(stderr);
|
std::fflush(stderr);
|
||||||
fflush(stdout);
|
std::fflush(stdout);
|
||||||
KillProcessTree();
|
KillProcessTree();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -248,19 +245,19 @@ static void AbortHandler(int signum) {
|
||||||
_LogMutex.enabled = false;
|
_LogMutex.enabled = false;
|
||||||
switch (signum) {
|
switch (signum) {
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
Log.report(logvisor::Fatal, "Segmentation Fault");
|
Log.report(logvisor::Fatal, fmt("Segmentation Fault"));
|
||||||
break;
|
break;
|
||||||
case SIGILL:
|
case SIGILL:
|
||||||
Log.report(logvisor::Fatal, "Bad Execution");
|
Log.report(logvisor::Fatal, fmt("Bad Execution"));
|
||||||
break;
|
break;
|
||||||
case SIGFPE:
|
case SIGFPE:
|
||||||
Log.report(logvisor::Fatal, "Floating Point Exception");
|
Log.report(logvisor::Fatal, fmt("Floating Point Exception"));
|
||||||
break;
|
break;
|
||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
Log.report(logvisor::Fatal, "Abort Signal");
|
Log.report(logvisor::Fatal, fmt("Abort Signal"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.report(logvisor::Fatal, "unknown signal %d", signum);
|
Log.report(logvisor::Fatal, fmt("unknown signal {}"), signum);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,10 +321,10 @@ struct ConsoleLogger : public ILogger {
|
||||||
static void _reportHead(const char* modName, const char* sourceInfo, Level severity) {
|
static void _reportHead(const char* modName, const char* sourceInfo, Level severity) {
|
||||||
/* Clear current line out */
|
/* Clear current line out */
|
||||||
int width = ConsoleWidth();
|
int width = ConsoleWidth();
|
||||||
fprintf(stderr, "\r");
|
std::fputs("\r", stderr);
|
||||||
for (int w = 0; w < width; ++w)
|
for (int w = 0; w < width; ++w)
|
||||||
fprintf(stderr, " ");
|
std::fputs(" ", stderr);
|
||||||
fprintf(stderr, "\r");
|
std::fputs("\r", stderr);
|
||||||
|
|
||||||
std::chrono::steady_clock::duration tm = CurrentUptime();
|
std::chrono::steady_clock::duration tm = CurrentUptime();
|
||||||
double tmd = tm.count() * std::chrono::steady_clock::duration::period::num /
|
double tmd = tm.count() * std::chrono::steady_clock::duration::period::num /
|
||||||
|
@ -338,33 +335,33 @@ struct ConsoleLogger : public ILogger {
|
||||||
thrName = ThreadMap[thrId];
|
thrName = ThreadMap[thrId];
|
||||||
|
|
||||||
if (XtermColor) {
|
if (XtermColor) {
|
||||||
fprintf(stderr, BOLD "[");
|
std::fputs(BOLD "[", stderr);
|
||||||
fprintf(stderr, GREEN "%5.4f ", tmd);
|
fmt::print(stderr, fmt(GREEN "{:5.4} "), tmd);
|
||||||
uint_fast64_t fIdx = FrameIndex.load();
|
uint_fast64_t fIdx = FrameIndex.load();
|
||||||
if (fIdx)
|
if (fIdx)
|
||||||
fprintf(stderr, "(%" PRIu64 ") ", fIdx);
|
fmt::print(stderr, fmt("({}) "), fIdx);
|
||||||
switch (severity) {
|
switch (severity) {
|
||||||
case Info:
|
case Info:
|
||||||
fprintf(stderr, BOLD CYAN "INFO");
|
std::fputs(BOLD CYAN "INFO", stderr);
|
||||||
break;
|
break;
|
||||||
case Warning:
|
case Warning:
|
||||||
fprintf(stderr, BOLD YELLOW "WARNING");
|
std::fputs(BOLD YELLOW "WARNING", stderr);
|
||||||
break;
|
break;
|
||||||
case Error:
|
case Error:
|
||||||
fprintf(stderr, RED BOLD "ERROR");
|
std::fputs(RED BOLD "ERROR", stderr);
|
||||||
break;
|
break;
|
||||||
case Fatal:
|
case Fatal:
|
||||||
fprintf(stderr, BOLD RED "FATAL ERROR");
|
std::fputs(BOLD RED "FATAL ERROR", stderr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
fprintf(stderr, NORMAL BOLD " %s", modName);
|
fmt::print(stderr, fmt(NORMAL BOLD " {}"), modName);
|
||||||
if (sourceInfo)
|
if (sourceInfo)
|
||||||
fprintf(stderr, BOLD YELLOW " {%s}", sourceInfo);
|
fmt::print(stderr, fmt(BOLD YELLOW " {{}}"), sourceInfo);
|
||||||
if (thrName)
|
if (thrName)
|
||||||
fprintf(stderr, BOLD MAGENTA " (%s)", thrName);
|
fmt::print(stderr, fmt(BOLD MAGENTA " ({})"), thrName);
|
||||||
fprintf(stderr, NORMAL BOLD "] " NORMAL);
|
std::fputs(NORMAL BOLD "] " NORMAL, stderr);
|
||||||
} else {
|
} else {
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
|
@ -408,69 +405,65 @@ struct ConsoleLogger : public ILogger {
|
||||||
SetConsoleTextAttribute(Term, FOREGROUND_WHITE);
|
SetConsoleTextAttribute(Term, FOREGROUND_WHITE);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "[");
|
std::fputs("[", stderr);
|
||||||
fprintf(stderr, "%5.4f ", tmd);
|
fmt::print(stderr, fmt("{:5.4} "), tmd);
|
||||||
uint_fast64_t fIdx = FrameIndex.load();
|
uint_fast64_t fIdx = FrameIndex.load();
|
||||||
if (fIdx)
|
if (fIdx)
|
||||||
fprintf(stderr, "(%" PRIu64 ") ", fIdx);
|
fmt::print(stderr, fmt("({}) "), fIdx);
|
||||||
switch (severity) {
|
switch (severity) {
|
||||||
case Info:
|
case Info:
|
||||||
fprintf(stderr, "INFO");
|
std::fputs("INFO", stderr);
|
||||||
break;
|
break;
|
||||||
case Warning:
|
case Warning:
|
||||||
fprintf(stderr, "WARNING");
|
std::fputs("WARNING", stderr);
|
||||||
break;
|
break;
|
||||||
case Error:
|
case Error:
|
||||||
fprintf(stderr, "ERROR");
|
std::fputs("ERROR", stderr);
|
||||||
break;
|
break;
|
||||||
case Fatal:
|
case Fatal:
|
||||||
fprintf(stderr, "FATAL ERROR");
|
std::fputs("FATAL ERROR", stderr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
fprintf(stderr, " %s", modName);
|
fmt::print(stderr, fmt(" {}"), modName);
|
||||||
if (sourceInfo)
|
if (sourceInfo)
|
||||||
fprintf(stderr, " {%s}", sourceInfo);
|
fmt::print(stderr, fmt(" {{}}"), sourceInfo);
|
||||||
if (thrName)
|
if (thrName)
|
||||||
fprintf(stderr, " (%s)", thrName);
|
fmt::print(stderr, fmt(" ({})"), thrName);
|
||||||
fprintf(stderr, "] ");
|
std::fputs("] ", stderr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void report(const char* modName, Level severity, const char* format, va_list ap) {
|
void report(const char* modName, Level severity, fmt::string_view format, fmt::format_args args) {
|
||||||
_reportHead(modName, nullptr, severity);
|
_reportHead(modName, nullptr, severity);
|
||||||
vfprintf(stderr, format, ap);
|
fmt::vprint(stderr, format, args);
|
||||||
fprintf(stderr, "\n");
|
std::fputs("\n", stderr);
|
||||||
fflush(stderr);
|
std::fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void report(const char* modName, Level severity, const wchar_t* format, va_list ap) {
|
void report(const char* modName, Level severity, fmt::wstring_view format, fmt::wformat_args args) {
|
||||||
_reportHead(modName, nullptr, severity);
|
_reportHead(modName, nullptr, severity);
|
||||||
vfwprintf(stderr, format, ap);
|
fmt::vprint(stderr, format, args);
|
||||||
fprintf(stderr, "\n");
|
std::fputs("\n", stderr);
|
||||||
fflush(stderr);
|
std::fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const char* format,
|
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
|
||||||
va_list ap) {
|
fmt::string_view format, fmt::format_args args) {
|
||||||
char sourceInfo[128];
|
_reportHead(modName, fmt::format(fmt("{}:{}"), file, linenum).c_str(), severity);
|
||||||
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
fmt::vprint(stderr, format, args);
|
||||||
_reportHead(modName, sourceInfo, severity);
|
std::fputs("\n", stderr);
|
||||||
vfprintf(stderr, format, ap);
|
std::fflush(stderr);
|
||||||
fprintf(stderr, "\n");
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const wchar_t* format,
|
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
|
||||||
va_list ap) {
|
fmt::wstring_view format, fmt::wformat_args args) {
|
||||||
char sourceInfo[128];
|
_reportHead(modName, fmt::format(fmt("{}:{}"), file, linenum).c_str(), severity);
|
||||||
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
fmt::vprint(stderr, format, args);
|
||||||
_reportHead(modName, sourceInfo, severity);
|
std::fputs("\n", stderr);
|
||||||
vfwprintf(stderr, format, ap);
|
std::fflush(stderr);
|
||||||
fprintf(stderr, "\n");
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -502,7 +495,7 @@ void RegisterStandardExceptions() {
|
||||||
struct FileLogger : public ILogger {
|
struct FileLogger : public ILogger {
|
||||||
FILE* fp;
|
FILE* fp;
|
||||||
virtual void openFile() = 0;
|
virtual void openFile() = 0;
|
||||||
virtual void closeFile() { fclose(fp); }
|
virtual void closeFile() { std::fclose(fp); }
|
||||||
|
|
||||||
void _reportHead(const char* modName, const char* sourceInfo, Level severity) {
|
void _reportHead(const char* modName, const char* sourceInfo, Level severity) {
|
||||||
std::chrono::steady_clock::duration tm = CurrentUptime();
|
std::chrono::steady_clock::duration tm = CurrentUptime();
|
||||||
|
@ -513,70 +506,66 @@ struct FileLogger : public ILogger {
|
||||||
if (ThreadMap.find(thrId) != ThreadMap.end())
|
if (ThreadMap.find(thrId) != ThreadMap.end())
|
||||||
thrName = ThreadMap[thrId];
|
thrName = ThreadMap[thrId];
|
||||||
|
|
||||||
fprintf(fp, "[");
|
std::fputs("[", fp);
|
||||||
fprintf(fp, "%5.4f ", tmd);
|
std::fprintf(fp, "%5.4f ", tmd);
|
||||||
uint_fast64_t fIdx = FrameIndex.load();
|
uint_fast64_t fIdx = FrameIndex.load();
|
||||||
if (fIdx)
|
if (fIdx)
|
||||||
fprintf(fp, "(%" PRIu64 ") ", fIdx);
|
std::fprintf(fp, "(%" PRIu64 ") ", fIdx);
|
||||||
switch (severity) {
|
switch (severity) {
|
||||||
case Info:
|
case Info:
|
||||||
fprintf(fp, "INFO");
|
std::fputs("INFO", fp);
|
||||||
break;
|
break;
|
||||||
case Warning:
|
case Warning:
|
||||||
fprintf(fp, "WARNING");
|
std::fputs("WARNING", fp);
|
||||||
break;
|
break;
|
||||||
case Error:
|
case Error:
|
||||||
fprintf(fp, "ERROR");
|
std::fputs("ERROR", fp);
|
||||||
break;
|
break;
|
||||||
case Fatal:
|
case Fatal:
|
||||||
fprintf(fp, "FATAL ERROR");
|
std::fputs("FATAL ERROR", fp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
fprintf(fp, " %s", modName);
|
std::fprintf(fp, " %s", modName);
|
||||||
if (sourceInfo)
|
if (sourceInfo)
|
||||||
fprintf(fp, " {%s}", sourceInfo);
|
std::fprintf(fp, " {%s}", sourceInfo);
|
||||||
if (thrName)
|
if (thrName)
|
||||||
fprintf(fp, " (%s)", thrName);
|
std::fprintf(fp, " (%s)", thrName);
|
||||||
fprintf(fp, "] ");
|
std::fputs("] ", fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void report(const char* modName, Level severity, const char* format, va_list ap) {
|
void report(const char* modName, Level severity, fmt::string_view format, fmt::format_args args) {
|
||||||
openFile();
|
openFile();
|
||||||
_reportHead(modName, nullptr, severity);
|
_reportHead(modName, nullptr, severity);
|
||||||
vfprintf(fp, format, ap);
|
fmt::vprint(fp, format, args);
|
||||||
fprintf(fp, "\n");
|
std::fputs("\n", fp);
|
||||||
closeFile();
|
closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void report(const char* modName, Level severity, const wchar_t* format, va_list ap) {
|
void report(const char* modName, Level severity, fmt::wstring_view format, fmt::wformat_args args) {
|
||||||
openFile();
|
openFile();
|
||||||
_reportHead(modName, nullptr, severity);
|
_reportHead(modName, nullptr, severity);
|
||||||
vfwprintf(fp, format, ap);
|
fmt::vprint(fp, format, args);
|
||||||
fprintf(fp, "\n");
|
std::fputs("\n", fp);
|
||||||
closeFile();
|
closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const char* format,
|
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
|
||||||
va_list ap) {
|
fmt::string_view format, fmt::format_args args) {
|
||||||
openFile();
|
openFile();
|
||||||
char sourceInfo[128];
|
_reportHead(modName, fmt::format(fmt("{}:{}"), file, linenum).c_str(), severity);
|
||||||
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
fmt::vprint(fp, format, args);
|
||||||
_reportHead(modName, sourceInfo, severity);
|
std::fputs("\n", fp);
|
||||||
vfprintf(fp, format, ap);
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
closeFile();
|
closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const wchar_t* format,
|
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
|
||||||
va_list ap) {
|
fmt::wstring_view format, fmt::wformat_args args) {
|
||||||
openFile();
|
openFile();
|
||||||
char sourceInfo[128];
|
_reportHead(modName, fmt::format(fmt("{}:{}"), file, linenum).c_str(), severity);
|
||||||
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
fmt::vprint(fp, format, args);
|
||||||
_reportHead(modName, sourceInfo, severity);
|
std::fputs("\n", fp);
|
||||||
vfwprintf(fp, format, ap);
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
closeFile();
|
closeFile();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -584,7 +573,7 @@ struct FileLogger : public ILogger {
|
||||||
struct FileLogger8 : public FileLogger {
|
struct FileLogger8 : public FileLogger {
|
||||||
const char* m_filepath;
|
const char* m_filepath;
|
||||||
FileLogger8(const char* filepath) : m_filepath(filepath) {}
|
FileLogger8(const char* filepath) : m_filepath(filepath) {}
|
||||||
void openFile() { fp = fopen(m_filepath, "a"); }
|
void openFile() { fp = std::fopen(m_filepath, "a"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void RegisterFileLogger(const char* filepath) {
|
void RegisterFileLogger(const char* filepath) {
|
||||||
|
|
Loading…
Reference in New Issue