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

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


The following commit(s) were added to refs/heads/LOGCXX-567 by this push:
     new 62439b18 Turn the stacktrace into a call-site macro instead of inside 
the library
62439b18 is described below

commit 62439b188cd7f5d009b6e4f53a95067d6404643b
Author: Robert Middleton <[email protected]>
AuthorDate: Thu Dec 15 20:42:53 2022 -0500

    Turn the stacktrace into a call-site macro instead of inside the library
---
 src/main/cpp/CMakeLists.txt                        |   6 ++
 src/main/cpp/logbuilder.cpp                        |  29 ++++++
 src/main/cpp/logger.cpp                            |  54 +++++------
 src/main/cpp/loggingevent.cpp                      |  46 ++++++++--
 src/main/cpp/stacktracepatternconverter.cpp        |   5 +
 src/main/include/log4cxx/log4cxx.h.in              |   1 +
 src/main/include/log4cxx/logbuilder.h              |  55 +++++++++++
 src/main/include/log4cxx/logger.h                  | 102 ++++++++++++++-------
 .../include/log4cxx/private/log4cxx_private.h.in   |   1 -
 .../include/log4cxx/spi/location/locationinfo.h    |   1 -
 src/main/include/log4cxx/spi/loggingevent.h        |  10 ++
 11 files changed, 241 insertions(+), 69 deletions(-)

diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt
index 59276e19..f2ab2796 100644
--- a/src/main/cpp/CMakeLists.txt
+++ b/src/main/cpp/CMakeLists.txt
@@ -27,6 +27,11 @@ else()
 endif()
 add_dependencies(log4cxx configure_log4cxx)
 
+get_directory_property( HAS_BOOST_STACKTRACE DIRECTORY ../include DEFINITION 
HAS_BOOST_STACKTRACE )
+if(HAS_BOOST_STACKTRACE)
+    target_compile_definitions(log4cxx PRIVATE LOG4CXX_ENABLE_STACKTRACE)
+endif()
+
 set(extra_classes "")
 
 if(LOG4CXX_NETWORKING_SUPPORT)
@@ -126,6 +131,7 @@ target_sources(log4cxx
   loader.cpp
   locale.cpp
   locationinfo.cpp
+  logbuilder.cpp
   logger.cpp
   loggermatchfilter.cpp
   loggerpatternconverter.cpp
diff --git a/src/main/cpp/logbuilder.cpp b/src/main/cpp/logbuilder.cpp
new file mode 100644
index 00000000..12bda43f
--- /dev/null
+++ b/src/main/cpp/logbuilder.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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/logbuilder.h>
+
+using log4cxx::OptionalLogParams;
+
+OptionalLogParams::OptionalLogParams(){}
+
+#if LOG4CXX_HAS_BOOST_STACKTRACE
+OptionalLogParams OptionalLogParams::setStacktrace(const 
boost::stacktrace::stacktrace* stacktrace){
+       m_builderParams[ParameterType::BoostStacktrace] = stacktrace;
+       return *this;
+}
+#endif
diff --git a/src/main/cpp/logger.cpp b/src/main/cpp/logger.cpp
index 8c7d8ba5..8233ce65 100644
--- a/src/main/cpp/logger.cpp
+++ b/src/main/cpp/logger.cpp
@@ -158,27 +158,27 @@ void Logger::closeNestedAppenders()
        }
 }
 
-
 void Logger::forcedLog(const LevelPtr& level1, const std::string& message,
-       const LocationInfo& location) const
+       const LocationInfo& location, const log4cxx::OptionalLogParams& 
optionalParams) 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, 
location);
-       callAppenders(event, p);
-}
-
+#if LOG4CXX_HAS_BOOST_STACKTRACE
+       auto it = 
optionalParams.m_builderParams.find(OptionalLogParams::ParameterType::BoostStacktrace);
+       const boost::stacktrace::stacktrace* stacktrace = nullptr;
+       if( it != optionalParams.m_builderParams.end() ){
+               stacktrace = static_cast<const 
boost::stacktrace::stacktrace*>(it->second);
+       }
+#endif
+       LoggingEventPtr event;
 
-void Logger::forcedLog(const LevelPtr& level1, const std::string& message) 
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());
+       if(stacktrace){
+               event = std::make_shared<LoggingEvent>(m_priv->name, level1, 
msg, location, *stacktrace);
+       }else{
+               event = std::make_shared<LoggingEvent>(m_priv->name, level1, 
msg, location);
+       }
        callAppenders(event, p);
 }
 
@@ -703,24 +703,26 @@ 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
+       const LocationInfo& location, const log4cxx::OptionalLogParams& 
optionalParams) 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, 
location);
-       callAppenders(event, p);
-}
+#if LOG4CXX_HAS_BOOST_STACKTRACE
+       auto it = 
optionalParams.m_builderParams.find(OptionalLogParams::ParameterType::BoostStacktrace);
+       const boost::stacktrace::stacktrace* stacktrace = nullptr;
+       if( it != optionalParams.m_builderParams.end() ){
+               stacktrace = static_cast<const 
boost::stacktrace::stacktrace*>(it->second);
+       }
+#endif
+       LoggingEventPtr event;
 
-void Logger::forcedLog(const LevelPtr& level1, const std::wstring& message) 
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());
+       if(stacktrace){
+               event = std::make_shared<LoggingEvent>(m_priv->name, level1, 
msg, location, *stacktrace);
+       }else{
+               event = std::make_shared<LoggingEvent>(m_priv->name, level1, 
msg, location);
+       }
        callAppenders(event, p);
 }
 
diff --git a/src/main/cpp/loggingevent.cpp b/src/main/cpp/loggingevent.cpp
index 0b1f1930..b6f23671 100644
--- a/src/main/cpp/loggingevent.cpp
+++ b/src/main/cpp/loggingevent.cpp
@@ -81,6 +81,27 @@ struct LoggingEvent::LoggingEventPrivate
        {
        }
 
+       LoggingEventPrivate(
+               const LogString& logger1, const LevelPtr& level1,
+               const LogString& message1, const LocationInfo& locationInfo1,
+               const boost::stacktrace::stacktrace& stacktrace) :
+               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)),
+               
stacktrace(std::make_unique<boost::stacktrace::stacktrace>(stacktrace))
+       {
+       }
+
        ~LoggingEventPrivate()
        {
                delete ndc;
@@ -148,7 +169,10 @@ struct LoggingEvent::LoggingEventPrivate
        std::chrono::time_point<std::chrono::system_clock> chronoTimeStamp;
 
 #if LOG4CXX_HAS_BOOST_STACKTRACE
-       boost::stacktrace::stacktrace stacktrace;
+       // we make this a unique_ptr so we can avoid constructing it by default.
+       // This should add only a small amount of overhead when stacktraces are
+       // enabled in order to dereference the pointer.
+       std::unique_ptr<boost::stacktrace::stacktrace> stacktrace;
 #endif
 };
 
@@ -175,6 +199,16 @@ LoggingEvent::LoggingEvent(
 {
 }
 
+#if LOG4CXX_HAS_BOOST_STACKTRACE
+LoggingEvent::LoggingEvent(
+       const LogString& logger1, const LevelPtr& level1,
+       const LogString& message1, const LocationInfo& locationInfo1,
+       const boost::stacktrace::stacktrace& stacktrace) :
+       m_priv(std::make_unique<LoggingEventPrivate>(logger1, level1, message1, 
locationInfo1, stacktrace))
+{
+}
+#endif
+
 LoggingEvent::~LoggingEvent()
 {
 }
@@ -449,11 +483,11 @@ std::chrono::time_point<std::chrono::system_clock> 
LoggingEvent::getChronoTimeSt
 }
 
 LogString LoggingEvent::getStacktrace() const{
-#if !LOG4CXX_HAS_BOOST_STACKTRACE
-       return LogString();
-#else
-       ::log4cxx::helpers::MessageBuffer oss_;
-       return oss_.str(oss_ << m_priv->stacktrace);
+#if LOG4CXX_HAS_BOOST_STACKTRACE
+       if(m_priv->stacktrace){
+               return boost::stacktrace::to_string(*m_priv->stacktrace);
+       }
 #endif
+       return LogString();
 }
 
diff --git a/src/main/cpp/stacktracepatternconverter.cpp 
b/src/main/cpp/stacktracepatternconverter.cpp
index 5fb71db4..75e48962 100644
--- a/src/main/cpp/stacktracepatternconverter.cpp
+++ b/src/main/cpp/stacktracepatternconverter.cpp
@@ -45,6 +45,11 @@ void StacktracePatternConverter::format(
        LogString& toAppendTo,
        Pool& /* p */) const
 {
+       LogString stacktrace = event->getStacktrace();
+       if(stacktrace.empty()){
+               return;
+       }
+       toAppendTo.append(LOG4CXX_EOL);
        toAppendTo.append(event->getStacktrace());
 }
 
diff --git a/src/main/include/log4cxx/log4cxx.h.in 
b/src/main/include/log4cxx/log4cxx.h.in
index 12ed0dbc..c67fd99d 100644
--- a/src/main/include/log4cxx/log4cxx.h.in
+++ b/src/main/include/log4cxx/log4cxx.h.in
@@ -50,6 +50,7 @@
 #define LOG4CXX_CFSTRING_API @CFSTRING_API@
 #define LOG4CXX_HAS_NETWORKING @NETWORKING_SUPPORT@
 #define LOG4CXX_HAS_MULTIPROCESS_ROLLING_FILE_APPENDER @MULTIPROCESS_RFA@
+#define LOG4CXX_HAS_BOOST_STACKTRACE @HAS_BOOST_STACKTRACE@
 
 typedef long long log4cxx_int64_t;
 #define LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE 0
diff --git a/src/main/include/log4cxx/logbuilder.h 
b/src/main/include/log4cxx/logbuilder.h
new file mode 100644
index 00000000..7e3dbbe2
--- /dev/null
+++ b/src/main/include/log4cxx/logbuilder.h
@@ -0,0 +1,55 @@
+/*
+ * 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_LOGBUILDER_H
+#define _LOG4CXX_LOGBUILDER_H
+
+#include <log4cxx/spi/location/locationinfo.h>
+#include <log4cxx/level.h>
+#include <map>
+
+#if defined(LOG4CXX_ENABLE_STACKTRACE) && LOG4CXX_HAS_BOOST_STACKTRACE
+#include <boost/stacktrace.hpp>
+#endif
+
+namespace log4cxx {
+
+/**
+ * The OptionalLogParams class provides a way of providing optional log 
parameters,
+ * depending on if the feature is enabled by client code or not.
+ */
+class OptionalLogParams{
+public:
+       enum class ParameterType{
+       BoostStacktrace,
+    };
+
+       OptionalLogParams();
+
+#if defined(LOG4CXX_ENABLE_STACKTRACE) && LOG4CXX_HAS_BOOST_STACKTRACE
+       OptionalLogParams setStacktrace(const boost::stacktrace::stacktrace* 
stacktrace);
+#endif
+
+private:
+    std::map<ParameterType,const void*> m_builderParams;
+
+    friend class Logger;
+};
+
+}
+
+#endif
diff --git a/src/main/include/log4cxx/logger.h 
b/src/main/include/log4cxx/logger.h
index 27eb93d1..c0e3b19a 100644
--- a/src/main/include/log4cxx/logger.h
+++ b/src/main/include/log4cxx/logger.h
@@ -24,6 +24,7 @@
 #include <log4cxx/spi/location/locationinfo.h>
 #include <log4cxx/helpers/resourcebundle.h>
 #include <log4cxx/helpers/messagebuffer.h>
+#include <log4cxx/logbuilder.h>
 
 namespace log4cxx
 {
@@ -457,15 +458,10 @@ class LOG4CXX_EXPORT Logger :
                @param message message.
                @param location location of source of logging request.
                */
-               void forcedLog(const LevelPtr& level, const std::string& 
message,
-                       const log4cxx::spi::LocationInfo& location) const;
-               /**
-               This method creates a new logging event and logs the event
-               without further checks.
-               @param level the level to log.
-               @param message message.
-               */
-               void forcedLog(const LevelPtr& level, const std::string& 
message) const;
+               void forcedLog(const LevelPtr& level,
+                       const std::string& message,
+                       const log4cxx::spi::LocationInfo& location = 
log4cxx::spi::LocationInfo::getLocationUnavailable(),
+                       const log4cxx::OptionalLogParams& optionalParams = 
log4cxx::OptionalLogParams()) const;
 
 #if LOG4CXX_WCHAR_T_API
                /**
@@ -475,15 +471,11 @@ class LOG4CXX_EXPORT Logger :
                @param message message.
                @param location location of source of logging request.
                */
-               void forcedLog(const LevelPtr& level, const std::wstring& 
message,
-                       const log4cxx::spi::LocationInfo& location) const;
-               /**
-               This method creates a new logging event and logs the event
-               without further checks.
-               @param level the level to log.
-               @param message message.
-               */
-               void forcedLog(const LevelPtr& level, const std::wstring& 
message) const;
+               void forcedLog(const LevelPtr& level,
+                       const std::wstring& message,
+                       const log4cxx::spi::LocationInfo& location = 
log4cxx::spi::LocationInfo::getLocationUnavailable(),
+                       const log4cxx::OptionalLogParams& optionalParams = 
log4cxx::OptionalLogParams()) const;
+
 #endif
 #if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API
                /**
@@ -1718,6 +1710,12 @@ LOG4CXX_LIST_DEF(LoggerList, LoggerPtr);
        #endif
 #endif
 
+#if defined(LOG4CXX_ENABLE_STACKTRACE) && LOG4CXX_HAS_BOOST_STACKTRACE
+#define LOG4CXX_STACKTRACE const boost::stacktrace::stacktrace stack_trace; \
+       builder.setStacktrace(&stack_trace);
+#else
+#define LOG4CXX_STACKTRACE
+#endif
 
 /**
 Logs a message to a specified logger with a specified level.
@@ -1729,7 +1727,9 @@ Logs a message to a specified logger with a specified 
level.
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(level, oss_.str(oss_ << message), 
LOG4CXX_LOCATION, builder); }} while (0)
 
 /**
 Logs a message to a specified logger with a specified level, formatting 
utilizing libfmt
@@ -1740,7 +1740,9 @@ Logs a message to a specified logger with a specified 
level, formatting utilizin
 */
 #define LOG4CXX_LOG_FMT(logger, level, ...) do { \
                if (logger->isEnabledFor(level)) {\
-                       logger->forcedLog(level, fmt::format( __VA_ARGS__ ), 
LOG4CXX_LOCATION); }} while (0)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(level, fmt::format( __VA_ARGS__ ), 
LOG4CXX_LOCATION, builder); }} while (0)
 
 /**
 Logs a message to a specified logger with a specified level.
@@ -1752,7 +1754,9 @@ Logs a message to a specified logger with a specified 
level.
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(level, oss_.str(oss_ << message), 
LOG4CXX_LOCATION, builder); }} while (0)
 
 #if !defined(LOG4CXX_THRESHOLD) || LOG4CXX_THRESHOLD <= 10000
 /**
@@ -1764,7 +1768,9 @@ Logs a message to a specified logger with the DEBUG level.
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getDebug(), 
oss_.str(oss_ << message), LOG4CXX_LOCATION, builder); }} while (0)
 
 /**
 Logs a message to a specified logger with the DEBUG level, formatting with 
libfmt
@@ -1774,7 +1780,9 @@ Logs a message to a specified logger with the DEBUG 
level, formatting with libfm
 */
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getDebug(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION, builder);  }} while (0)
 #else
 #define LOG4CXX_DEBUG(logger, message)
 #define LOG4CXX_DEBUG_FMT(logger, ...)
@@ -1790,7 +1798,9 @@ Logs a message to a specified logger with the TRACE level.
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getTrace(), 
oss_.str(oss_ << message), LOG4CXX_LOCATION, builder); }} while (0)
 
 /**
 Logs a message to a specified logger with the TRACE level, formatting with 
libfmt.
@@ -1800,7 +1810,9 @@ Logs a message to a specified logger with the TRACE 
level, formatting with libfm
 */
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getTrace(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION, builder); }} while (0)
 #else
 #define LOG4CXX_TRACE(logger, message)
 #define LOG4CXX_TRACE_FMT(logger, ...)
@@ -1816,7 +1828,9 @@ Logs a message to a specified logger with the INFO level.
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getInfo(), 
oss_.str(oss_ << message), LOG4CXX_LOCATION, builder);  }} while (0)
 
 /**
 Logs a message to a specified logger with the INFO level, formatting with 
libfmt.
@@ -1827,7 +1841,9 @@ Logs a message to a specified logger with the INFO level, 
formatting with libfmt
 */
 #define LOG4CXX_INFO_FMT(logger, ...) do { \
                if (::log4cxx::Logger::isInfoEnabledFor(logger)) {\
-                       logger->forcedLog(::log4cxx::Level::getInfo(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getInfo(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION, builder); }} while (0)
 #else
 #define LOG4CXX_INFO(logger, message)
 #define LOG4CXX_INFO_FMT(logger, ...)
@@ -1843,7 +1859,9 @@ Logs a message to a specified logger with the WARN level.
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getWarn(), 
oss_.str(oss_ << message), LOG4CXX_LOCATION, builder);  }} while (0)
 
 /**
 Logs a message to a specified logger with the WARN level, formatting with 
libfmt
@@ -1853,7 +1871,9 @@ Logs a message to a specified logger with the WARN level, 
formatting with libfmt
 */
 #define LOG4CXX_WARN_FMT(logger, ...) do { \
                if (::log4cxx::Logger::isWarnEnabledFor(logger)) {\
-                       logger->forcedLog(::log4cxx::Level::getWarn(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getWarn(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION, builder); }} while (0)
 #else
 #define LOG4CXX_WARN(logger, message)
 #define LOG4CXX_WARN_FMT(logger, ...)
@@ -1869,7 +1889,9 @@ Logs a message to a specified logger with the ERROR level.
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getError(), 
oss_.str(oss_ << message), LOG4CXX_LOCATION, builder);  }} while (0)
 
 /**
 Logs a message to a specified logger with the ERROR level, formatting with 
libfmt
@@ -1879,7 +1901,9 @@ Logs a message to a specified logger with the ERROR 
level, formatting with libfm
 */
 #define LOG4CXX_ERROR_FMT(logger, ...) do { \
                if (::log4cxx::Logger::isErrorEnabledFor(logger)) {\
-                       logger->forcedLog(::log4cxx::Level::getError(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getError(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION, builder); }} while (0)
 
 /**
 Logs a error if the condition is not true.
@@ -1891,7 +1915,9 @@ Logs a error if the condition is not true.
 #define LOG4CXX_ASSERT(logger, condition, message) do { \
                if (!(condition) && 
::log4cxx::Logger::isErrorEnabledFor(logger)) {\
                        ::log4cxx::helpers::MessageBuffer oss_; \
-                       logger->forcedLog(::log4cxx::Level::getError(), 
oss_.str(oss_ << message), LOG4CXX_LOCATION); }} while (0)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getError(), 
oss_.str(oss_ << message), LOG4CXX_LOCATION, builder); }} while (0)
 
 /**
 Logs a error if the condition is not true, formatting with libfmt
@@ -1902,7 +1928,9 @@ Logs a error if the condition is not true, formatting 
with libfmt
 */
 #define LOG4CXX_ASSERT_FMT(logger, condition, ...) do { \
                if (!(condition) && 
::log4cxx::Logger::isErrorEnabledFor(logger)) {\
-                       logger->forcedLog(::log4cxx::Level::getError(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getError(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION, builder); }} while (0)
 
 #else
 #define LOG4CXX_ERROR(logger, message)
@@ -1921,7 +1949,9 @@ Logs a message to a specified logger with the FATAL level.
 #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)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getFatal(), 
oss_.str(oss_ << message), LOG4CXX_LOCATION, builder);  }} while (0)
 
 /**
 Logs a message to a specified logger with the FATAL level, formatting with 
libfmt
@@ -1931,7 +1961,9 @@ Logs a message to a specified logger with the FATAL 
level, formatting with libfm
 */
 #define LOG4CXX_FATAL_FMT(logger, ...) do { \
                if (::log4cxx::Logger::isFatalEnabledFor(logger)) {\
-                       logger->forcedLog(::log4cxx::Level::getFatal(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION); }} while (0)
+                       ::log4cxx::OptionalLogParams builder; \
+                       LOG4CXX_STACKTRACE \
+                       logger->forcedLog(::log4cxx::Level::getFatal(), 
fmt::format( __VA_ARGS__ ), LOG4CXX_LOCATION, builder); }} while (0)
 #else
 #define LOG4CXX_FATAL(logger, message)
 #define LOG4CXX_FATAL_FMT(logger, ...)
diff --git a/src/main/include/log4cxx/private/log4cxx_private.h.in 
b/src/main/include/log4cxx/private/log4cxx_private.h.in
index b6ad1bdb..9eb5ec23 100644
--- a/src/main/include/log4cxx/private/log4cxx_private.h.in
+++ b/src/main/include/log4cxx/private/log4cxx_private.h.in
@@ -63,6 +63,5 @@
 #define LOG4CXX_HAS_SETTHREADDESCRIPTION @HAS_SETTHREADDESCRIPTION@
 #define LOG4CXX_HAS_GETTHREADDESCRIPTION @HAS_GETTHREADDESCRIPTION@
 #define LOG4CXX_HAS_THREAD_LOCAL @HAS_THREAD_LOCAL@
-#define LOG4CXX_HAS_BOOST_STACKTRACE @HAS_BOOST_STACKTRACE@
 
 #endif
diff --git a/src/main/include/log4cxx/spi/location/locationinfo.h 
b/src/main/include/log4cxx/spi/location/locationinfo.h
index 51b1ce4c..eac4861d 100644
--- a/src/main/include/log4cxx/spi/location/locationinfo.h
+++ b/src/main/include/log4cxx/spi/location/locationinfo.h
@@ -169,7 +169,6 @@ class LOG4CXX_EXPORT LocationInfo
        #define __LOG4CXX_FUNC__ ""
 #endif
 
-
 #define LOG4CXX_LOCATION ::log4cxx::spi::LocationInfo(__FILE__,         \
        ::log4cxx::spi::LocationInfo::calcShortFileName(__FILE__), \
        __LOG4CXX_FUNC__, \
diff --git a/src/main/include/log4cxx/spi/loggingevent.h 
b/src/main/include/log4cxx/spi/loggingevent.h
index 1e14764b..d649d9c1 100644
--- a/src/main/include/log4cxx/spi/loggingevent.h
+++ b/src/main/include/log4cxx/spi/loggingevent.h
@@ -26,6 +26,9 @@
 #include <vector>
 #include <chrono>
 
+#if defined(LOG4CXX_ENABLE_STACKTRACE) && LOG4CXX_HAS_BOOST_STACKTRACE
+#include <boost/stacktrace.hpp>
+#endif
 
 namespace log4cxx
 {
@@ -76,6 +79,13 @@ class LOG4CXX_EXPORT LoggingEvent :
                        const LevelPtr& level,   const LogString& message,
                        const log4cxx::spi::LocationInfo& location);
 
+#if defined(LOG4CXX_ENABLE_STACKTRACE) && LOG4CXX_HAS_BOOST_STACKTRACE
+               LoggingEvent(const LogString& logger,
+                       const LevelPtr& level,   const LogString& message,
+                       const log4cxx::spi::LocationInfo& location,
+                       const boost::stacktrace::stacktrace& stacktrace);
+#endif
+
                ~LoggingEvent();
 
                /** Return the level of this event. */

Reply via email to