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

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

commit 855b323ace087bab44624a3a2c02e66550810e89
Author: Stephen Webb <[email protected]>
AuthorDate: Tue Sep 30 17:48:20 2025 +1000

    Allow binary-to-text conversion to be moved to a background thread
---
 src/main/cpp/CMakeLists.txt                    |   1 +
 src/main/cpp/asyncappender.cpp                 |   2 +-
 src/main/cpp/asyncbuffer.cpp                   |  85 ++++++++++++++++++
 src/main/cpp/fmtlayout.cpp                     |   7 +-
 src/main/cpp/htmllayout.cpp                    |   5 +-
 src/main/cpp/jsonlayout.cpp                    |   5 +-
 src/main/cpp/logger.cpp                        |  14 +++
 src/main/cpp/loggingevent.cpp                  |  49 ++++++++++
 src/main/cpp/patternlayout.cpp                 |   3 +-
 src/main/cpp/telnetappender.cpp                |   2 +-
 src/main/cpp/xmllayout.cpp                     |   5 +-
 src/main/include/log4cxx/helpers/asyncbuffer.h | 119 +++++++++++++++++++++++++
 src/main/include/log4cxx/logger.h              |  19 ++++
 src/main/include/log4cxx/spi/loggingevent.h    |  20 +++++
 src/test/cpp/asyncappendertestcase.cpp         |   7 +-
 src/test/cpp/benchmark/benchmark.cpp           |   4 +-
 16 files changed, 330 insertions(+), 17 deletions(-)

diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt
index 465a51d8..8a2526f4 100644
--- a/src/main/cpp/CMakeLists.txt
+++ b/src/main/cpp/CMakeLists.txt
@@ -78,6 +78,7 @@ target_sources(log4cxx
   appenderskeleton.cpp
   aprinitializer.cpp
   asyncappender.cpp
+  asyncbuffer.cpp
   basicconfigurator.cpp
   bufferedwriter.cpp
   bytearrayinputstream.cpp
diff --git a/src/main/cpp/asyncappender.cpp b/src/main/cpp/asyncappender.cpp
index 2427cb62..d199e392 100644
--- a/src/main/cpp/asyncappender.cpp
+++ b/src/main/cpp/asyncappender.cpp
@@ -498,7 +498,7 @@ LoggingEventPtr DiscardSummary::createEvent(Pool& p)
        LogString msg(LOG4CXX_STR("Discarded "));
        StringHelper::toString(count, p, msg);
        msg.append(LOG4CXX_STR(" messages due to a full event buffer including: 
"));
-       msg.append(maxEvent->getMessage());
+       msg.append(maxEvent->getRenderedMessage());
        return std::make_shared<LoggingEvent>(
                                maxEvent->getLoggerName(),
                                maxEvent->getLevel(),
diff --git a/src/main/cpp/asyncbuffer.cpp b/src/main/cpp/asyncbuffer.cpp
new file mode 100644
index 00000000..125474f4
--- /dev/null
+++ b/src/main/cpp/asyncbuffer.cpp
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <log4cxx/helpers/asyncbuffer.h>
+
+namespace LOG4CXX_NS
+{
+
+namespace helpers
+{
+
+struct AsyncBuffer::Private
+{
+       std::vector<MessageBufferAppender> data;
+};
+
+/** An empty buffer.
+*/
+AsyncBuffer::AsyncBuffer()
+{}
+
+/** A new buffer with the content of \c other
+*/
+AsyncBuffer::AsyncBuffer(AsyncBuffer&& other)
+       : m_priv(std::move(other.m_priv))
+{
+}
+
+/** Release resources.
+*/
+AsyncBuffer::~AsyncBuffer()
+{
+}
+
+/**
+* Has no item been added to this?
+*/
+bool AsyncBuffer::empty() const { return !m_priv || m_priv->data.empty(); }
+
+/**
+* Add text version of buffered values to \c msg
+*/
+void AsyncBuffer::renderMessage(helpers::MessageBuffer& msg)
+{
+       if (m_priv)
+               for (auto& renderer : m_priv->data)
+                       renderer(msg);
+}
+
+/**
+* Remove all message appenders
+*/
+void AsyncBuffer::clear()
+{
+       if (m_priv)
+               m_priv->data.clear();
+}
+
+/**
+ *   Append \c function to this buffer.
+ */
+void AsyncBuffer::append(const MessageBufferAppender& f)
+{
+       if (!m_priv)
+               m_priv = std::make_unique<Private>();
+       m_priv->data.push_back(f);
+}
+
+} // namespace helpers
+} // namespace LOG4CXX_NS
+
diff --git a/src/main/cpp/fmtlayout.cpp b/src/main/cpp/fmtlayout.cpp
index faa0d0c9..21a73c6b 100644
--- a/src/main/cpp/fmtlayout.cpp
+++ b/src/main/cpp/fmtlayout.cpp
@@ -89,7 +89,8 @@ void FMTLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        LOG4CXX_NS::helpers::Pool&) const
 {
-       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
+       auto lsMsg = event->getRenderedMessage();
+       output.reserve(m_priv->expectedPatternLength + lsMsg.size());
        auto locationFull = fmt::format("{}({})",
                                                                                
 event->getLocationInformation().getFileName(),
                                                                                
 event->getLocationInformation().getLineNumber());
@@ -100,7 +101,7 @@ void FMTLayout::format(LogString& output,
        LOG4CXX_ENCODE_CHAR(sPattern, m_priv->conversionPattern);
        LOG4CXX_ENCODE_CHAR(sLogger, event->getLoggerName());
        LOG4CXX_ENCODE_CHAR(sLevel, event->getLevel()->toString());
-       LOG4CXX_ENCODE_CHAR(sMsg, event->getMessage());
+       LOG4CXX_ENCODE_CHAR(sMsg, lsMsg);
        LOG4CXX_ENCODE_CHAR(sThread, event->getThreadName());
        LOG4CXX_ENCODE_CHAR(endOfLine, LOG4CXX_EOL);
 #else
@@ -108,7 +109,7 @@ void FMTLayout::format(LogString& output,
        auto& sPattern = m_priv->conversionPattern;
        auto& sLogger = event->getLoggerName();
        auto sLevel = event->getLevel()->toString();
-       auto& sMsg = event->getMessage();
+       auto& sMsg = lsMsg;
        auto& sThread = event->getThreadName();
        auto endOfLine = LOG4CXX_EOL;
 #endif
diff --git a/src/main/cpp/htmllayout.cpp b/src/main/cpp/htmllayout.cpp
index f1b2747c..cfa18db3 100644
--- a/src/main/cpp/htmllayout.cpp
+++ b/src/main/cpp/htmllayout.cpp
@@ -84,7 +84,8 @@ void HTMLLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        Pool& p) const
 {
-       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
+       auto lsMsg = event->getRenderedMessage();
+       output.reserve(m_priv->expectedPatternLength + lsMsg.size());
        output.append(LOG4CXX_EOL);
        output.append(LOG4CXX_STR("<tr>"));
        output.append(LOG4CXX_EOL);
@@ -152,7 +153,7 @@ void HTMLLayout::format(LogString& output,
        }
 
        output.append(LOG4CXX_STR("<td title=\"Message\">"));
-       Transform::appendEscapingTags(output, event->getRenderedMessage());
+       Transform::appendEscapingTags(output, lsMsg);
        output.append(LOG4CXX_STR("</td>"));
        output.append(LOG4CXX_EOL);
        output.append(LOG4CXX_STR("</tr>"));
diff --git a/src/main/cpp/jsonlayout.cpp b/src/main/cpp/jsonlayout.cpp
index 9b286aff..ce27c286 100644
--- a/src/main/cpp/jsonlayout.cpp
+++ b/src/main/cpp/jsonlayout.cpp
@@ -132,7 +132,8 @@ void JSONLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        Pool& p) const
 {
-       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
+       auto lsMsg = event->getRenderedMessage();
+       output.reserve(m_priv->expectedPatternLength + lsMsg.size());
        output.append(LOG4CXX_STR("{"));
        output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));
 
@@ -187,7 +188,7 @@ void JSONLayout::format(LogString& output,
        }
 
        output.append(LOG4CXX_STR("\"message\": "));
-       appendQuotedEscapedString(output, event->getMessage());
+       appendQuotedEscapedString(output, lsMsg);
 
        appendSerializedMDC(output, event);
        appendSerializedNDC(output, event);
diff --git a/src/main/cpp/logger.cpp b/src/main/cpp/logger.cpp
index e814620f..4933546b 100644
--- a/src/main/cpp/logger.cpp
+++ b/src/main/cpp/logger.cpp
@@ -173,6 +173,15 @@ void Logger::closeNestedAppenders()
        }
 }
 
+void Logger::addEvent(const LevelPtr& level, helpers::AsyncBuffer&& 
messageAppender, const LocationInfo& location) const
+{
+       if (!getHierarchy()) // Has removeHierarchy() been called?
+               return;
+       auto event = std::make_shared<LoggingEvent>(m_priv->name, level, 
location, std::move(messageAppender));
+       Pool p;
+       callAppenders(event, p);
+}
+
 void Logger::addEvent(const LevelPtr& level, std::string&& message, const 
LocationInfo& location) const
 {
        if (!getHierarchy()) // Has removeHierarchy() been called?
@@ -207,6 +216,11 @@ void Logger::addInfoEvent(std::string&& message, const 
LocationInfo& location) c
        addEvent(m_priv->levelData->Info, std::move(message), location);
 }
 
+void Logger::addInfoEvent(helpers::AsyncBuffer&& messageAppender, const 
LocationInfo& location) const
+{
+       addEvent(m_priv->levelData->Info, std::move(messageAppender), location);
+}
+
 void Logger::addDebugEvent(std::string&& message, const LocationInfo& 
location) const
 {
        addEvent(m_priv->levelData->Debug, std::move(message), location);
diff --git a/src/main/cpp/loggingevent.cpp b/src/main/cpp/loggingevent.cpp
index e1fc11f2..f81b2df2 100644
--- a/src/main/cpp/loggingevent.cpp
+++ b/src/main/cpp/loggingevent.cpp
@@ -29,6 +29,7 @@
 #include <log4cxx/helpers/aprinitializer.h>
 #include <log4cxx/helpers/threadspecificdata.h>
 #include <log4cxx/helpers/bytebuffer.h>
+#include <log4cxx/helpers/messagebuffer.h>
 #include <log4cxx/helpers/date.h>
 #include <log4cxx/helpers/optional.h>
 
@@ -61,6 +62,23 @@ struct LoggingEvent::LoggingEventPrivate
        {
        }
 
+       LoggingEventPrivate
+               ( const LogString& logger1
+               , const LevelPtr& level1
+               , const LocationInfo& locationInfo1
+               , helpers::AsyncBuffer&& messageAppenderArg
+               , const ThreadSpecificData::NamePairPtr p = 
ThreadSpecificData::getNames()
+               )
+               : logger(logger1)
+               , level(level1)
+               , timeStamp(Date::currentTime())
+               , locationInfo(locationInfo1)
+               , chronoTimeStamp(std::chrono::microseconds(timeStamp))
+               , pNames(p)
+               , messageAppender(std::move(messageAppenderArg))
+       {
+       }
+
        LoggingEventPrivate(
                const LogString& logger1, const LevelPtr& level1,
                const LogString& message1, const LocationInfo& locationInfo1,
@@ -124,6 +142,21 @@ struct LoggingEvent::LoggingEventPrivate
         *  of this LoggingEvent exceeds the duration of the logging request.
         */
        mutable std::unique_ptr<DiagnosticContext> dc;
+
+       /** Application supplied message builders.
+        */
+       helpers::AsyncBuffer messageAppender;
+
+       void renderMessage()
+       {
+               if (!this->messageAppender.empty())
+               {
+                       helpers::MessageBuffer buf;
+                       this->messageAppender.renderMessage(buf);
+                       this->message = buf.extract_str(buf);
+                       this->messageAppender.clear();
+               }
+       }
 };
 
 IMPLEMENT_LOG4CXX_OBJECT(LoggingEvent)
@@ -152,6 +185,16 @@ LoggingEvent::LoggingEvent
 {
 }
 
+LoggingEvent::LoggingEvent
+       ( const LogString&    logger
+       , const LevelPtr&     level
+       , const LocationInfo& location
+       , helpers::AsyncBuffer&& messageAppender
+       )
+       : m_priv(std::make_unique<LoggingEventPrivate>(logger, level, location, 
std::move(messageAppender)))
+{
+}
+
 LoggingEvent::LoggingEvent(
        const LogString& logger1, const LevelPtr& level1,
        const LogString& message1, const LocationInfo& locationInfo1) :
@@ -273,6 +316,11 @@ LoggingEvent::KeySet LoggingEvent::getPropertyKeySet() 
const
        return set;
 }
 
+void LoggingEvent::renderMessage()
+{
+       m_priv->renderMessage();
+}
+
 void LoggingEvent::setProperty(const LogString& key, const LogString& value)
 {
        if (m_priv->properties == 0)
@@ -300,6 +348,7 @@ const LogString& LoggingEvent::getMessage() const
 
 const LogString& LoggingEvent::getRenderedMessage() const
 {
+       m_priv->renderMessage();
        return m_priv->message;
 }
 
diff --git a/src/main/cpp/patternlayout.cpp b/src/main/cpp/patternlayout.cpp
index 371e47d7..c7040d37 100644
--- a/src/main/cpp/patternlayout.cpp
+++ b/src/main/cpp/patternlayout.cpp
@@ -122,7 +122,8 @@ void PatternLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        Pool& pool) const
 {
-       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
+       auto lsMsg = event->getRenderedMessage();
+       output.reserve(m_priv->expectedPatternLength + lsMsg.size());
        std::vector<FormattingInfoPtr>::const_iterator formatterIter =
                m_priv->patternFields.begin();
 
diff --git a/src/main/cpp/telnetappender.cpp b/src/main/cpp/telnetappender.cpp
index fcacc40c..cc3b1439 100644
--- a/src/main/cpp/telnetappender.cpp
+++ b/src/main/cpp/telnetappender.cpp
@@ -230,7 +230,7 @@ void TelnetAppender::append(const spi::LoggingEventPtr& 
event, Pool& p)
                if (_priv->layout)
                        _priv->layout->format(msg, event, p);
                else
-                       msg = event->getMessage();
+                       msg = event->getRenderedMessage();
                msg.append(LOG4CXX_STR("\r\n"));
                size_t bytesSize = msg.size() * 2;
                char* bytes = p.pstralloc(bytesSize);
diff --git a/src/main/cpp/xmllayout.cpp b/src/main/cpp/xmllayout.cpp
index 0b7fe073..4f508ffc 100644
--- a/src/main/cpp/xmllayout.cpp
+++ b/src/main/cpp/xmllayout.cpp
@@ -78,7 +78,8 @@ void XMLLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        Pool& p) const
 {
-       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
+       auto lsMsg = event->getRenderedMessage();
+       output.reserve(m_priv->expectedPatternLength + lsMsg.size());
        output.append(LOG4CXX_STR("<log4j:event logger=\""));
        Transform::appendEscapingTags(output, event->getLoggerName());
        output.append(LOG4CXX_STR("\" timestamp=\""));
@@ -93,7 +94,7 @@ void XMLLayout::format(LogString& output,
        output.append(LOG4CXX_STR("<log4j:message><![CDATA["));
        // Append the rendered message. Also make sure to escape any
        // existing CDATA sections.
-       Transform::appendEscapingCDATA(output, event->getRenderedMessage());
+       Transform::appendEscapingCDATA(output, lsMsg);
        output.append(LOG4CXX_STR("]]></log4j:message>"));
        output.append(LOG4CXX_EOL);
 
diff --git a/src/main/include/log4cxx/helpers/asyncbuffer.h 
b/src/main/include/log4cxx/helpers/asyncbuffer.h
new file mode 100644
index 00000000..496d1f12
--- /dev/null
+++ b/src/main/include/log4cxx/helpers/asyncbuffer.h
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LOG4CXX_ASYNC_BUFFER_H
+#define LOG4CXX_ASYNC_BUFFER_H
+
+#include <log4cxx/helpers/messagebuffer.h>
+#include <functional>
+#include <vector>
+
+namespace LOG4CXX_NS
+{
+
+namespace helpers
+{
+
+/**
+ *   This class is used by the LOG4CXX2_INFO and similar
+ *   macros to support insertion operators.
+ *   The class is not intended for use outside of that context.
+ */
+class LOG4CXX_EXPORT AsyncBuffer
+{
+public:
+       /** An empty buffer.
+       */
+       AsyncBuffer();
+
+       /** A new buffer with the content of \c other
+       */
+       AsyncBuffer(AsyncBuffer&& other);
+
+       /** Release resources.
+       */
+       ~AsyncBuffer();
+
+       /** Append a function to this buffer that will convert \c value to text.
+        *   @param value must be copy-constructable or move-constructable
+        *   @return this buffer.
+        */
+       template<typename T>
+       AsyncBuffer& operator<<(const T& value)
+       {
+               append([value](MessageBuffer& msgBuf)
+                       {
+                               msgBuf << value;
+                       });
+               return *this;
+       }
+
+       /**
+       * Has no item been added to this?
+       */
+       bool empty() const;
+
+       /**
+       * Add text version of buffered values to \c msg
+       */
+       void renderMessage(helpers::MessageBuffer& msg);
+
+       /**
+       * Remove all message appenders
+       */
+       void clear();
+
+private:
+       AsyncBuffer(const AsyncBuffer&) = delete;
+       AsyncBuffer& operator=(const AsyncBuffer&) = delete;
+
+       LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(Private, m_priv)
+       using MessageBufferAppender = std::function<void(MessageBuffer&)>;
+
+       /**
+        *   Append \c function to this buffer.
+        */
+       void append(const MessageBufferAppender& f);
+};
+
+} // namespace helpers
+} // namespace LOG4CXX_NS
+
+/**
+Add a new logging event containing \c message to attached appender(s) if \c 
logger is enabled for <code>INFO</code> events.
+
+\usage
+~~~{.cpp}
+LOG4CXX2_INFO(m_log, surface->GetName()
+       << " successfully planned " << std::fixed << std::setprecision(1) << 
((plannedArea  / (plannedArea + unplannedArea)) * 100.0) << "%"
+       << " planned area " << std::fixed << std::setprecision(4) << 
plannedArea << "m^2"
+       << " unplanned area " << unplannedArea << "m^2"
+       << " planned segments " << surface->GetSegmentPlanCount() << " of " << 
surface->GetSegmentCount()
+       );
+~~~
+
+@param logger the logger that has the enabled status.
+@param message a valid r-value expression of an 
<code>operator<<(std::ostream&. ...)</code> overload.
+*/
+#define LOG4CXX2_INFO(logger, message) do { \
+               if (::LOG4CXX_NS::Logger::isInfoEnabledFor(logger)) {\
+                       ::LOG4CXX_NS::helpers::AsyncBuffer buf;\
+                       logger->addInfoEvent(std::move(buf << message), 
LOG4CXX_LOCATION);\
+               }} while (0)
+
+#endif
+
diff --git a/src/main/include/log4cxx/logger.h 
b/src/main/include/log4cxx/logger.h
index 91181504..3230a3e0 100644
--- a/src/main/include/log4cxx/logger.h
+++ b/src/main/include/log4cxx/logger.h
@@ -23,6 +23,7 @@
 #include <log4cxx/helpers/pool.h>
 #include <log4cxx/spi/location/locationinfo.h>
 #include <log4cxx/helpers/resourcebundle.h>
+#include <log4cxx/helpers/asyncbuffer.h>
 #include <log4cxx/helpers/messagebuffer.h>
 
 namespace LOG4CXX_NS
@@ -506,6 +507,16 @@ class LOG4CXX_EXPORT Logger
                void addEvent(const LevelPtr& level, std::string&& message
                        , const spi::LocationInfo& location = 
spi::LocationInfo::getLocationUnavailable()) const;
 
+               /**
+               Add to attached appender(s) a new \c level LoggingEvent which 
was requested at \c sourceLocation where the message is built asynchronously by 
\c messageAppender
+               without further checks.
+               @param level The logging event level.
+               @param message The text to add to the logging event.
+               @param location The source code location of the logging request.
+               */
+               void addEvent(const LevelPtr& level, helpers::AsyncBuffer&& 
messageAppender
+                       , const spi::LocationInfo& sourceLocation = 
spi::LocationInfo::getLocationUnavailable()) const;
+
                /**
                Add a new fatal level logging event containing \c message and 
\c location to attached appender(s)
                without further checks.
@@ -538,6 +549,14 @@ class LOG4CXX_EXPORT Logger
                */
                void addInfoEvent(std::string&& message, const 
spi::LocationInfo& location = spi::LocationInfo::getLocationUnavailable()) 
const;
 
+               /**
+               Add to attached appender(s) a new INFO level LoggingEvent which 
was requested at \c sourceLocation where the message is built asynchronously by 
\c messageAppender
+               without further checks.
+               @param message The text to add to the logging event.
+               @param location The source code location of the logging request.
+               */
+               void addInfoEvent(helpers::AsyncBuffer&& messageAppender, const 
spi::LocationInfo& location = spi::LocationInfo::getLocationUnavailable()) 
const;
+
                /**
                Add a new debug level logging event containing \c message and 
\c location to attached appender(s)
                without further checks.
diff --git a/src/main/include/log4cxx/spi/loggingevent.h 
b/src/main/include/log4cxx/spi/loggingevent.h
index cd0b81c8..e40c8a5f 100644
--- a/src/main/include/log4cxx/spi/loggingevent.h
+++ b/src/main/include/log4cxx/spi/loggingevent.h
@@ -87,6 +87,21 @@ class LOG4CXX_EXPORT LoggingEvent :
                        , const LocationInfo& location
                        );
 
+               /**
+               An event composed using the supplied parameters.
+
+               @param logger The logger used to make the logging request.
+               @param level The severity of this event.
+               @param location The source code location of the logging request.
+               @param messageAppender  Builds the message text to add to this 
event.
+               */
+               LoggingEvent
+                       ( const LogString& logger
+                       , const LevelPtr& level
+                       , const LocationInfo& location
+                       , helpers::AsyncBuffer&& messageAppender
+                       );
+
                ~LoggingEvent();
 
                /** The severity level of the logging request that generated 
this event. */
@@ -195,6 +210,11 @@ class LOG4CXX_EXPORT LoggingEvent :
                */
                void setProperty(const LogString& key, const LogString& value);
 
+               /**
+               * Use the renderers to construct the message
+               */
+               void renderMessage();
+
        private:
                LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(LoggingEventPrivate, m_priv)
 
diff --git a/src/test/cpp/asyncappendertestcase.cpp 
b/src/test/cpp/asyncappendertestcase.cpp
index 28b2c9e6..9b431c6b 100644
--- a/src/test/cpp/asyncappendertestcase.cpp
+++ b/src/test/cpp/asyncappendertestcase.cpp
@@ -105,7 +105,8 @@ class LoggingVectorAppender : public VectorAppender
        void append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& 
p) override
        {
                VectorAppender::append(event, p);
-               if (event->getMessage() == LOG4CXX_STR("Hello, World"))
+               auto lsMsg = event->getRenderedMessage();
+               if (LogString::npos != lsMsg.find(LOG4CXX_STR("World")))
                {
                        LOG4CXX_LOGLS(logger, Level::getError(), 
LOG4CXX_STR("Some example error"));
                        LOG4CXX_LOGLS(logger, Level::getWarn(), 
LOG4CXX_STR("Some example warning"));
@@ -347,7 +348,7 @@ class AsyncAppenderTestCase : public 
AppenderSkeletonTestCase
 
                                for (int i = 0; i < 140; i++)
                                {
-                                       LOG4CXX_INFO(rootLogger, "Hello, 
World");
+                                       LOG4CXX2_INFO(rootLogger, "Hello, World 
" << i);
                                }
 
                                LOG4CXX_ERROR(rootLogger, "That's all folks.");
@@ -418,7 +419,7 @@ class AsyncAppenderTestCase : public 
AppenderSkeletonTestCase
                        std::this_thread::sleep_for( std::chrono::milliseconds( 
10 ) ); // Wait for the dispatch thread  to be ready
                        for (int i = 0; i < 10; i++)
                        {
-                               LOG4CXX_INFO(rootLogger, "Hello, World");
+                               LOG4CXX2_INFO(rootLogger, "Hello, World " << i);
                        }
                        LOG4CXX_INFO(rootLogger, "Bye bye World");
                        std::this_thread::sleep_for( std::chrono::milliseconds( 
10 ) ); // Wait for the dispatch thread take the above events
diff --git a/src/test/cpp/benchmark/benchmark.cpp 
b/src/test/cpp/benchmark/benchmark.cpp
index 873d2cd7..4fac7db9 100644
--- a/src/test/cpp/benchmark/benchmark.cpp
+++ b/src/test/cpp/benchmark/benchmark.cpp
@@ -416,7 +416,7 @@ BENCHMARK_DEFINE_F(benchmarker, 
asyncIntPlusFloatValueMessageBuffer)(benchmark::
        for (auto _ : state)
        {
                auto f = static_cast<float>(rand()) / 
static_cast<float>(RAND_MAX);
-               LOG4CXX_INFO( m_asyncLogger, "Hello: message number " << ++x
+               LOG4CXX2_INFO( m_asyncLogger, "Hello: message number " << ++x
                        << " pseudo-random float " << std::setprecision(3) << 
std::fixed << f);
        }
 }
@@ -429,7 +429,7 @@ BENCHMARK_DEFINE_F(benchmarker, 
fileIntPlusFloatValueMessageBuffer)(benchmark::S
        for (auto _ : state)
        {
                auto f = static_cast<float>(rand()) / 
static_cast<float>(RAND_MAX);
-               LOG4CXX_INFO( m_fileLogger, "Hello: message number " << ++x
+               LOG4CXX2_INFO( m_fileLogger, "Hello: message number " << ++x
                        << " pseudo-random float " << std::setprecision(3) << 
std::fixed << f);
        }
 }

Reply via email to