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 2023/07/20 06:32:30 UTC

[logging-log4cxx] branch move_message_to_event created (now a7214301)

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

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


      at a7214301 Move the constructed log message to the logging event (instead of copying)

This branch includes the following new commits:

     new a7214301 Move the constructed log message to the logging event (instead of copying)

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: Move the constructed log message to the logging event (instead of copying)

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

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

commit a7214301883a3595c47f36ee1ca36419c3f6937d
Author: Stephen Webb <sw...@gmail.com>
AuthorDate: Thu Jul 20 16:32:04 2023 +1000

    Move the constructed log message to the logging event (instead of copying)
---
 src/main/cpp/logger.cpp                          | 47 +++++++++++----
 src/main/cpp/loggingevent.cpp                    | 33 ++++++++++-
 src/main/cpp/messagebuffer.cpp                   | 60 +++++++++++++++++++
 src/main/include/log4cxx/helpers/messagebuffer.h | 74 ++++++++++++++++++++++++
 src/main/include/log4cxx/logger.h                | 52 +++++++++--------
 src/main/include/log4cxx/spi/loggingevent.h      | 22 ++++++-
 6 files changed, 250 insertions(+), 38 deletions(-)

diff --git a/src/main/cpp/logger.cpp b/src/main/cpp/logger.cpp
index 8c7d8ba5..1ec7338a 100644
--- a/src/main/cpp/logger.cpp
+++ b/src/main/cpp/logger.cpp
@@ -158,6 +158,19 @@ void Logger::closeNestedAppenders()
 	}
 }
 
+void Logger::addEvent(const LevelPtr& level, std::string&& message, const LocationInfo& location) const
+{
+	if (!getHierarchy()) // Has removeHierarchy() been called?
+		return;
+#if LOG4CXX_LOGCHAR_IS_UTF8
+	auto event = std::make_shared<LoggingEvent>(m_priv->name, level, location, std::move(message));
+#else
+	LOG4CXX_DECODE_CHAR(msg, message);
+	auto event = std::make_shared<LoggingEvent>(m_priv->name, level, location, std::move(msg));
+#endif
+	Pool p;
+	callAppenders(event, p);
+}
 
 void Logger::forcedLog(const LevelPtr& level1, const std::string& message,
 	const LocationInfo& location) const
@@ -170,15 +183,17 @@ void Logger::forcedLog(const LevelPtr& level1, const std::string& message,
 	callAppenders(event, p);
 }
 
-
 void Logger::forcedLog(const LevelPtr& level1, const std::string& message) const
+{
+	forcedLog(level1, message, LocationInfo::getLocationUnavailable());
+}
+
+void Logger::addEventLS(const LevelPtr& level, LogString&& message, const LocationInfo& location) const
 {
 	if (!getHierarchy()) // Has removeHierarchy() been called?
 		return;
 	Pool p;
-	LOG4CXX_DECODE_CHAR(msg, message);
-	auto event = std::make_shared<LoggingEvent>(m_priv->name, level1, msg,
-			LocationInfo::getLocationUnavailable());
+	auto event = std::make_shared<LoggingEvent>(m_priv->name, level, location, std::move(message));
 	callAppenders(event, p);
 }
 
@@ -427,7 +442,7 @@ void Logger::l7dlog(const LevelPtr& level1, const LogString& key,
 			msg = StringHelper::format(pattern, params);
 		}
 
-		forcedLogLS(level1, msg, location);
+		addEventLS(level1, std::move(msg), location);
 	}
 }
 
@@ -702,28 +717,36 @@ LoggerPtr Logger::getLoggerLS(const LogString& name)
 
 
 #if LOG4CXX_WCHAR_T_API
-void Logger::forcedLog(const LevelPtr& level1, const std::wstring& message,
-	const LocationInfo& location) const
+void Logger::addEvent(const LevelPtr& level, std::wstring&& message, const LocationInfo& location) const
 {
 	if (!getHierarchy()) // Has removeHierarchy() been called?
 		return;
-	Pool p;
+#if LOG4CXX_LOGCHAR_IS_WCHAR
+	auto event = std::make_shared<LoggingEvent>(m_priv->name, level, location, std::move(message));
+#else
 	LOG4CXX_DECODE_WCHAR(msg, message);
-	auto event = std::make_shared<LoggingEvent>(m_priv->name, level1, msg, location);
+	auto event = std::make_shared<LoggingEvent>(m_priv->name, level, location, std::move(msg));
+#endif
+	Pool p;
 	callAppenders(event, p);
 }
 
-void Logger::forcedLog(const LevelPtr& level1, const std::wstring& message) const
+void Logger::forcedLog(const LevelPtr& level1, const std::wstring& message,
+	const LocationInfo& location) const
 {
 	if (!getHierarchy()) // Has removeHierarchy() been called?
 		return;
 	Pool p;
 	LOG4CXX_DECODE_WCHAR(msg, message);
-	auto event = std::make_shared<LoggingEvent>(m_priv->name, level1, msg,
-			LocationInfo::getLocationUnavailable());
+	auto event = std::make_shared<LoggingEvent>(m_priv->name, level1, msg, location);
 	callAppenders(event, p);
 }
 
+void Logger::forcedLog(const LevelPtr& level1, const std::wstring& message) const
+{
+	forcedLog(level1, message, LocationInfo::getLocationUnavailable());
+}
+
 void Logger::getName(std::wstring& rv) const
 {
 	Transcoder::encode(m_priv->name, rv);
diff --git a/src/main/cpp/loggingevent.cpp b/src/main/cpp/loggingevent.cpp
index aa7d304e..71938db6 100644
--- a/src/main/cpp/loggingevent.cpp
+++ b/src/main/cpp/loggingevent.cpp
@@ -57,6 +57,28 @@ struct LoggingEvent::LoggingEventPrivate
 	{
 	}
 
+	LoggingEventPrivate
+		( const LogString& logger1
+		, const LevelPtr& level1
+		, const LocationInfo& locationInfo1
+		, LogString&& message1
+		) :
+		logger(logger1),
+		level(level1),
+		ndc(0),
+		mdcCopy(0),
+		properties(0),
+		ndcLookupRequired(true),
+		mdcCopyLookupRequired(true),
+		message(message1),
+		timeStamp(Date::currentTime()),
+		locationInfo(locationInfo1),
+		threadName(getCurrentThreadName()),
+		threadUserName(getCurrentThreadUserName()),
+		chronoTimeStamp(std::chrono::microseconds(timeStamp))
+	{
+	}
+
 	LoggingEventPrivate(
 		const LogString& logger1, const LevelPtr& level1,
 		const LogString& message1, const LocationInfo& locationInfo1) :
@@ -159,13 +181,22 @@ LoggingEvent::LoggingEvent() :
 {
 }
 
+LoggingEvent::LoggingEvent
+	( const LogString&    logger
+	, const LevelPtr&     level
+	, const LocationInfo& location
+	, LogString&&         message
+	)
+	: m_priv(std::make_unique<LoggingEventPrivate>(logger, level, location, std::move(message)))
+{
+}
+
 LoggingEvent::LoggingEvent(
 	const LogString& logger1, const LevelPtr& level1,
 	const LogString& message1, const LocationInfo& locationInfo1) :
 	m_priv(std::make_unique<LoggingEventPrivate>(logger1, level1, message1, locationInfo1))
 {
 }
-
 LoggingEvent::~LoggingEvent()
 {
 }
diff --git a/src/main/cpp/messagebuffer.cpp b/src/main/cpp/messagebuffer.cpp
index 607d5959..e17a6ef4 100644
--- a/src/main/cpp/messagebuffer.cpp
+++ b/src/main/cpp/messagebuffer.cpp
@@ -149,6 +149,16 @@ CharMessageBuffer::operator std::basic_ostream<char>& ()
 	return m_priv->StreamFromBuf();
 }
 
+std::basic_string<char> CharMessageBuffer::extract_str(std::basic_ostream<char>&)
+{
+	return std::move(m_priv->BufFromStream());
+}
+
+std::basic_string<char> CharMessageBuffer::extract_str(CharMessageBuffer&)
+{
+	return std::move(m_priv->buf);
+}
+
 const std::basic_string<char>& CharMessageBuffer::str(std::basic_ostream<char>&)
 {
 	return m_priv->BufFromStream();
@@ -284,6 +294,16 @@ WideMessageBuffer::operator std::basic_ostream<wchar_t>& ()
 	return m_priv->StreamFromBuf();
 }
 
+std::basic_string<wchar_t> WideMessageBuffer::extract_str(std::basic_ostream<wchar_t>&)
+{
+	return std::move(m_priv->BufFromStream());
+}
+
+std::basic_string<wchar_t> WideMessageBuffer::extract_str(WideMessageBuffer&)
+{
+	return std::move(m_priv->buf);
+}
+
 const std::basic_string<wchar_t>& WideMessageBuffer::str(std::basic_ostream<wchar_t>&)
 {
 	return m_priv->BufFromStream();
@@ -416,6 +436,16 @@ CharMessageBuffer& MessageBuffer::operator<<(const char msg)
 	return m_priv->cbuf.operator << (msg);
 }
 
+std::string MessageBuffer::extract_str(CharMessageBuffer& buf)
+{
+	return std::move(m_priv->cbuf.extract_str(buf));
+}
+
+std::string MessageBuffer::extract_str(std::ostream& os)
+{
+	return std::move(m_priv->cbuf.extract_str(os));
+}
+
 const std::string& MessageBuffer::str(CharMessageBuffer& buf)
 {
 	return m_priv->cbuf.str(buf);
@@ -449,6 +479,16 @@ WideMessageBuffer& MessageBuffer::operator<<(const wchar_t msg)
 	return (*m_priv->wbuf) << msg;
 }
 
+std::wstring MessageBuffer::extract_str(WideMessageBuffer& buf)
+{
+	return std::move(m_priv->wbuf->extract_str(buf));
+}
+
+std::wstring MessageBuffer::extract_str(std::basic_ostream<wchar_t>& os)
+{
+	return std::move(m_priv->wbuf->extract_str(os));
+}
+
 const std::wstring& MessageBuffer::str(WideMessageBuffer& buf)
 {
 	return m_priv->wbuf->str(buf);
@@ -524,6 +564,16 @@ UniCharMessageBuffer& MessageBuffer::operator<<(const log4cxx::UniChar msg)
 	return (*m_priv->ubuf) << msg;
 }
 
+std::basic_string<log4cxx::UniChar> MessageBuffer::extract_str(UniCharMessageBuffer& buf)
+{
+	return std::move(m_priv->ubuf->extract_str(buf));
+}
+
+std::basic_string<log4cxx::UniChar> MessageBuffer::extract_str(std::basic_ostream<log4cxx::UniChar>& os)
+{
+	return std::move(m_priv->ubuf->extract_str(os));
+}
+
 const std::basic_string<log4cxx::UniChar>& MessageBuffer::str(UniCharMessageBuffer& buf)
 {
 	return m_priv->ubuf->str(buf);
@@ -609,6 +659,16 @@ UniCharMessageBuffer::operator UniCharMessageBuffer::uostream& ()
 	return m_priv->StreamFromBuf();
 }
 
+std::basic_string<log4cxx::UniChar> UniCharMessageBuffer::extract_str(UniCharMessageBuffer::uostream&)
+{
+	return std::move(m_priv->BufFromStream());
+}
+
+std::basic_string<log4cxx::UniChar> UniCharMessageBuffer::extract_str(UniCharMessageBuffer&)
+{
+	return std::move(m_priv->buf);
+}
+
 const std::basic_string<log4cxx::UniChar>& UniCharMessageBuffer::str(UniCharMessageBuffer::uostream&)
 {
 	return m_priv->BufFromStream();
diff --git a/src/main/include/log4cxx/helpers/messagebuffer.h b/src/main/include/log4cxx/helpers/messagebuffer.h
index cb85102c..0eed9e9b 100644
--- a/src/main/include/log4cxx/helpers/messagebuffer.h
+++ b/src/main/include/log4cxx/helpers/messagebuffer.h
@@ -148,6 +148,20 @@ class LOG4CXX_EXPORT CharMessageBuffer
 		 */
 		operator std::basic_ostream<char>& ();
 
+		/**
+		 *   Remove the constucted string.
+		 *   @param os used only to signal that
+		 *       the embedded stream was used.
+		 */
+		std::basic_string<char> extract_str(std::basic_ostream<char>& os);
+
+		/**
+		 *   Remove the constucted string.
+		 *   @param buf used only to signal that
+		 *       the embedded stream was not used.
+		 */
+		std::basic_string<char> extract_str(CharMessageBuffer& buf);
+
 		/**
 		 *   Get content of buffer.
 		 *   @param os used only to signal that
@@ -318,6 +332,20 @@ class LOG4CXX_EXPORT UniCharMessageBuffer
 		*/
 		operator uostream& ();
 
+		/**
+		 *   Remove the constructed string.
+		 *   @param os used only to signal that
+		 *       the embedded stream was used.
+		 */
+		std::basic_string<UniChar> extract_str(uostream& os);
+
+		/**
+		 *   Remove the constructed string.
+		 *   @param buf used only to signal that
+		 *       the embedded stream was not used.
+		 */
+		std::basic_string<UniChar> extract_str(UniCharMessageBuffer& buf);
+
 		/**
 		 *   Get content of buffer.
 		 *   @param os used only to signal that
@@ -477,6 +505,20 @@ class LOG4CXX_EXPORT WideMessageBuffer
 		*/
 		operator std::basic_ostream<wchar_t>& ();
 
+		/**
+		 *   Remove the constructed string.
+		 *   @param os used only to signal that
+		 *       the embedded stream was used.
+		 */
+		std::basic_string<wchar_t> extract_str(std::basic_ostream<wchar_t>& os);
+
+		/**
+		 *   Remove the constructed string.
+		 *   @param buf used only to signal that
+		 *       the embedded stream was not used.
+		 */
+		std::basic_string<wchar_t> extract_str(WideMessageBuffer& buf);
+
 		/**
 		 *   Get content of buffer.
 		 *   @param os used only to signal that
@@ -568,6 +610,22 @@ class LOG4CXX_EXPORT MessageBuffer
 		 */
 		CharMessageBuffer& operator<<(const char msg);
 
+		/**
+		 *   Remove the constructed string.
+		 *   @param buf used only to signal
+		 *       the character type and that
+		 *       the embedded stream was not used.
+		 */
+		std::string extract_str(CharMessageBuffer& buf);
+
+		/**
+		 *   Remove the constructed string.
+		 *   @param os used only to signal
+		 *       the character type and that
+		 *       the embedded stream was used.
+		 */
+		std::string extract_str(std::ostream& os);
+
 		/**
 		 *   Get content of buffer.
 		 *   @param buf used only to signal
@@ -722,6 +780,22 @@ class LOG4CXX_EXPORT MessageBuffer
 		 *   @return encapsulated STL stream.
 		 */
 		std::ostream& operator<<(void* val);
+		/**
+		 *   Remove the constructed string.
+		 *   @param buf used only to signal
+		 *       the character type and that
+		 *       the embedded stream was not used.
+		 */
+		std::wstring extract_str(WideMessageBuffer& buf);
+
+		/**
+		 *   Remove the constructed string.
+		 *   @param os used only to signal
+		 *       the character type and that
+		 *       the embedded stream was used.
+		 */
+		std::wstring extract_str(std::basic_ostream<wchar_t>& os);
+
 		/**
 		 *   Get content of buffer.
 		 *   @param buf used only to signal
diff --git a/src/main/include/log4cxx/logger.h b/src/main/include/log4cxx/logger.h
index 14edd657..16de09d6 100644
--- a/src/main/include/log4cxx/logger.h
+++ b/src/main/include/log4cxx/logger.h
@@ -499,10 +499,12 @@ class LOG4CXX_EXPORT Logger :
 		/**
 		Add a new logging event containing \c message and \c location to attached appender(s).
 		without further checks.
-		@param level the level to log.
-		@param message message.
-		@param location location of source of logging request.
+		@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, std::string&& message
+			, const spi::LocationInfo& location = spi::LocationInfo::getLocationUnavailable()) const;
 		void forcedLog(const LevelPtr& level, const std::string& message,
 			const log4cxx::spi::LocationInfo& location) const;
 		/**
@@ -517,10 +519,12 @@ class LOG4CXX_EXPORT Logger :
 		/**
 		Add a new logging event containing \c message and \c location to attached appender(s).
 		without further checks.
-		@param level the level to log.
-		@param message message.
-		@param location location of source of logging request.
+		@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, std::wstring&& message
+			, const spi::LocationInfo& location = spi::LocationInfo::getLocationUnavailable()) const;
 		void forcedLog(const LevelPtr& level, const std::wstring& message,
 			const log4cxx::spi::LocationInfo& location) const;
 		/**
@@ -574,6 +578,8 @@ class LOG4CXX_EXPORT Logger :
 		@param message the message string to log.
 		@param location location of the logging statement.
 		*/
+		void addEventLS(const LevelPtr& level, LogString&& message
+			, const spi::LocationInfo& location = spi::LocationInfo::getLocationUnavailable()) const;
 		void forcedLogLS(const LevelPtr& level, const LogString& message,
 			const log4cxx::spi::LocationInfo& location) const;
 
@@ -1987,7 +1993,7 @@ Add a new logging event containing \c message to attached appender(s) if this lo
 #define LOG4CXX_LOG(logger, level, message) do { \
 		if (logger->isEnabledFor(level)) {\
 			::log4cxx::helpers::MessageBuffer oss_; \
-			logger->forcedLog(level, oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(level, oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 /**
 Add a new logging event containing libfmt formatted <code>...</code> to attached appender(s) if this logger is enabled for \c events.
@@ -1998,7 +2004,7 @@ Add a new logging event containing libfmt formatted <code>...</code> to attached
 */
 #define LOG4CXX_LOG_FMT(logger, level, ...) do { \
 		if (logger->isEnabledFor(level)) {\
-			logger->forcedLog(level, fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(level, fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
 
 /**
 Add a new logging event containing \c message to attached appender(s) if this logger is enabled for \c events.
@@ -2010,7 +2016,7 @@ Add a new logging event containing \c message to attached appender(s) if this lo
 #define LOG4CXX_LOGLS(logger, level, message) do { \
 		if (logger->isEnabledFor(level)) {\
 			::log4cxx::helpers::LogCharMessageBuffer oss_; \
-			logger->forcedLog(level, oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(level, oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 #if !defined(LOG4CXX_THRESHOLD) || LOG4CXX_THRESHOLD <= 10000
 /**
@@ -2034,7 +2040,7 @@ LOG4CXX_DEBUG(m_log, "AddMesh:"
 #define LOG4CXX_DEBUG(logger, message) do { \
 		if (LOG4CXX_UNLIKELY(::log4cxx::Logger::isDebugEnabledFor(logger))) {\
 			::log4cxx::helpers::MessageBuffer oss_; \
-			logger->forcedLog(::log4cxx::Level::getDebug(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getDebug(), oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 /**
 Add a new logging event containing libfmt formatted <code>...</code> to attached appender(s) if \c logger is enabled for <code>DEBUG</code> events.
@@ -2044,7 +2050,7 @@ Add a new logging event containing libfmt formatted <code>...</code> to attached
 */
 #define LOG4CXX_DEBUG_FMT(logger, ...) do { \
 		if (LOG4CXX_UNLIKELY(::log4cxx::Logger::isDebugEnabledFor(logger))) {\
-			logger->forcedLog(::log4cxx::Level::getDebug(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getDebug(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
 #else
 #define LOG4CXX_DEBUG(logger, message)
 #define LOG4CXX_DEBUG_FMT(logger, ...)
@@ -2066,7 +2072,7 @@ Add a new logging event containing \c message to attached appender(s) if \c logg
 #define LOG4CXX_TRACE(logger, message) do { \
 		if (LOG4CXX_UNLIKELY(::log4cxx::Logger::isTraceEnabledFor(logger))) {\
 			::log4cxx::helpers::MessageBuffer oss_; \
-			logger->forcedLog(::log4cxx::Level::getTrace(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getTrace(), oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 /**
 Add a new logging event containing libfmt formatted <code>...</code> to attached appender(s) if \c logger is enabled for <code>TRACE</code> events.
@@ -2076,7 +2082,7 @@ Add a new logging event containing libfmt formatted <code>...</code> to attached
 */
 #define LOG4CXX_TRACE_FMT(logger, ...) do { \
 		if (LOG4CXX_UNLIKELY(::log4cxx::Logger::isTraceEnabledFor(logger))) {\
-			logger->forcedLog(::log4cxx::Level::getTrace(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getTrace(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
 #else
 #define LOG4CXX_TRACE(logger, message)
 #define LOG4CXX_TRACE_FMT(logger, ...)
@@ -2102,7 +2108,7 @@ LOG4CXX_INFO(m_log, surface->GetName()
 #define LOG4CXX_INFO(logger, message) do { \
 		if (::log4cxx::Logger::isInfoEnabledFor(logger)) {\
 			::log4cxx::helpers::MessageBuffer oss_; \
-			logger->forcedLog(::log4cxx::Level::getInfo(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getInfo(), oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 /**
 Add a new logging event containing libfmt formatted <code>...</code> to attached appender(s) if \c logger is enabled for <code>INFO</code> events.
@@ -2112,7 +2118,7 @@ Add a new logging event containing libfmt formatted <code>...</code> to attached
 */
 #define LOG4CXX_INFO_FMT(logger, ...) do { \
 		if (::log4cxx::Logger::isInfoEnabledFor(logger)) {\
-			logger->forcedLog(::log4cxx::Level::getInfo(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getInfo(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
 #else
 #define LOG4CXX_INFO(logger, message)
 #define LOG4CXX_INFO_FMT(logger, ...)
@@ -2136,7 +2142,7 @@ catch (const std::exception& ex)
 #define LOG4CXX_WARN(logger, message) do { \
 		if (::log4cxx::Logger::isWarnEnabledFor(logger)) {\
 			::log4cxx::helpers::MessageBuffer oss_; \
-			logger->forcedLog(::log4cxx::Level::getWarn(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getWarn(), oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 /**
 Add a new logging event containing libfmt formatted <code>...</code> to attached appender(s) if \c logger is enabled for <code>WARN</code> events.
@@ -2146,7 +2152,7 @@ Add a new logging event containing libfmt formatted <code>...</code> to attached
 */
 #define LOG4CXX_WARN_FMT(logger, ...) do { \
 		if (::log4cxx::Logger::isWarnEnabledFor(logger)) {\
-			logger->forcedLog(::log4cxx::Level::getWarn(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getWarn(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
 #else
 #define LOG4CXX_WARN(logger, message)
 #define LOG4CXX_WARN_FMT(logger, ...)
@@ -2170,7 +2176,7 @@ catch (std::exception& ex)
 #define LOG4CXX_ERROR(logger, message) do { \
 		if (::log4cxx::Logger::isErrorEnabledFor(logger)) {\
 			::log4cxx::helpers::MessageBuffer oss_; \
-			logger->forcedLog(::log4cxx::Level::getError(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getError(), oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 /**
 Add a new logging event containing libfmt formatted <code>...</code> to attached appender(s) if \c logger is enabled for <code>ERROR</code> events.
@@ -2180,7 +2186,7 @@ Add a new logging event containing libfmt formatted <code>...</code> to attached
 */
 #define LOG4CXX_ERROR_FMT(logger, ...) do { \
 		if (::log4cxx::Logger::isErrorEnabledFor(logger)) {\
-			logger->forcedLog(::log4cxx::Level::getError(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getError(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
 
 /**
 If \c condition is not true, add a new logging event containing \c message to attached appender(s) if \c logger is enabled for <code>ERROR</code> events.
@@ -2193,7 +2199,7 @@ If \c condition is not true, add a new logging event containing \c message to at
 		if (!(condition) && ::log4cxx::Logger::isErrorEnabledFor(logger)) {\
 			::log4cxx::helpers::MessageBuffer oss_; \
 			LOG4CXX_STACKTRACE \
-			logger->forcedLog(::log4cxx::Level::getError(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getError(), oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 /**
 If \c condition is not true, add a new logging event containing libfmt formatted \c message to attached appender(s) if \c logger is enabled for <code>ERROR</code> events.
@@ -2205,7 +2211,7 @@ If \c condition is not true, add a new logging event containing libfmt formatted
 #define LOG4CXX_ASSERT_FMT(logger, condition, ...) do { \
 		if (!(condition) && ::log4cxx::Logger::isErrorEnabledFor(logger)) {\
 			LOG4CXX_STACKTRACE \
-			logger->forcedLog(::log4cxx::Level::getError(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getError(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
 
 #else
 #define LOG4CXX_ERROR(logger, message)
@@ -2229,7 +2235,7 @@ LOG4CXX_FATAL(m_log, m_renderSystem->getName() << " is not supported");
 #define LOG4CXX_FATAL(logger, message) do { \
 		if (::log4cxx::Logger::isFatalEnabledFor(logger)) {\
 			::log4cxx::helpers::MessageBuffer oss_; \
-			logger->forcedLog(::log4cxx::Level::getFatal(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getFatal(), oss_.extract_str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
 
 /**
 Add a new logging event containing libfmt formatted <code>...</code> to attached appender(s) if \c logger is enabled for <code>FATAL</code> events.
@@ -2239,7 +2245,7 @@ Add a new logging event containing libfmt formatted <code>...</code> to attached
 */
 #define LOG4CXX_FATAL_FMT(logger, ...) do { \
 		if (::log4cxx::Logger::isFatalEnabledFor(logger)) {\
-			logger->forcedLog(::log4cxx::Level::getFatal(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+			logger->addEvent(::log4cxx::Level::getFatal(), fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
 #else
 #define LOG4CXX_FATAL(logger, message)
 #define LOG4CXX_FATAL_FMT(logger, ...)
diff --git a/src/main/include/log4cxx/spi/loggingevent.h b/src/main/include/log4cxx/spi/loggingevent.h
index 8641fcf6..b4234624 100644
--- a/src/main/include/log4cxx/spi/loggingevent.h
+++ b/src/main/include/log4cxx/spi/loggingevent.h
@@ -69,8 +69,26 @@ class LOG4CXX_EXPORT LoggingEvent :
 		<p>
 		@param logger The logger of this event.
 		@param level The level of this event.
-		@param message  The message of this event.
-		@param location location of logging request.
+		@param location The source code location of the logging request.
+		@param message  The text to add to this event.
+		*/
+		LoggingEvent
+			( const LogString& logger
+			, const LevelPtr& level
+			, const spi::LocationInfo& location
+			, LogString&& message
+			);
+
+		/**
+		Instantiate a LoggingEvent from the supplied parameters.
+
+		<p>Except timeStamp all the other fields of
+		<code>LoggingEvent</code> are filled when actually needed.
+		<p>
+		@param logger The logger of this event.
+		@param level The level of this event.
+		@param message  The text to add to this event.
+		@param location The source code location of the logging request.
 		*/
 		LoggingEvent(const LogString& logger,
 			const LevelPtr& level,   const LogString& message,