This is an automated email from the ASF dual-hosted git repository.

swebb2066 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git


The following commit(s) were added to refs/heads/master by this push:
     new e72dce26 Color console messages unless explicity disabled (#529)
e72dce26 is described below

commit e72dce26613b8b135ef8aff391d08f244a6fe667
Author: Stephen Webb <stephen.w...@ieee.org>
AuthorDate: Sun Aug 31 11:55:15 2025 +1000

    Color console messages unless explicity disabled (#529)
---
 src/main/cpp/basicconfigurator.cpp                 | 10 ++--
 src/main/cpp/domconfigurator.cpp                   | 24 +++++----
 src/main/cpp/loglog.cpp                            | 62 +++++++++++++++++-----
 src/main/cpp/propertyconfigurator.cpp              | 11 ++--
 src/main/include/log4cxx/basicconfigurator.h       |  5 +-
 src/main/include/log4cxx/helpers/loglog.h          | 20 +++++--
 src/site/markdown/1-usage.md                       |  1 +
 src/site/markdown/change-report-gh.md              |  4 +-
 .../{1-usage.md => colored_console_output.md}      | 31 +++--------
 src/site/markdown/example-programs.md              |  3 +-
 10 files changed, 110 insertions(+), 61 deletions(-)

diff --git a/src/main/cpp/basicconfigurator.cpp 
b/src/main/cpp/basicconfigurator.cpp
index 7839f308..e369f8ef 100644
--- a/src/main/cpp/basicconfigurator.cpp
+++ b/src/main/cpp/basicconfigurator.cpp
@@ -20,7 +20,7 @@
 #include <log4cxx/consoleappender.h>
 #include <log4cxx/logmanager.h>
 #include <log4cxx/logger.h>
-#include <log4cxx/helpers/widelife.h>
+#include <log4cxx/helpers/loglog.h>
 
 using namespace LOG4CXX_NS;
 
@@ -30,8 +30,12 @@ void BasicConfigurator::configure(const LayoutPtr& layoutArg)
        auto layout = layoutArg;
        if (!layout)
        {
-               LogString TTCC_CONVERSION_PATTERN{LOG4CXX_STR("%r [%t] %p %c %x 
- %m%n")};
-               layout = 
std::make_shared<PatternLayout>(TTCC_CONVERSION_PATTERN);
+               auto pattern = LogString
+                       { helpers::LogLog::isColorEnabled()
+                       ? LOG4CXX_STR("%r [%t] %p %c %x - %Y%m%y%n")
+                       : LOG4CXX_STR("%r [%t] %p %c %x - %m%n")
+                       };
+               layout = std::make_shared<PatternLayout>(pattern);
        }
        auto appender = std::make_shared<ConsoleAppender>(layout);
        Logger::getRootLogger()->addAppender(appender);
diff --git a/src/main/cpp/domconfigurator.cpp b/src/main/cpp/domconfigurator.cpp
index 3ec80773..6f78b3ac 100644
--- a/src/main/cpp/domconfigurator.cpp
+++ b/src/main/cpp/domconfigurator.cpp
@@ -136,6 +136,7 @@ IMPLEMENT_LOG4CXX_OBJECT(DOMConfigurator)
 #define STRINGSTREAM_ATTR "stringstream"
 #define CONFIG_DEBUG_ATTR "configDebug"
 #define INTERNAL_DEBUG_ATTR "debug"
+#define INTERNAL_COLOR_ATTR "color"
 #define THREAD_CONFIG_ATTR "threadConfiguration"
 
 DOMConfigurator::DOMConfigurator()
@@ -647,9 +648,9 @@ LayoutPtr DOMConfigurator::parseLayout (
 ObjectPtr DOMConfigurator::parseTriggeringPolicy (
        LOG4CXX_NS::helpers::Pool& p,
        LOG4CXX_NS::helpers::CharsetDecoderPtr& utf8Decoder,
-       apr_xml_elem* layout_element)
+       apr_xml_elem* policy_element)
 {
-       LogString className = subst(getAttribute(utf8Decoder, layout_element, 
CLASS_ATTR));
+       LogString className = subst(getAttribute(utf8Decoder, policy_element, 
CLASS_ATTR));
        if (LogLog::isDebugEnabled())
        {
                LogLog::debug(LOG4CXX_STR("Desired ") + 
TriggeringPolicy::getStaticClass().getName()
@@ -661,7 +662,7 @@ ObjectPtr DOMConfigurator::parseTriggeringPolicy (
                ObjectPtr instance = 
ObjectPtr(Loader::loadClass(className).newInstance());
                PropertySetter propSetter(instance);
 
-               for (apr_xml_elem* currentElement = layout_element->first_child;
+               for (apr_xml_elem* currentElement = policy_element->first_child;
                        currentElement;
                        currentElement = currentElement->next)
                {
@@ -703,9 +704,9 @@ ObjectPtr DOMConfigurator::parseTriggeringPolicy (
 RollingPolicyPtr DOMConfigurator::parseRollingPolicy (
        LOG4CXX_NS::helpers::Pool& p,
        LOG4CXX_NS::helpers::CharsetDecoderPtr& utf8Decoder,
-       apr_xml_elem* layout_element)
+       apr_xml_elem* policy_element)
 {
-       LogString className = subst(getAttribute(utf8Decoder, layout_element, 
CLASS_ATTR));
+       LogString className = subst(getAttribute(utf8Decoder, policy_element, 
CLASS_ATTR));
        if (LogLog::isDebugEnabled())
        {
                LogLog::debug(LOG4CXX_STR("Desired ") + 
RollingPolicy::getStaticClass().getName()
@@ -715,10 +716,9 @@ RollingPolicyPtr DOMConfigurator::parseRollingPolicy (
        try
        {
                ObjectPtr instance = 
ObjectPtr(Loader::loadClass(className).newInstance());
-               RollingPolicyPtr layout = 
LOG4CXX_NS::cast<RollingPolicy>(instance);
-               PropertySetter propSetter(layout);
+               PropertySetter propSetter(instance);
 
-               for (apr_xml_elem* currentElement = layout_element->first_child;
+               for (apr_xml_elem* currentElement = policy_element->first_child;
                        currentElement;
                        currentElement = currentElement->next)
                {
@@ -731,7 +731,7 @@ RollingPolicyPtr DOMConfigurator::parseRollingPolicy (
                }
 
                propSetter.activate(p);
-               return layout;
+               return LOG4CXX_NS::cast<RollingPolicy>(instance);
        }
        catch (Exception& oops)
        {
@@ -1056,6 +1056,12 @@ void DOMConfigurator::parse(
                
LogLog::setInternalDebugging(OptionConverter::toBoolean(debugAttrib, true));
        }
 
+       LogString colorAttrib = subst(getAttribute(utf8Decoder, element, 
INTERNAL_COLOR_ATTR));
+       if (!colorAttrib.empty())
+       {
+               LogLog::setColorEnabled(OptionConverter::toBoolean(colorAttrib, 
true));
+       }
+
        LogString thresholdStr = subst(getAttribute(utf8Decoder, element, 
THRESHOLD_ATTR));
 
        if (!thresholdStr.empty() && thresholdStr != LOG4CXX_STR("NULL"))
diff --git a/src/main/cpp/loglog.cpp b/src/main/cpp/loglog.cpp
index 016485c6..678939b0 100644
--- a/src/main/cpp/loglog.cpp
+++ b/src/main/cpp/loglog.cpp
@@ -48,6 +48,27 @@ struct LogLog::LogLogPrivate {
         */
        bool quietMode;
        std::mutex mutex;
+       LogString errorPrefix;
+       LogString warnPrefix;
+       LogString debugPrefix;
+       LogString suffix;
+       void setColorEnabled(bool newValue)
+       {
+               if (newValue)
+               {
+                       this->errorPrefix = LOG4CXX_STR("\x1B[31m"); //red
+                       this->warnPrefix = LOG4CXX_STR("\x1B[33m"); //yellow
+                       this->debugPrefix = LOG4CXX_STR("\x1B[32m"); //green
+                       this->suffix = LOG4CXX_STR("\x1B[0m"); // none
+               }
+               else
+               {
+                       this->errorPrefix.clear();
+                       this->warnPrefix.clear();
+                       this->debugPrefix.clear();
+                       this->suffix.clear();
+               }
+       }
 };
 
 LogLog::LogLog() :
@@ -55,6 +76,8 @@ LogLog::LogLog() :
 {
        LogString log4cxxDebug = 
OptionConverter::getSystemProperty(LOG4CXX_STR("LOG4CXX_DEBUG"), 
LOG4CXX_STR("false"));
        m_priv->debugEnabled = OptionConverter::toBoolean(log4cxxDebug, false);
+       auto color = 
OptionConverter::getSystemProperty(LOG4CXX_STR("LOG4CXX_COLOR"), 
LOG4CXX_STR("true"));
+       m_priv->setColorEnabled(OptionConverter::toBoolean(color, true));
 }
 
 LogLog::~LogLog()
@@ -81,6 +104,18 @@ void LogLog::setInternalDebugging(bool debugEnabled1)
                p->debugEnabled = debugEnabled1;
 }
 
+bool LogLog::isColorEnabled()
+{
+       auto p = getInstance().m_priv.get();
+       return p && !p->errorPrefix.empty();
+}
+
+void LogLog::setColorEnabled(bool newValue)
+{
+       if (auto p = getInstance().m_priv.get())
+               p->setColorEnabled(newValue);
+}
+
 void LogLog::debug(const LogString& msg)
 {
        auto p = getInstance().m_priv.get();
@@ -93,7 +128,7 @@ void LogLog::debug(const LogString& msg)
 
                std::lock_guard<std::mutex> lock(p->mutex);
 
-               emit_log(msg);
+               emit_log(p->debugPrefix, msg, p->suffix);
        }
 }
 
@@ -106,8 +141,8 @@ void LogLog::debug(const LogString& msg, const 
std::exception& e)
                        return;
 
                std::lock_guard<std::mutex> lock(p->mutex);
-               emit_log(msg);
-               emit_log(e);
+               emit_log(p->debugPrefix, msg, p->suffix);
+               emit_log(p->debugPrefix, e, p->suffix);
        }
 }
 
@@ -119,7 +154,7 @@ void LogLog::error(const LogString& msg)
        {
                std::lock_guard<std::mutex> lock(p->mutex);
 
-               emit_log(msg);
+               emit_log(p->errorPrefix, msg, p->suffix);
        }
 }
 
@@ -129,8 +164,8 @@ void LogLog::error(const LogString& msg, const 
std::exception& e)
        if (p && !p->quietMode) // Not deleted by onexit processing?
        {
                std::lock_guard<std::mutex> lock(p->mutex);
-               emit_log(msg);
-               emit_log(e);
+               emit_log(p->errorPrefix, msg, p->suffix);
+               emit_log(p->errorPrefix, e, p->suffix);
        }
 }
 
@@ -148,7 +183,7 @@ void LogLog::warn(const LogString& msg)
        if (p && !p->quietMode) // Not deleted by onexit processing?
        {
                std::lock_guard<std::mutex> lock(p->mutex);
-               emit_log(msg);
+               emit_log(p->warnPrefix, msg, p->suffix);
        }
 }
 
@@ -158,24 +193,26 @@ void LogLog::warn(const LogString& msg, const 
std::exception& e)
        if (p && !p->quietMode) // Not deleted by onexit processing?
        {
                std::lock_guard<std::mutex> lock(p->mutex);
-               emit_log(msg);
-               emit_log(e);
+               emit_log(p->warnPrefix, msg, p->suffix);
+               emit_log(p->warnPrefix, e, p->suffix);
        }
 }
 
-void LogLog::emit_log(const LogString& msg)
+void LogLog::emit_log(const LogString& prefix, const LogString& msg, const 
LogString& suffix)
 {
        LogString out(LOG4CXX_STR("log4cxx: "));
-
+       out.append(prefix);
        out.append(msg);
+       out.append(suffix);
        out.append(1, (logchar) 0x0A);
 
        SystemErrWriter::write(out);
 }
 
-void LogLog::emit_log(const std::exception& ex)
+void LogLog::emit_log(const LogString& prefix, const std::exception& ex, const 
LogString& suffix)
 {
        LogString out(LOG4CXX_STR("log4cxx: "));
+       out.append(prefix);
        const char* raw = ex.what();
 
        if (raw != 0)
@@ -187,6 +224,7 @@ void LogLog::emit_log(const std::exception& ex)
                out.append(LOG4CXX_STR("std::exception::what() == null"));
        }
 
+       out.append(suffix);
        out.append(1, (logchar) 0x0A);
 
        SystemErrWriter::write(out);
diff --git a/src/main/cpp/propertyconfigurator.cpp 
b/src/main/cpp/propertyconfigurator.cpp
index a1a8530c..6dd2036b 100644
--- a/src/main/cpp/propertyconfigurator.cpp
+++ b/src/main/cpp/propertyconfigurator.cpp
@@ -177,11 +177,16 @@ spi::ConfigurationStatus 
PropertyConfigurator::doConfigure(helpers::Properties&
 {
        hierarchy->setConfigured(true);
 
-       LogString value(properties.getProperty(LOG4CXX_STR("log4j.debug")));
+       LogString 
debugValue(properties.getProperty(LOG4CXX_STR("log4j.debug")));
+       if (!debugValue.empty())
+       {
+               
LogLog::setInternalDebugging(OptionConverter::toBoolean(debugValue, true));
+       }
 
-       if (!value.empty())
+       LogString 
colorValue(properties.getProperty(LOG4CXX_STR("log4j.color")));
+       if (!colorValue.empty())
        {
-               LogLog::setInternalDebugging(OptionConverter::toBoolean(value, 
true));
+               LogLog::setColorEnabled(OptionConverter::toBoolean(colorValue, 
true));
        }
 
        LogString thresholdStr =
diff --git a/src/main/include/log4cxx/basicconfigurator.h 
b/src/main/include/log4cxx/basicconfigurator.h
index bf35f72c..a2eb6fbd 100644
--- a/src/main/include/log4cxx/basicconfigurator.h
+++ b/src/main/include/log4cxx/basicconfigurator.h
@@ -45,8 +45,9 @@ class LOG4CXX_EXPORT BasicConfigurator
                Add a ConsoleAppender to the root logger that formats output 
using \c layout.
 
                If \c layout is not provided,
-               use a PatternLayout with <code>%%r [%%t] %%p %%c %%x - 
%%m%%n</code>
-               as the conversion pattern.
+               use a PatternLayout with the conversion pattern:
+               - <code>%%r [%%t] %%p %%c %%x - %%Y%%m%%y%%n</code> if color is 
enabled (the default)
+               - <code>%%r [%%t] %%p %%c %%x - %%m%%n</code> if [color is 
disabled](disabling-color.html)
                */
                static void configure(const LayoutPtr& layout = LayoutPtr());
 
diff --git a/src/main/include/log4cxx/helpers/loglog.h 
b/src/main/include/log4cxx/helpers/loglog.h
index 22c6d291..f163b36c 100644
--- a/src/main/include/log4cxx/helpers/loglog.h
+++ b/src/main/include/log4cxx/helpers/loglog.h
@@ -53,14 +53,24 @@ class LOG4CXX_EXPORT LogLog
                ~LogLog();
 
                /**
-                *  Is internal debugging enabled?
+                *  Are debug messages sent to SystemErrWriter?
                 **/
                static bool isDebugEnabled();
 
                /**
-               Use the value of \c enabled as the new internal debug logging 
state.
+               Start/stop outputing debug messages if \c newValue is 
true/false respectively.
                */
-               static void setInternalDebugging(bool enabled);
+               static void setInternalDebugging(bool newValue);
+
+               /**
+                *  Are messages output in color?
+                **/
+               static bool isColorEnabled();
+
+               /**
+               Start/stop coloring message text if \c newValue is true/false 
respectively.
+               */
+               static void setColorEnabled(bool newValue);
 
                /**
                Output \c msg to SystemErrWriter if internal debug logging is 
enabled.
@@ -102,8 +112,8 @@ class LOG4CXX_EXPORT LogLog
                static void warn(const LogString&  msg, const std::exception& 
ex);
 
        private:
-               static void emit_log(const LogString& msg);
-               static void emit_log(const std::exception& ex);
+               static void emit_log(const LogString& prefix, const LogString& 
msg, const LogString& suffix);
+               static void emit_log(const LogString& prefix, const 
std::exception& ex, const LogString& suffix);
 };
 }  // namespace helpers
 } // namespace log4cxx
diff --git a/src/site/markdown/1-usage.md b/src/site/markdown/1-usage.md
index 67402fbf..e7295f0a 100644
--- a/src/site/markdown/1-usage.md
+++ b/src/site/markdown/1-usage.md
@@ -35,6 +35,7 @@ See the following pages for usage information:
 * @subpage environment-variables
 * @subpage macros-influencing-log4cxx
 * @subpage internal-debugging
+* @subpage disabling-color
 * @subpage performance
 * @subpage conclusions
 * @subpage faq
diff --git a/src/site/markdown/change-report-gh.md 
b/src/site/markdown/change-report-gh.md
index 912f43a2..9d9d93c3 100644
--- a/src/site/markdown/change-report-gh.md
+++ b/src/site/markdown/change-report-gh.md
@@ -54,13 +54,13 @@ Change Log {#changelog}
 
 Release 1.6.0 includes the following new features:
 
-Release 1.6.0 includes the following new features:
-
 * Configuration ${varname} values can be set programatically prior to loading 
a configuration file (see \ref com/foo/config4.cpp)
    \[[#520](https://github.com/apache/logging-log4cxx/pull/520)\]
 * The current executable's file name and its components are available for use 
in a configuration file
 and the LOG4CXX_CONFIGURATION environment variable (see 
log4cxx::spi::Configurator::properties).
    \[[#520](https://github.com/apache/logging-log4cxx/pull/520)\]
+* Console output (Log4cxx internal logging and BasicConfigurator) use a color 
per message level by default
+   \[[#529](https://github.com/apache/logging-log4cxx/pull/529)\]
 
 The following issues have been addressed:
 
diff --git a/src/site/markdown/1-usage.md 
b/src/site/markdown/colored_console_output.md
similarity index 55%
copy from src/site/markdown/1-usage.md
copy to src/site/markdown/colored_console_output.md
index 67402fbf..03510dac 100644
--- a/src/site/markdown/1-usage.md
+++ b/src/site/markdown/colored_console_output.md
@@ -1,9 +1,5 @@
-Use {#usage-overview}
+Disabling Console Color {#disabling-color}
 ===
-<!--
- Note: License header cannot be first, as doxygen does not generate
- cleanly if it before the '==='
--->
 <!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
@@ -21,22 +17,9 @@ Use {#usage-overview}
  limitations under the License.
 -->
 
-See the following pages for usage information:
-
-* @subpage quick-start
-* @subpage concepts
-* @subpage configuration-files
-* @subpage filters
-* @subpage extending-log4cxx
-* @subpage qt-support
-* @subpage stacktrace-support
-* @subpage threading
-* @subpage multiprocess-logging
-* @subpage environment-variables
-* @subpage macros-influencing-log4cxx
-* @subpage internal-debugging
-* @subpage performance
-* @subpage conclusions
-* @subpage faq
-* @subpage buildsystems
-* @subpage log-flow
+There are several ways to disable colored console output:
+-# Setting the environment variable <code>LOG4CXX_COLOR</code> to the value 
<code>false</code>
+-# If using a properties file, add the line <code>log4j.color=false</code> to 
your file
+-# If using an XML file, add the <code>color="false"</code> attribute in the 
<code>log4j.configuration</code> element
+-# Configure the library programmatically by calling
+[LogLog::setColorEnabled](@ref log4cxx.helpers.LogLog.setColorEnabled)
diff --git a/src/site/markdown/example-programs.md 
b/src/site/markdown/example-programs.md
index 97834df8..35ae215e 100644
--- a/src/site/markdown/example-programs.md
+++ b/src/site/markdown/example-programs.md
@@ -87,7 +87,8 @@ method creates a rather simple Log4cxx setup. This method is 
hardwired
 to add to the root logger a [ConsoleAppender](@ref log4cxx.ConsoleAppender).
 The output will be formatted using a
 [PatternLayout](@ref log4cxx.PatternLayout)
-set to the pattern `%%r [%%t] %%p %%c %%x - %%m%%n`.
+with either <code>%%r [%%t] %%p %%c %%x - %%Y%%m%%y%%n</code> if color is 
enabled (the default)
+or <code>%%r [%%t] %%p %%c %%x - %%m%%n</code> if [color is 
disabled](disabling-color.html).
 
 Note that by default, the root logger is assigned a *DEBUG* level.
 

Reply via email to