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 <[email protected]>
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.