mirror of https://github.com/AxioDL/logvisor.git
New code style refactor
This commit is contained in:
parent
1b6c2ae715
commit
01e291833b
|
@ -15,8 +15,7 @@
|
||||||
|
|
||||||
extern "C" void logvisorBp();
|
extern "C" void logvisorBp();
|
||||||
|
|
||||||
namespace logvisor
|
namespace logvisor {
|
||||||
{
|
|
||||||
|
|
||||||
void logvisorAbort();
|
void logvisorAbort();
|
||||||
|
|
||||||
|
@ -30,8 +29,7 @@ extern bool XtermColor;
|
||||||
/**
|
/**
|
||||||
* @brief Severity level for log messages
|
* @brief Severity level for log messages
|
||||||
*/
|
*/
|
||||||
enum Level
|
enum Level {
|
||||||
{
|
|
||||||
Info, /**< Non-error informative message */
|
Info, /**< Non-error informative message */
|
||||||
Warning, /**< Non-error warning message */
|
Warning, /**< Non-error warning message */
|
||||||
Error, /**< Recoverable error message */
|
Error, /**< Recoverable error message */
|
||||||
|
@ -41,19 +39,14 @@ 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() {}
|
||||||
virtual void report(const char* modName, Level severity,
|
virtual void report(const char* modName, Level severity, const char* format, va_list ap) = 0;
|
||||||
const char* format, va_list ap)=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,
|
virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const char* format,
|
||||||
const wchar_t* format, va_list ap)=0;
|
va_list ap) = 0;
|
||||||
virtual void reportSource(const char* modName, Level severity,
|
virtual void reportSource(const char* modName, Level severity, const char* file, unsigned linenum,
|
||||||
const char* file, unsigned linenum,
|
const wchar_t* format, va_list ap) = 0;
|
||||||
const char* format, va_list ap)=0;
|
|
||||||
virtual void reportSource(const char* modName, Level severity,
|
|
||||||
const char* file, unsigned linenum,
|
|
||||||
const wchar_t* format, va_list ap)=0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,13 +90,11 @@ extern std::atomic_uint_fast64_t FrameIndex;
|
||||||
*
|
*
|
||||||
* Ensures logging streams aren't written concurrently
|
* Ensures logging streams aren't written concurrently
|
||||||
*/
|
*/
|
||||||
struct LogMutex
|
struct LogMutex {
|
||||||
{
|
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
std::recursive_mutex mutex;
|
std::recursive_mutex mutex;
|
||||||
~LogMutex() { enabled = false; }
|
~LogMutex() { enabled = false; }
|
||||||
std::unique_lock<std::recursive_mutex> lock()
|
std::unique_lock<std::recursive_mutex> lock() {
|
||||||
{
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
return std::unique_lock<std::recursive_mutex>(mutex);
|
return std::unique_lock<std::recursive_mutex>(mutex);
|
||||||
else
|
else
|
||||||
|
@ -116,10 +107,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()
|
static inline std::unique_lock<std::recursive_mutex> LockLog() { return _LogMutex.lock(); }
|
||||||
{
|
|
||||||
return _LogMutex.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern uint64_t _LogCounter;
|
extern uint64_t _LogCounter;
|
||||||
|
|
||||||
|
@ -127,15 +115,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()
|
static inline uint64_t GetLogCounter() { return _LogCounter; }
|
||||||
{
|
|
||||||
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();}
|
static 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
|
||||||
|
@ -180,9 +165,9 @@ void RegisterFileLogger(const wchar_t* filepath);
|
||||||
/**
|
/**
|
||||||
* @brief This is constructed per-subsystem in a locally centralized fashon
|
* @brief This is constructed per-subsystem in a locally centralized fashon
|
||||||
*/
|
*/
|
||||||
class Module
|
class Module {
|
||||||
{
|
|
||||||
const char* m_modName;
|
const char* m_modName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Module(const char* modName) : m_modName(modName) {}
|
Module(const char* modName) : m_modName(modName) {}
|
||||||
|
|
||||||
|
@ -192,8 +177,7 @@ public:
|
||||||
* @param format Standard printf-style format string
|
* @param format Standard printf-style format string
|
||||||
*/
|
*/
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
inline void report(Level severity, const CharType* format, ...)
|
inline void report(Level severity, const CharType* format, ...) {
|
||||||
{
|
|
||||||
if (MainLoggers.empty() && severity != Level::Fatal)
|
if (MainLoggers.empty() && severity != Level::Fatal)
|
||||||
return;
|
return;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -203,14 +187,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
inline void report(Level severity, const CharType* format, va_list ap)
|
inline void report(Level severity, const CharType* format, va_list ap) {
|
||||||
{
|
|
||||||
auto lk = LockLog();
|
auto lk = LockLog();
|
||||||
++_LogCounter;
|
++_LogCounter;
|
||||||
if (severity == Fatal)
|
if (severity == Fatal)
|
||||||
RegisterConsoleLogger();
|
RegisterConsoleLogger();
|
||||||
for (auto& logger : MainLoggers)
|
for (auto& logger : MainLoggers) {
|
||||||
{
|
|
||||||
va_list apc;
|
va_list apc;
|
||||||
va_copy(apc, ap);
|
va_copy(apc, ap);
|
||||||
logger->report(m_modName, severity, format, apc);
|
logger->report(m_modName, severity, format, apc);
|
||||||
|
@ -232,8 +214,7 @@ public:
|
||||||
* @param format Standard printf-style format string
|
* @param format Standard printf-style format string
|
||||||
*/
|
*/
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
inline void reportSource(Level severity, const char* file, unsigned linenum, const CharType* format, ...)
|
inline void reportSource(Level severity, const char* file, unsigned linenum, const CharType* format, ...) {
|
||||||
{
|
|
||||||
if (MainLoggers.empty() && severity != Level::Fatal)
|
if (MainLoggers.empty() && severity != Level::Fatal)
|
||||||
return;
|
return;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -243,14 +224,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CharType>
|
template <typename CharType>
|
||||||
inline void reportSource(Level severity, const char* file, unsigned linenum, const CharType* format, va_list ap)
|
inline void reportSource(Level severity, const char* file, unsigned linenum, const CharType* format, va_list ap) {
|
||||||
{
|
|
||||||
auto lk = LockLog();
|
auto lk = LockLog();
|
||||||
++_LogCounter;
|
++_LogCounter;
|
||||||
if (severity == Fatal)
|
if (severity == Fatal)
|
||||||
RegisterConsoleLogger();
|
RegisterConsoleLogger();
|
||||||
for (auto& logger : MainLoggers)
|
for (auto& logger : MainLoggers) {
|
||||||
{
|
|
||||||
va_list apc;
|
va_list apc;
|
||||||
va_copy(apc, ap);
|
va_copy(apc, ap);
|
||||||
logger->reportSource(m_modName, severity, file, linenum, format, apc);
|
logger->reportSource(m_modName, severity, file, linenum, format, apc);
|
||||||
|
@ -264,5 +243,4 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace logvisor
|
||||||
|
|
||||||
|
|
217
lib/logvisor.cpp
217
lib/logvisor.cpp
|
@ -44,45 +44,37 @@
|
||||||
#define NORMAL "\x1b[0m"
|
#define NORMAL "\x1b[0m"
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#define FOREGROUND_WHITE FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE
|
#define FOREGROUND_WHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void logvisorBp() {}
|
void logvisorBp() {}
|
||||||
|
|
||||||
namespace logvisor
|
namespace logvisor {
|
||||||
{
|
|
||||||
static Module Log("logvisor");
|
static Module Log("logvisor");
|
||||||
|
|
||||||
static std::unordered_map<std::thread::id, const char*> ThreadMap;
|
static std::unordered_map<std::thread::id, const char*> ThreadMap;
|
||||||
|
|
||||||
static void AddThreadToMap(const char* name)
|
static void AddThreadToMap(const char* name) {
|
||||||
{
|
|
||||||
auto lk = LockLog();
|
auto lk = LockLog();
|
||||||
ThreadMap[std::this_thread::get_id()] = name;
|
ThreadMap[std::this_thread::get_id()] = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterThreadName(const char* name)
|
void RegisterThreadName(const char* name) {
|
||||||
{
|
|
||||||
AddThreadToMap(name);
|
AddThreadToMap(name);
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
pthread_setname_np(name);
|
pthread_setname_np(name);
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
prctl(PR_SET_NAME, name);
|
prctl(PR_SET_NAME, name);
|
||||||
#elif _MSC_VER
|
#elif _MSC_VER
|
||||||
struct
|
struct {
|
||||||
{
|
|
||||||
DWORD dwType; // Must be 0x1000.
|
DWORD dwType; // Must be 0x1000.
|
||||||
LPCSTR szName; // Pointer to name (in user addr space).
|
LPCSTR szName; // Pointer to name (in user addr space).
|
||||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||||
} info = {0x1000, name, (DWORD)-1, 0};
|
} info = {0x1000, name, (DWORD)-1, 0};
|
||||||
__try
|
__try {
|
||||||
{
|
RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
||||||
RaiseException(0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
|
} __except (EXCEPTION_EXECUTE_HANDLER) {}
|
||||||
}
|
|
||||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,28 +87,23 @@ void RegisterThreadName(const char* name)
|
||||||
#define WINDOWS_STORE 0
|
#define WINDOWS_STORE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void KillProcessTree()
|
void KillProcessTree() {
|
||||||
{
|
|
||||||
DWORD myprocID = GetCurrentProcessId();
|
DWORD myprocID = GetCurrentProcessId();
|
||||||
PROCESSENTRY32 pe = {};
|
PROCESSENTRY32 pe = {};
|
||||||
pe.dwSize = sizeof(PROCESSENTRY32);
|
pe.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
|
||||||
HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
|
||||||
if (::Process32First(hSnap, &pe))
|
if (::Process32First(hSnap, &pe)) {
|
||||||
{
|
|
||||||
BOOL bContinue = TRUE;
|
BOOL bContinue = TRUE;
|
||||||
|
|
||||||
// kill child processes
|
// kill child processes
|
||||||
while (bContinue)
|
while (bContinue) {
|
||||||
{
|
|
||||||
// only kill child processes
|
// only kill child processes
|
||||||
if (pe.th32ParentProcessID == myprocID)
|
if (pe.th32ParentProcessID == myprocID) {
|
||||||
{
|
|
||||||
HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
|
HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
|
||||||
|
|
||||||
if (hChildProc)
|
if (hChildProc) {
|
||||||
{
|
|
||||||
::TerminateProcess(hChildProc, 1);
|
::TerminateProcess(hChildProc, 1);
|
||||||
::CloseHandle(hChildProc);
|
::CloseHandle(hChildProc);
|
||||||
}
|
}
|
||||||
|
@ -127,8 +114,7 @@ void KillProcessTree()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void logvisorAbort()
|
void logvisorAbort() {
|
||||||
{
|
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
void* stack[100];
|
void* stack[100];
|
||||||
|
@ -143,8 +129,7 @@ void logvisorAbort()
|
||||||
symbol->MaxNameLen = 255;
|
symbol->MaxNameLen = 255;
|
||||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
|
||||||
for (i = 0; i < frames; i++)
|
for (i = 0; i < frames; i++) {
|
||||||
{
|
|
||||||
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
|
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
|
||||||
|
|
||||||
fprintf(stderr, "%i: %s - 0x%0llX", frames - i - 1, symbol->Name, symbol->Address);
|
fprintf(stderr, "%i: %s - 0x%0llX", frames - i - 1, symbol->Name, symbol->Address);
|
||||||
|
@ -154,13 +139,10 @@ void logvisorAbort()
|
||||||
SymSetOptions(SYMOPT_LOAD_LINES);
|
SymSetOptions(SYMOPT_LOAD_LINES);
|
||||||
|
|
||||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||||
if (SymGetLineFromAddr64(process, (DWORD64)(stack[i]), &dwDisplacement, &line))
|
if (SymGetLineFromAddr64(process, (DWORD64)(stack[i]), &dwDisplacement, &line)) {
|
||||||
{
|
|
||||||
// SymGetLineFromAddr64 returned success
|
// SymGetLineFromAddr64 returned success
|
||||||
fprintf(stderr, " LINE %d\n", int(line.LineNumber));
|
fprintf(stderr, " LINE %d\n", int(line.LineNumber));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,17 +165,13 @@ void logvisorAbort()
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__SWITCH__)
|
#elif defined(__SWITCH__)
|
||||||
void logvisorAbort()
|
void logvisorAbort() { exit(1); }
|
||||||
{
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void KillProcessTree() {}
|
void KillProcessTree() {}
|
||||||
|
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
void logvisorAbort()
|
void logvisorAbort() {
|
||||||
{
|
|
||||||
void* array[128];
|
void* array[128];
|
||||||
size_t size = backtrace(array, 128);
|
size_t size = backtrace(array, 128);
|
||||||
|
|
||||||
|
@ -212,8 +190,7 @@ void logvisorAbort()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string cmdLineStr = cmdLine;
|
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))
|
||||||
|
@ -227,30 +204,23 @@ void logvisorAbort()
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* fp = popen(cmdLineStr.c_str(), "r");
|
FILE* fp = popen(cmdLineStr.c_str(), "r");
|
||||||
if (fp)
|
if (fp) {
|
||||||
{
|
|
||||||
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);
|
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, "- ");
|
fprintf(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,
|
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);
|
free(demangledName);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%p\n", array[i]);
|
fprintf(stderr, "%p\n", array[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,11 +242,9 @@ void logvisorAbort()
|
||||||
|
|
||||||
LogMutex _LogMutex;
|
LogMutex _LogMutex;
|
||||||
|
|
||||||
static void AbortHandler(int signum)
|
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, "Segmentation Fault");
|
||||||
case SIGILL:
|
case SIGILL:
|
||||||
|
@ -296,12 +264,10 @@ std::vector<std::unique_ptr<ILogger>> MainLoggers;
|
||||||
std::atomic_size_t ErrorCount(0);
|
std::atomic_size_t ErrorCount(0);
|
||||||
static std::chrono::steady_clock MonoClock;
|
static std::chrono::steady_clock MonoClock;
|
||||||
static std::chrono::steady_clock::time_point GlobalStart = MonoClock.now();
|
static std::chrono::steady_clock::time_point GlobalStart = MonoClock.now();
|
||||||
static inline std::chrono::steady_clock::duration CurrentUptime()
|
static inline std::chrono::steady_clock::duration CurrentUptime() { return MonoClock.now() - GlobalStart; }
|
||||||
{return MonoClock.now() - GlobalStart;}
|
|
||||||
std::atomic_uint_fast64_t FrameIndex(0);
|
std::atomic_uint_fast64_t FrameIndex(0);
|
||||||
|
|
||||||
static inline int ConsoleWidth()
|
static inline int ConsoleWidth() {
|
||||||
{
|
|
||||||
int retval = 80;
|
int retval = 80;
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
|
@ -327,10 +293,8 @@ static HANDLE Term = 0;
|
||||||
static const char* Term = nullptr;
|
static const char* Term = nullptr;
|
||||||
#endif
|
#endif
|
||||||
bool XtermColor = false;
|
bool XtermColor = false;
|
||||||
struct ConsoleLogger : public ILogger
|
struct ConsoleLogger : public ILogger {
|
||||||
{
|
ConsoleLogger() {
|
||||||
ConsoleLogger()
|
|
||||||
{
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
const char* conemuANSI = getenv("ConEmuANSI");
|
const char* conemuANSI = getenv("ConEmuANSI");
|
||||||
|
@ -340,11 +304,9 @@ struct ConsoleLogger : public ILogger
|
||||||
if (!Term)
|
if (!Term)
|
||||||
Term = GetStdHandle(STD_ERROR_HANDLE);
|
Term = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
#else
|
#else
|
||||||
if (!Term)
|
if (!Term) {
|
||||||
{
|
|
||||||
Term = getenv("TERM");
|
Term = getenv("TERM");
|
||||||
if (Term && !strncmp(Term, "xterm", 5))
|
if (Term && !strncmp(Term, "xterm", 5)) {
|
||||||
{
|
|
||||||
XtermColor = true;
|
XtermColor = true;
|
||||||
putenv((char*)"TERM=xterm-16color");
|
putenv((char*)"TERM=xterm-16color");
|
||||||
}
|
}
|
||||||
|
@ -352,33 +314,29 @@ struct ConsoleLogger : public ILogger
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
fprintf(stderr, "\r");
|
||||||
for (int w=0 ; w<width ; ++w)
|
for (int w = 0; w < width; ++w)
|
||||||
fprintf(stderr, " ");
|
fprintf(stderr, " ");
|
||||||
fprintf(stderr, "\r");
|
fprintf(stderr, "\r");
|
||||||
|
|
||||||
std::chrono::steady_clock::duration tm = CurrentUptime();
|
std::chrono::steady_clock::duration tm = CurrentUptime();
|
||||||
double tmd = tm.count() *
|
double tmd = tm.count() * std::chrono::steady_clock::duration::period::num /
|
||||||
std::chrono::steady_clock::duration::period::num /
|
|
||||||
(double)std::chrono::steady_clock::duration::period::den;
|
(double)std::chrono::steady_clock::duration::period::den;
|
||||||
std::thread::id thrId = std::this_thread::get_id();
|
std::thread::id thrId = std::this_thread::get_id();
|
||||||
const char* thrName = nullptr;
|
const char* thrName = nullptr;
|
||||||
if (ThreadMap.find(thrId) != ThreadMap.end())
|
if (ThreadMap.find(thrId) != ThreadMap.end())
|
||||||
thrName = ThreadMap[thrId];
|
thrName = ThreadMap[thrId];
|
||||||
|
|
||||||
if (XtermColor)
|
if (XtermColor) {
|
||||||
{
|
|
||||||
fprintf(stderr, BOLD "[");
|
fprintf(stderr, BOLD "[");
|
||||||
fprintf(stderr, GREEN "%5.4f ", tmd);
|
fprintf(stderr, GREEN "%5.4f ", tmd);
|
||||||
uint_fast64_t fIdx = FrameIndex.load();
|
uint_fast64_t fIdx = FrameIndex.load();
|
||||||
if (fIdx)
|
if (fIdx)
|
||||||
fprintf(stderr, "(%" PRIu64 ") ", fIdx);
|
fprintf(stderr, "(%" PRIu64 ") ", fIdx);
|
||||||
switch (severity)
|
switch (severity) {
|
||||||
{
|
|
||||||
case Info:
|
case Info:
|
||||||
fprintf(stderr, BOLD CYAN "INFO");
|
fprintf(stderr, BOLD CYAN "INFO");
|
||||||
break;
|
break;
|
||||||
|
@ -400,9 +358,7 @@ struct ConsoleLogger : public ILogger
|
||||||
if (thrName)
|
if (thrName)
|
||||||
fprintf(stderr, BOLD MAGENTA " (%s)", thrName);
|
fprintf(stderr, BOLD MAGENTA " (%s)", thrName);
|
||||||
fprintf(stderr, NORMAL BOLD "] " NORMAL);
|
fprintf(stderr, NORMAL BOLD "] " NORMAL);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
SetConsoleTextAttribute(Term, FOREGROUND_INTENSITY | FOREGROUND_WHITE);
|
SetConsoleTextAttribute(Term, FOREGROUND_INTENSITY | FOREGROUND_WHITE);
|
||||||
|
@ -412,8 +368,7 @@ struct ConsoleLogger : public ILogger
|
||||||
uint64_t fi = FrameIndex.load();
|
uint64_t fi = FrameIndex.load();
|
||||||
if (fi)
|
if (fi)
|
||||||
fprintf(stderr, "(%" PRIu64 ") ", fi);
|
fprintf(stderr, "(%" PRIu64 ") ", fi);
|
||||||
switch (severity)
|
switch (severity) {
|
||||||
{
|
|
||||||
case Info:
|
case Info:
|
||||||
SetConsoleTextAttribute(Term, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
SetConsoleTextAttribute(Term, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||||
fprintf(stderr, "INFO");
|
fprintf(stderr, "INFO");
|
||||||
|
@ -451,8 +406,7 @@ struct ConsoleLogger : public ILogger
|
||||||
uint_fast64_t fIdx = FrameIndex.load();
|
uint_fast64_t fIdx = FrameIndex.load();
|
||||||
if (fIdx)
|
if (fIdx)
|
||||||
fprintf(stderr, "(%" PRIu64 ") ", fIdx);
|
fprintf(stderr, "(%" PRIu64 ") ", fIdx);
|
||||||
switch (severity)
|
switch (severity) {
|
||||||
{
|
|
||||||
case Info:
|
case Info:
|
||||||
fprintf(stderr, "INFO");
|
fprintf(stderr, "INFO");
|
||||||
break;
|
break;
|
||||||
|
@ -478,28 +432,22 @@ struct ConsoleLogger : public ILogger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void report(const char* modName, Level severity,
|
void report(const char* modName, Level severity, const char* format, va_list ap) {
|
||||||
const char* format, va_list ap)
|
|
||||||
{
|
|
||||||
_reportHead(modName, nullptr, severity);
|
_reportHead(modName, nullptr, severity);
|
||||||
vfprintf(stderr, format, ap);
|
vfprintf(stderr, format, ap);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void report(const char* modName, Level severity,
|
void report(const char* modName, Level severity, const wchar_t* format, va_list ap) {
|
||||||
const wchar_t* format, va_list ap)
|
|
||||||
{
|
|
||||||
_reportHead(modName, nullptr, severity);
|
_reportHead(modName, nullptr, severity);
|
||||||
vfwprintf(stderr, format, ap);
|
vfwprintf(stderr, format, ap);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportSource(const char* modName, Level severity,
|
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const char* format,
|
||||||
const char* file, unsigned linenum,
|
va_list ap) {
|
||||||
const char* format, va_list ap)
|
|
||||||
{
|
|
||||||
char sourceInfo[128];
|
char sourceInfo[128];
|
||||||
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
||||||
_reportHead(modName, sourceInfo, severity);
|
_reportHead(modName, sourceInfo, severity);
|
||||||
|
@ -508,10 +456,8 @@ struct ConsoleLogger : public ILogger
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportSource(const char* modName, Level severity,
|
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const wchar_t* format,
|
||||||
const char* file, unsigned linenum,
|
va_list ap) {
|
||||||
const wchar_t* format, va_list ap)
|
|
||||||
{
|
|
||||||
char sourceInfo[128];
|
char sourceInfo[128];
|
||||||
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
||||||
_reportHead(modName, sourceInfo, severity);
|
_reportHead(modName, sourceInfo, severity);
|
||||||
|
@ -521,15 +467,13 @@ struct ConsoleLogger : public ILogger
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void RegisterConsoleLogger()
|
void RegisterConsoleLogger() {
|
||||||
{
|
|
||||||
/* Otherwise construct new console logger */
|
/* Otherwise construct new console logger */
|
||||||
MainLoggers.emplace_back(new ConsoleLogger);
|
MainLoggers.emplace_back(new ConsoleLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
void CreateWin32Console()
|
void CreateWin32Console() {
|
||||||
{
|
|
||||||
#if !WINDOWS_STORE
|
#if !WINDOWS_STORE
|
||||||
/* Debug console */
|
/* Debug console */
|
||||||
AllocConsole();
|
AllocConsole();
|
||||||
|
@ -541,25 +485,21 @@ void CreateWin32Console()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void RegisterStandardExceptions()
|
void RegisterStandardExceptions() {
|
||||||
{
|
|
||||||
signal(SIGABRT, AbortHandler);
|
signal(SIGABRT, AbortHandler);
|
||||||
signal(SIGSEGV, AbortHandler);
|
signal(SIGSEGV, AbortHandler);
|
||||||
signal(SIGILL, AbortHandler);
|
signal(SIGILL, AbortHandler);
|
||||||
signal(SIGFPE, AbortHandler);
|
signal(SIGFPE, AbortHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
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() { 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();
|
||||||
double tmd = tm.count() *
|
double tmd = tm.count() * std::chrono::steady_clock::duration::period::num /
|
||||||
std::chrono::steady_clock::duration::period::num /
|
|
||||||
(double)std::chrono::steady_clock::duration::period::den;
|
(double)std::chrono::steady_clock::duration::period::den;
|
||||||
std::thread::id thrId = std::this_thread::get_id();
|
std::thread::id thrId = std::this_thread::get_id();
|
||||||
const char* thrName = nullptr;
|
const char* thrName = nullptr;
|
||||||
|
@ -571,8 +511,7 @@ struct FileLogger : public ILogger
|
||||||
uint_fast64_t fIdx = FrameIndex.load();
|
uint_fast64_t fIdx = FrameIndex.load();
|
||||||
if (fIdx)
|
if (fIdx)
|
||||||
fprintf(fp, "(%" PRIu64 ") ", fIdx);
|
fprintf(fp, "(%" PRIu64 ") ", fIdx);
|
||||||
switch (severity)
|
switch (severity) {
|
||||||
{
|
|
||||||
case Info:
|
case Info:
|
||||||
fprintf(fp, "INFO");
|
fprintf(fp, "INFO");
|
||||||
break;
|
break;
|
||||||
|
@ -596,9 +535,7 @@ struct FileLogger : public ILogger
|
||||||
fprintf(fp, "] ");
|
fprintf(fp, "] ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void report(const char* modName, Level severity,
|
void report(const char* modName, Level severity, const char* format, va_list ap) {
|
||||||
const char* format, va_list ap)
|
|
||||||
{
|
|
||||||
openFile();
|
openFile();
|
||||||
_reportHead(modName, nullptr, severity);
|
_reportHead(modName, nullptr, severity);
|
||||||
vfprintf(fp, format, ap);
|
vfprintf(fp, format, ap);
|
||||||
|
@ -606,9 +543,7 @@ struct FileLogger : public ILogger
|
||||||
closeFile();
|
closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void report(const char* modName, Level severity,
|
void report(const char* modName, Level severity, const wchar_t* format, va_list ap) {
|
||||||
const wchar_t* format, va_list ap)
|
|
||||||
{
|
|
||||||
openFile();
|
openFile();
|
||||||
_reportHead(modName, nullptr, severity);
|
_reportHead(modName, nullptr, severity);
|
||||||
vfwprintf(fp, format, ap);
|
vfwprintf(fp, format, ap);
|
||||||
|
@ -616,10 +551,8 @@ struct FileLogger : public ILogger
|
||||||
closeFile();
|
closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportSource(const char* modName, Level severity,
|
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const char* format,
|
||||||
const char* file, unsigned linenum,
|
va_list ap) {
|
||||||
const char* format, va_list ap)
|
|
||||||
{
|
|
||||||
openFile();
|
openFile();
|
||||||
char sourceInfo[128];
|
char sourceInfo[128];
|
||||||
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
||||||
|
@ -629,10 +562,8 @@ struct FileLogger : public ILogger
|
||||||
closeFile();
|
closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportSource(const char* modName, Level severity,
|
void reportSource(const char* modName, Level severity, const char* file, unsigned linenum, const wchar_t* format,
|
||||||
const char* file, unsigned linenum,
|
va_list ap) {
|
||||||
const wchar_t* format, va_list ap)
|
|
||||||
{
|
|
||||||
openFile();
|
openFile();
|
||||||
char sourceInfo[128];
|
char sourceInfo[128];
|
||||||
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
snprintf(sourceInfo, 128, "%s:%u", file, linenum);
|
||||||
|
@ -643,36 +574,30 @@ 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 = fopen(m_filepath, "a"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void RegisterFileLogger(const char* filepath)
|
void RegisterFileLogger(const char* filepath) {
|
||||||
{
|
|
||||||
/* Otherwise construct new file logger */
|
/* Otherwise construct new file logger */
|
||||||
MainLoggers.emplace_back(new FileLogger8(filepath));
|
MainLoggers.emplace_back(new FileLogger8(filepath));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LOG_UCS2
|
#if LOG_UCS2
|
||||||
|
|
||||||
struct FileLogger16 : public FileLogger
|
struct FileLogger16 : public FileLogger {
|
||||||
{
|
|
||||||
const wchar_t* m_filepath;
|
const wchar_t* m_filepath;
|
||||||
FileLogger16(const wchar_t* filepath) : m_filepath(filepath) {}
|
FileLogger16(const wchar_t* filepath) : m_filepath(filepath) {}
|
||||||
void openFile() {fp = _wfopen(m_filepath, L"a");}
|
void openFile() { fp = _wfopen(m_filepath, L"a"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void RegisterFileLogger(const wchar_t* filepath)
|
void RegisterFileLogger(const wchar_t* filepath) {
|
||||||
{
|
|
||||||
/* Determine if file logger already added */
|
/* Determine if file logger already added */
|
||||||
for (auto& logger : MainLoggers)
|
for (auto& logger : MainLoggers) {
|
||||||
{
|
|
||||||
FileLogger16* filelogger = dynamic_cast<FileLogger16*>(logger.get());
|
FileLogger16* filelogger = dynamic_cast<FileLogger16*>(logger.get());
|
||||||
if (filelogger)
|
if (filelogger) {
|
||||||
{
|
|
||||||
if (!wcscmp(filepath, filelogger->m_filepath))
|
if (!wcscmp(filepath, filelogger->m_filepath))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -684,4 +609,4 @@ void RegisterFileLogger(const wchar_t* filepath)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
} // namespace logvisor
|
||||||
|
|
Loading…
Reference in New Issue