mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-03 17:05:50 +00:00
feat(logging): add colored file:line numbers to JLOG macro
- Add LOG_LINE_NUMBERS CMake option (ON for Debug, OFF for Release) - Implement constexpr path stripping using SOURCE_ROOT_PATH - Add smart TTY detection with NO_COLOR/FORCE_COLOR support - Extend Journal::ScopedStream with file/line constructor - Update JLOG macro to conditionally include source location - Maintain backward compatibility when disabled
This commit is contained in:
@@ -33,6 +33,24 @@ if(Git_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
endif() #git
|
endif() #git
|
||||||
|
|
||||||
|
# make SOURCE_ROOT_PATH define available for logging
|
||||||
|
set(SOURCE_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/")
|
||||||
|
add_definitions(-DSOURCE_ROOT_PATH="${SOURCE_ROOT_PATH}")
|
||||||
|
|
||||||
|
# LOG_LINE_NUMBERS option - default to ON for Debug builds, OFF for Release
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
option(LOG_LINE_NUMBERS "Include file and line numbers in log messages" ON)
|
||||||
|
else()
|
||||||
|
option(LOG_LINE_NUMBERS "Include file and line numbers in log messages" OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(LOG_LINE_NUMBERS)
|
||||||
|
add_definitions(-DLOG_LINE_NUMBERS=1)
|
||||||
|
message(STATUS "Log line numbers enabled")
|
||||||
|
else()
|
||||||
|
message(STATUS "Log line numbers disabled")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(thread_safety_analysis)
|
if(thread_safety_analysis)
|
||||||
add_compile_options(-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -DRIPPLE_ENABLE_THREAD_SAFETY_ANNOTATIONS)
|
add_compile_options(-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -DRIPPLE_ENABLE_THREAD_SAFETY_ANNOTATIONS)
|
||||||
add_compile_options("-stdlib=libc++")
|
add_compile_options("-stdlib=libc++")
|
||||||
|
|||||||
@@ -249,13 +249,22 @@ private:
|
|||||||
// Wraps a Journal::Stream to skip evaluation of
|
// Wraps a Journal::Stream to skip evaluation of
|
||||||
// expensive argument lists if the stream is not active.
|
// expensive argument lists if the stream is not active.
|
||||||
#ifndef JLOG
|
#ifndef JLOG
|
||||||
|
#ifdef LOG_LINE_NUMBERS
|
||||||
#define JLOG(x) \
|
#define JLOG(x) \
|
||||||
if (!x) \
|
if (!(x)) \
|
||||||
|
{ \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
(x).writeWithLocation("", __FILE__, __LINE__)
|
||||||
|
#else
|
||||||
|
#define JLOG(x) \
|
||||||
|
if (!(x)) \
|
||||||
{ \
|
{ \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
x
|
x
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Debug logging:
|
// Debug logging:
|
||||||
|
|||||||
@@ -21,7 +21,15 @@
|
|||||||
#define BEAST_UTILITY_JOURNAL_H_INCLUDED
|
#define BEAST_UTILITY_JOURNAL_H_INCLUDED
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <io.h>
|
||||||
|
#define isatty _isatty
|
||||||
|
#define STDERR_FILENO 2
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
@@ -149,6 +157,15 @@ private:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
ScopedStream(Stream const& stream, T const& t);
|
ScopedStream(Stream const& stream, T const& t);
|
||||||
|
|
||||||
|
#ifdef LOG_LINE_NUMBERS
|
||||||
|
template <typename T>
|
||||||
|
ScopedStream(
|
||||||
|
Stream const& stream,
|
||||||
|
T const& t,
|
||||||
|
const char* file,
|
||||||
|
int line);
|
||||||
|
#endif
|
||||||
|
|
||||||
ScopedStream(Stream const& stream, std::ostream& manip(std::ostream&));
|
ScopedStream(Stream const& stream, std::ostream& manip(std::ostream&));
|
||||||
|
|
||||||
ScopedStream&
|
ScopedStream&
|
||||||
@@ -253,6 +270,12 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
ScopedStream
|
ScopedStream
|
||||||
operator<<(T const& t) const;
|
operator<<(T const& t) const;
|
||||||
|
|
||||||
|
#ifdef LOG_LINE_NUMBERS
|
||||||
|
template <typename T>
|
||||||
|
ScopedStream
|
||||||
|
writeWithLocation(T const& t, const char* file, int line) const;
|
||||||
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -361,6 +384,84 @@ Journal::ScopedStream::ScopedStream(Journal::Stream const& stream, T const& t)
|
|||||||
m_ostream << t;
|
m_ostream << t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
// Helper to strip source root path from __FILE__ at compile time
|
||||||
|
constexpr const char*
|
||||||
|
stripSourceRoot(const char* file)
|
||||||
|
{
|
||||||
|
#ifdef SOURCE_ROOT_PATH
|
||||||
|
constexpr const char* sourceRoot = SOURCE_ROOT_PATH;
|
||||||
|
constexpr auto strlen_constexpr = [](const char* s) constexpr
|
||||||
|
{
|
||||||
|
const char* p = s;
|
||||||
|
while (*p)
|
||||||
|
++p;
|
||||||
|
return p - s;
|
||||||
|
};
|
||||||
|
constexpr auto strncmp_constexpr =
|
||||||
|
[](const char* a, const char* b, size_t n) constexpr
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
if (a[i] != b[i])
|
||||||
|
return a[i] - b[i];
|
||||||
|
if (a[i] == '\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
constexpr size_t sourceRootLen = strlen_constexpr(sourceRoot);
|
||||||
|
return (strncmp_constexpr(file, sourceRoot, sourceRootLen) == 0)
|
||||||
|
? file + sourceRootLen
|
||||||
|
: file;
|
||||||
|
#else
|
||||||
|
return file;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we should use colors - cached at startup
|
||||||
|
inline bool
|
||||||
|
shouldUseColors()
|
||||||
|
{
|
||||||
|
static const bool useColors = []() {
|
||||||
|
// Honor NO_COLOR environment variable (standard)
|
||||||
|
if (std::getenv("NO_COLOR"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Honor FORCE_COLOR to override terminal detection
|
||||||
|
if (std::getenv("FORCE_COLOR"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Check if stderr is a terminal
|
||||||
|
return isatty(STDERR_FILENO) != 0;
|
||||||
|
}();
|
||||||
|
return useColors;
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
#ifdef LOG_LINE_NUMBERS
|
||||||
|
template <typename T>
|
||||||
|
Journal::ScopedStream::ScopedStream(
|
||||||
|
Journal::Stream const& stream,
|
||||||
|
T const& t,
|
||||||
|
const char* file,
|
||||||
|
int line)
|
||||||
|
: ScopedStream(stream.sink(), stream.level())
|
||||||
|
{
|
||||||
|
// Use constexpr path stripping and conditional color codes
|
||||||
|
if (detail::shouldUseColors())
|
||||||
|
{
|
||||||
|
m_ostream << "\033[36m[" << detail::stripSourceRoot(file) << ":" << line
|
||||||
|
<< "]\033[0m " << t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ostream << "[" << detail::stripSourceRoot(file) << ":" << line << "] "
|
||||||
|
<< t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::ostream&
|
std::ostream&
|
||||||
Journal::ScopedStream::operator<<(T const& t) const
|
Journal::ScopedStream::operator<<(T const& t) const
|
||||||
@@ -378,6 +479,15 @@ Journal::Stream::operator<<(T const& t) const
|
|||||||
return ScopedStream(*this, t);
|
return ScopedStream(*this, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LOG_LINE_NUMBERS
|
||||||
|
template <typename T>
|
||||||
|
Journal::ScopedStream
|
||||||
|
Journal::Stream::writeWithLocation(T const& t, const char* file, int line) const
|
||||||
|
{
|
||||||
|
return ScopedStream(*this, t, file, line);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <class CharT, class Traits = std::char_traits<CharT>>
|
template <class CharT, class Traits = std::char_traits<CharT>>
|
||||||
|
|||||||
Reference in New Issue
Block a user