You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rm...@apache.org on 2022/12/10 02:09:33 UTC
[logging-log4cxx] 01/01: LOGCXX-567 Add optional stacktrace support
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
commit 8f1e6869d56d325c109153ce9d5f205c73c122de
Author: Robert Middleton <ro...@rm5248.com>
AuthorDate: Fri Dec 9 21:09:18 2022 -0500
LOGCXX-567 Add optional stacktrace support
---
CMakeLists.txt | 4 +-
src/main/cpp/CMakeLists.txt | 1 +
src/main/cpp/loggingevent.cpp | 17 ++++++
src/main/cpp/patternlayout.cpp | 3 ++
src/main/cpp/stacktracepatternconverter.cpp | 50 +++++++++++++++++
src/main/include/CMakeLists.txt | 7 +++
.../log4cxx/pattern/stacktracepatternconverter.h | 62 ++++++++++++++++++++++
src/main/include/log4cxx/patternlayout.h | 9 ++++
.../include/log4cxx/private/log4cxx_private.h.in | 1 +
src/main/include/log4cxx/spi/loggingevent.h | 9 ++++
10 files changed, 162 insertions(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fca0f7e2..1cee0564 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -197,8 +197,9 @@ get_directory_property( SHARED_MUTEX_IMPL DIRECTORY src/main/include DEFINITION
get_directory_property( ATOMIC_IMPL DIRECTORY src/main/include DEFINITION ATOMIC_IMPL )
get_directory_property( FILESYSTEM_IMPL DIRECTORY src/main/include DEFINITION FILESYSTEM_IMPL )
get_directory_property( STD_MAKE_UNIQUE_IMPL DIRECTORY src/main/include DEFINITION STD_MAKE_UNIQUE_IMPL )
+get_directory_property( HAS_BOOST_STACKTRACE DIRECTORY src/main/include DEFINITION HAS_BOOST_STACKTRACE )
-foreach(varName HAS_STD_LOCALE HAS_ODBC HAS_MBSRTOWCS HAS_WCSTOMBS HAS_FWIDE HAS_LIBESMTP HAS_SYSLOG HAS_FMT)
+foreach(varName HAS_STD_LOCALE HAS_ODBC HAS_MBSRTOWCS HAS_WCSTOMBS HAS_FWIDE HAS_LIBESMTP HAS_SYSLOG HAS_FMT HAS_BOOST_STACKTRACE)
if(${varName} EQUAL 0)
set(${varName} "OFF" )
elseif(${varName} EQUAL 1)
@@ -278,6 +279,7 @@ message(STATUS " shared_mutex implementation ..... : ${SHARED_MUTEX_IMPL}")
message(STATUS " atomic implementation ........... : ${ATOMIC_IMPL}")
message(STATUS " filesystem implementation ....... : ${FILESYSTEM_IMPL}")
message(STATUS " std::make_unique found? ......... : ${STD_MAKE_UNIQUE_IMPL}")
+message(STATUS " Boost stacktrace support ........ : ${HAS_BOOST_STACKTRACE}")
if(BUILD_TESTING)
message(STATUS "Applications required for tests:")
diff --git a/src/main/cpp/CMakeLists.txt b/src/main/cpp/CMakeLists.txt
index acd4f46a..59276e19 100644
--- a/src/main/cpp/CMakeLists.txt
+++ b/src/main/cpp/CMakeLists.txt
@@ -175,6 +175,7 @@ target_sources(log4cxx
simplelayout.cpp
sizebasedtriggeringpolicy.cpp
smtpappender.cpp
+ stacktracepatternconverter.cpp
strftimedateformat.cpp
stringhelper.cpp
stringmatchfilter.cpp
diff --git a/src/main/cpp/loggingevent.cpp b/src/main/cpp/loggingevent.cpp
index adba3c43..0b1f1930 100644
--- a/src/main/cpp/loggingevent.cpp
+++ b/src/main/cpp/loggingevent.cpp
@@ -39,6 +39,10 @@
#include <log4cxx/private/log4cxx_private.h>
#include <log4cxx/helpers/date.h>
+#if LOG4CXX_HAS_BOOST_STACKTRACE
+#include <boost/stacktrace.hpp>
+#endif
+
using namespace log4cxx;
using namespace log4cxx::spi;
using namespace log4cxx::helpers;
@@ -142,6 +146,10 @@ struct LoggingEvent::LoggingEventPrivate
const LogString& threadUserName;
std::chrono::time_point<std::chrono::system_clock> chronoTimeStamp;
+
+#if LOG4CXX_HAS_BOOST_STACKTRACE
+ boost::stacktrace::stacktrace stacktrace;
+#endif
};
IMPLEMENT_LOG4CXX_OBJECT(LoggingEvent)
@@ -440,3 +448,12 @@ std::chrono::time_point<std::chrono::system_clock> LoggingEvent::getChronoTimeSt
return m_priv->chronoTimeStamp;
}
+LogString LoggingEvent::getStacktrace() const{
+#if !LOG4CXX_HAS_BOOST_STACKTRACE
+ return LogString();
+#else
+ ::log4cxx::helpers::MessageBuffer oss_;
+ return oss_.str(oss_ << m_priv->stacktrace);
+#endif
+}
+
diff --git a/src/main/cpp/patternlayout.cpp b/src/main/cpp/patternlayout.cpp
index b2f6c56b..8fae6bd3 100644
--- a/src/main/cpp/patternlayout.cpp
+++ b/src/main/cpp/patternlayout.cpp
@@ -47,6 +47,7 @@
#include <log4cxx/pattern/propertiespatternconverter.h>
#include <log4cxx/pattern/throwableinformationpatternconverter.h>
#include <log4cxx/pattern/threadusernamepatternconverter.h>
+#include <log4cxx/pattern/stacktracepatternconverter.h>
using namespace log4cxx;
@@ -256,6 +257,8 @@ log4cxx::pattern::PatternMap PatternLayout::getFormatSpecifiers()
RULES_PUT("properties", PropertiesPatternConverter);
RULES_PUT("throwable", ThrowableInformationPatternConverter);
+
+ RULES_PUT("st", StacktracePatternConverter);
return specs;
}
diff --git a/src/main/cpp/stacktracepatternconverter.cpp b/src/main/cpp/stacktracepatternconverter.cpp
new file mode 100644
index 00000000..5fb71db4
--- /dev/null
+++ b/src/main/cpp/stacktracepatternconverter.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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/logstring.h>
+#include <log4cxx/pattern/stacktracepatternconverter.h>
+#include <log4cxx/spi/loggingevent.h>
+#include <log4cxx/helpers/loglog.h>
+
+using namespace log4cxx;
+using namespace log4cxx::pattern;
+using namespace log4cxx::spi;
+using namespace log4cxx::helpers;
+
+IMPLEMENT_LOG4CXX_OBJECT(StacktracePatternConverter)
+
+StacktracePatternConverter::StacktracePatternConverter() :
+ LoggingEventPatternConverter(LOG4CXX_STR("Stacktrace"),
+ LOG4CXX_STR("stacktrace"))
+{
+}
+
+PatternConverterPtr StacktracePatternConverter::newInstance(
+ const std::vector<LogString>& /* options */)
+{
+ static PatternConverterPtr def = std::make_shared<StacktracePatternConverter>();
+ return def;
+}
+
+void StacktracePatternConverter::format(
+ const LoggingEventPtr& event,
+ LogString& toAppendTo,
+ Pool& /* p */) const
+{
+ toAppendTo.append(event->getStacktrace());
+}
+
diff --git a/src/main/include/CMakeLists.txt b/src/main/include/CMakeLists.txt
index 3b235249..4d0ee04f 100644
--- a/src/main/include/CMakeLists.txt
+++ b/src/main/include/CMakeLists.txt
@@ -240,6 +240,13 @@ else()
set(STD_MAKE_UNIQUE_FOUND 0)
endif()
+find_package(Boost COMPONENTS stacktrace)
+if(${Boost_FOUND})
+ set(HAS_BOOST_STACKTRACE 1)
+else()
+ set(HAS_BOOST_STACKTRACE 0)
+endif()
+
# Configure both our private header and our public header
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/log4cxx/private/log4cxx_private.h.in
${CMAKE_CURRENT_BINARY_DIR}/log4cxx/private/log4cxx_private.h
diff --git a/src/main/include/log4cxx/pattern/stacktracepatternconverter.h b/src/main/include/log4cxx/pattern/stacktracepatternconverter.h
new file mode 100644
index 00000000..019dcd2d
--- /dev/null
+++ b/src/main/include/log4cxx/pattern/stacktracepatternconverter.h
@@ -0,0 +1,62 @@
+/*
+ * 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_STACKTRACE_PATTERN_CONVERTER
+#define _LOG4CXX_STACKTRACE_PATTERN_CONVERTER
+
+#include <log4cxx/pattern/loggingeventpatternconverter.h>
+
+namespace log4cxx
+{
+namespace pattern
+{
+
+
+/**
+ * Formats the message of an logging event.
+ *
+ *
+ *
+ */
+class LOG4CXX_EXPORT StacktracePatternConverter : public LoggingEventPatternConverter
+{
+ public:
+ DECLARE_LOG4CXX_PATTERN(StacktracePatternConverter)
+ BEGIN_LOG4CXX_CAST_MAP()
+ LOG4CXX_CAST_ENTRY(StacktracePatternConverter)
+ LOG4CXX_CAST_ENTRY_CHAIN(LoggingEventPatternConverter)
+ END_LOG4CXX_CAST_MAP()
+
+ StacktracePatternConverter();
+
+ /**
+ * Obtains an instance of pattern converter.
+ * @param options options, may be null.
+ * @return instance of pattern converter.
+ */
+ static PatternConverterPtr newInstance(
+ const std::vector<LogString>& options);
+
+ using LoggingEventPatternConverter::format;
+
+ void format(const spi::LoggingEventPtr& event,
+ LogString& toAppendTo,
+ helpers::Pool& p) const override;
+};
+}
+}
+#endif
diff --git a/src/main/include/log4cxx/patternlayout.h b/src/main/include/log4cxx/patternlayout.h
index 3aa1f748..fdb4fb35 100644
--- a/src/main/include/log4cxx/patternlayout.h
+++ b/src/main/include/log4cxx/patternlayout.h
@@ -248,6 +248,15 @@ LOG4CXX_LIST_DEF(FormattingInfoList, log4cxx::pattern::FormattingInfoPtr);
* </td>
* </tr>
* <tr>
+ * <td align="center"><strong>st</strong></td>
+ * <td>
+ * Print the stacktrace(if available). Requires Log4cxx to have been built with Boost
+ * stacktrace support.
+ *
+ * If no stacktrace is available, does not print anything.
+ * </td>
+ * </tr>
+ * <tr>
* <td align="center"><strong>%</strong></td>
* <td>The sequence %% outputs a single percent sign.</td>
* </tr>
diff --git a/src/main/include/log4cxx/private/log4cxx_private.h.in b/src/main/include/log4cxx/private/log4cxx_private.h.in
index 9eb5ec23..b6ad1bdb 100644
--- a/src/main/include/log4cxx/private/log4cxx_private.h.in
+++ b/src/main/include/log4cxx/private/log4cxx_private.h.in
@@ -63,5 +63,6 @@
#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/loggingevent.h b/src/main/include/log4cxx/spi/loggingevent.h
index 8641fcf6..1e14764b 100644
--- a/src/main/include/log4cxx/spi/loggingevent.h
+++ b/src/main/include/log4cxx/spi/loggingevent.h
@@ -177,6 +177,15 @@ class LOG4CXX_EXPORT LoggingEvent :
*/
void setProperty(const LogString& key, const LogString& value);
+ /**
+ * Returns a string of the backtrace. Note that the backtrace is created inside
+ * of the LoggingEvent, and as such will likely be several levels deeper than the line
+ * of code that generated the logging event.
+ *
+ * @return A backtrace string, or nothing if backtrace support is not available.
+ */
+ LogString getStacktrace() const;
+
private:
LOG4CXX_DECLARE_PRIVATE_MEMBER_PTR(LoggingEventPrivate, m_priv)