You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by sw...@apache.org on 2025/08/29 03:32:03 UTC

(logging-log4cxx) branch color_internal_logging_messages created (now f449f745)

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

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


      at f449f745 Color console messages unless explicity disabled

This branch includes the following new commits:

     new f449f745 Color console messages unless explicity disabled

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(logging-log4cxx) 01/01: Color console messages unless explicity disabled

Posted by sw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f449f7451124be0c4d6cd63bdf85d00de723d11c
Author: Stephen Webb <sw...@gmail.com>
AuthorDate: Fri Aug 29 13:31:36 2025 +1000

    Color console messages unless explicity disabled
---
 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 +
 .../{1-usage.md => colored_console_output.md}      | 31 +++--------
 8 files changed, 106 insertions(+), 58 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/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)