171 lines
3.5 KiB
C++
Executable File
171 lines
3.5 KiB
C++
Executable File
// License: Modified MIT (NON-AI)
|
|
// See the LICENSE file in the root directory for license information.
|
|
// Copyright 2025 Timothy Prepscius
|
|
|
|
#pragma once
|
|
|
|
#include <unistd.h>
|
|
#include <chrono>
|
|
#include <ctime>
|
|
#include <stdio.h>
|
|
|
|
#include "../algorithm/set_has.hpp"
|
|
#include "../algorithm/is_in.hpp"
|
|
|
|
namespace tjp::core::log::detail {
|
|
|
|
TJP_CORE_HEADER_ONLY_INLINE
|
|
long timeSinceEpochMillisec()
|
|
{
|
|
using namespace std::chrono;
|
|
return duration_cast<microseconds>(system_clock::now().time_since_epoch()).count() % 1000000;
|
|
}
|
|
|
|
|
|
|
|
TJP_CORE_HEADER_ONLY_INLINE
|
|
bool detectIfColorIsAvailable()
|
|
{
|
|
// is the stdout redirected, if so no color
|
|
if (getenv("FORCE_COLOR"))
|
|
return true;
|
|
|
|
if (!isatty(fileno(stdout)))
|
|
return false;
|
|
|
|
const char* term = getenv("TERM");
|
|
if (!term)
|
|
return false;
|
|
|
|
// Some terminals support color
|
|
std::string_view term_(term);
|
|
if (term_ == "dumb")
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
using ThreadID = uint64_t;
|
|
ThreadID getCurrentThreadID();
|
|
|
|
TJP_CORE_HEADER_ONLY_INLINE
|
|
ThreadID getCurrentThreadID ()
|
|
{
|
|
#ifdef WIN32
|
|
return GetCurrentThreadId();
|
|
#else
|
|
return (ThreadID)pthread_self();
|
|
#endif
|
|
}
|
|
|
|
|
|
TJP_CORE_HEADER_ONLY_INLINE
|
|
char * GetTimeStamp (char *data, int size, char marker=0)
|
|
{
|
|
#ifdef WIN32
|
|
__time64_t ltime;
|
|
_time64( <ime );
|
|
|
|
char *timestr = _ctime64(<ime);
|
|
// auto threadID = getCurrentThreadID();
|
|
|
|
#else
|
|
std::time_t t = std::time(nullptr);
|
|
char timestr[128];
|
|
std::strftime(timestr, size, "%Y%m%d_%H:%M:%S", std::localtime(&t));
|
|
// auto threadID = getCurrentThreadID();
|
|
#endif
|
|
|
|
snprintf (data, size, "%s.%06ld", timestr, timeSinceEpochMillisec());
|
|
|
|
if (marker)
|
|
for (auto *c=data; *c; ++c)
|
|
if (*c == ':' || *c == '.')
|
|
*c = marker;
|
|
|
|
return data;
|
|
}
|
|
|
|
TJP_CORE_HEADER_ONLY_INLINE
|
|
char * __GetLogStamp__ (char *data, bool colorize)
|
|
{
|
|
char timeStamp[128];
|
|
GetTimeStamp(timeStamp, std::size(timeStamp));
|
|
|
|
auto threadID = getCurrentThreadID();
|
|
auto dataSize = 256;
|
|
|
|
if (colorize)
|
|
{
|
|
// all of the threadIDs are divisible by 128, so we use 127
|
|
auto color = (int)threadID % 127 + 1;
|
|
#if defined(SYS_LINUX) || defined(SYS_ANDROID)
|
|
snprintf (data, dataSize, "%s \033[38;5;%dm%lx\033[0m | ", timeStamp, color, threadID);
|
|
#else
|
|
snprintf (data, dataSize, "%s \033[38;5;%dm%llx\033[0m | ", timeStamp, color, threadID);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#if defined(SYS_LINUX) || defined(SYS_ANDROID)
|
|
snprintf (data, dataSize, "%s %lx | ", timeStamp, threadID);
|
|
#else
|
|
snprintf (data, dataSize, "%s %llx | ", timeStamp, threadID);
|
|
#endif
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
TJP_CORE_HEADER_ONLY_INLINE
|
|
std::string methodName(const char *prettyFunction_)
|
|
{
|
|
if (!prettyFunction_)
|
|
return "[]";
|
|
|
|
std::string_view prettyFunction(prettyFunction_);
|
|
auto end = prettyFunction.find('(');
|
|
if (end == std::string_view::npos)
|
|
end = 0;
|
|
auto begin = end;
|
|
|
|
auto stack = 0;
|
|
decltype(begin) skipEnd = 0;
|
|
decltype(begin) skipBegin = 0;
|
|
for (begin = end; begin > 0; begin--)
|
|
{
|
|
if (prettyFunction[begin] == '>')
|
|
{
|
|
if (stack == 0)
|
|
skipEnd = begin;
|
|
stack++;
|
|
}
|
|
if (prettyFunction[begin] == '<')
|
|
{
|
|
stack--;
|
|
if (stack == 0)
|
|
skipBegin = begin;
|
|
}
|
|
|
|
if (prettyFunction[begin] == ' ' && stack == 0)
|
|
break;
|
|
}
|
|
|
|
while (begin < end && is_in(prettyFunction[begin], ' ', '&', '*'))
|
|
begin = begin+1;
|
|
|
|
std::string part;
|
|
|
|
if (skipBegin != skipEnd)
|
|
part = std::string(prettyFunction.substr(begin,skipBegin-begin+1)) + std::string(prettyFunction.substr(skipEnd, end-skipEnd));
|
|
else
|
|
part = prettyFunction.substr(begin,end-begin);
|
|
|
|
if (part.size() > 30)
|
|
return part.substr(part.size() - 30);
|
|
|
|
return part;
|
|
}
|
|
|
|
} // namespace
|