flatten 20260225
This commit is contained in:
170
tjp/core/log/Util.inl
Executable file
170
tjp/core/log/Util.inl
Executable file
@@ -0,0 +1,170 @@
|
||||
// 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
|
||||
Reference in New Issue
Block a user