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 <swebb2...@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)