refactor: move LOG_LINE_NUMBERS color logic to cpp file

Move location logging functions from Journal.h to beast_Journal.cpp to avoid
recompilation of all dependent files when color mappings change.

- Move detail::shouldUseColors() to cpp (env var checks, isatty call)
- Move detail::getLocationEscape() to cpp (color name mappings)
- Move writeLocationPrefix() to cpp (formatting logic)
- Add support for LOG_LOCATION_ESCAPE env var with color names:
  red, green, yellow, blue, magenta, cyan, white, gray/grey, orange, none
- Default remains cyan for backward compatibility

This significantly reduces compilation time when tweaking log colors.
This commit is contained in:
Nicholas Dudfield
2025-07-26 12:37:05 +07:00
parent 640b9c91f9
commit 797a5d4c5b
2 changed files with 94 additions and 44 deletions

View File

@@ -22,10 +22,6 @@
#include <cassert>
#include <sstream>
#ifdef LOG_LINE_NUMBERS
#include <cstdlib>
#include <unistd.h>
#endif
namespace beast {
@@ -216,6 +212,11 @@ public:
operator<<(std::ostream& manip(std::ostream&)) const;
private:
// Helper to write the location prefix (implemented after detail
// namespace)
void
writeLocationPrefix(ScopedStream& s) const;
const char* file_;
int line_;
const Stream& stream_;
@@ -431,23 +432,12 @@ stripSourceRoot(const char* file)
}
// 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;
bool
shouldUseColors();
// 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;
}
// Get the location escape sequence - can be overridden via LOG_LOCATION_ESCAPE
const char*
getLocationEscape();
} // namespace detail
#endif
@@ -486,18 +476,7 @@ Journal::StreamWithLocation::operator<<(T const& t) const
{
// Create a ScopedStream and inject the location info first
ScopedStream scoped(stream_.sink(), stream_.level());
if (detail::shouldUseColors())
{
scoped.ostream() << "\033[36m[" << detail::stripSourceRoot(file_) << ":"
<< line_ << "]\033[0m ";
}
else
{
scoped.ostream() << "[" << detail::stripSourceRoot(file_) << ":"
<< line_ << "] ";
}
writeLocationPrefix(scoped);
scoped.ostream() << t;
return scoped;
}

View File

@@ -19,6 +19,11 @@
#include <ripple/beast/utility/Journal.h>
#include <cassert>
#ifdef LOG_LINE_NUMBERS
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#endif
namespace beast {
@@ -160,24 +165,90 @@ Journal::Stream::operator<<(std::ostream& manip(std::ostream&)) const
#ifdef LOG_LINE_NUMBERS
//------------------------------------------------------------------------------
namespace detail {
// Check if we should use colors - cached at startup
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;
}
// Get the location escape sequence - can be overridden via LOG_LOCATION_ESCAPE
const char*
getLocationEscape()
{
static const char* escape = []() {
const char* env = std::getenv("LOG_LOCATION_ESCAPE");
if (!env)
return "\033[36m"; // Default: cyan
// Simple map of color names to escape sequences
if (std::strcmp(env, "red") == 0)
return "\033[31m";
if (std::strcmp(env, "green") == 0)
return "\033[32m";
if (std::strcmp(env, "yellow") == 0)
return "\033[33m";
if (std::strcmp(env, "blue") == 0)
return "\033[34m";
if (std::strcmp(env, "magenta") == 0)
return "\033[35m";
if (std::strcmp(env, "cyan") == 0)
return "\033[36m";
if (std::strcmp(env, "white") == 0)
return "\033[37m";
if (std::strcmp(env, "gray") == 0 || std::strcmp(env, "grey") == 0)
return "\033[90m"; // Bright black (gray)
if (std::strcmp(env, "orange") == 0)
return "\033[93m"; // Bright yellow (appears orange-ish)
if (std::strcmp(env, "none") == 0)
return "";
// Default to cyan if unknown color name
return "\033[36m";
}();
return escape;
}
} // namespace detail
// Implementation of writeLocationPrefix helper
void
Journal::StreamWithLocation::writeLocationPrefix(ScopedStream& s) const
{
if (detail::shouldUseColors())
{
s.ostream() << detail::getLocationEscape() << "["
<< detail::stripSourceRoot(file_) << ":" << line_
<< "]\033[0m ";
}
else
{
s.ostream() << "[" << detail::stripSourceRoot(file_) << ":" << line_
<< "] ";
}
}
Journal::ScopedStream
Journal::StreamWithLocation::operator<<(
std::ostream& manip(std::ostream&)) const
{
// Create a ScopedStream and inject the location info first
ScopedStream scoped(stream_.sink(), stream_.level());
if (detail::shouldUseColors())
{
scoped.ostream() << "\033[36m[" << detail::stripSourceRoot(file_) << ":"
<< line_ << "]\033[0m ";
}
else
{
scoped.ostream() << "[" << detail::stripSourceRoot(file_) << ":"
<< line_ << "] ";
}
writeLocationPrefix(scoped);
scoped.ostream() << manip;
return scoped;
}