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

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


The following commit(s) were added to refs/heads/master by this push:
     new 610018a5 Reduce logging overhead by reserving storage in the output 
string (#246)
610018a5 is described below

commit 610018a5de7d3cda283053cd98a7320ed8753a3d
Author: Stephen Webb <[email protected]>
AuthorDate: Fri Aug 4 10:33:59 2023 +1000

    Reduce logging overhead by reserving storage in the output string (#246)
---
 src/main/cpp/fmtlayout.cpp        | 15 +++++++++++----
 src/main/cpp/htmllayout.cpp       | 14 ++++++++++++--
 src/main/cpp/jsonlayout.cpp       |  9 +++++++--
 src/main/cpp/layout.cpp           | 17 +++++++++++++++++
 src/main/cpp/patternlayout.cpp    | 15 ++++++++++++---
 src/main/cpp/xmllayout.cpp        | 13 ++++++++++++-
 src/main/include/log4cxx/layout.h |  6 ++++++
 7 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/src/main/cpp/fmtlayout.cpp b/src/main/cpp/fmtlayout.cpp
index 38e01a28..79aa7f6a 100644
--- a/src/main/cpp/fmtlayout.cpp
+++ b/src/main/cpp/fmtlayout.cpp
@@ -31,13 +31,19 @@ using namespace log4cxx;
 using namespace log4cxx::spi;
 
 struct FMTLayout::FMTLayoutPrivate{
-       FMTLayoutPrivate(){}
+       FMTLayoutPrivate()
+               : expectedPatternLength(100)
+               {}
 
-       FMTLayoutPrivate(const LogString& pattern) :
-               conversionPattern(pattern)
+       FMTLayoutPrivate(const LogString& pattern)
+               : conversionPattern(pattern)
+               , expectedPatternLength(100)
        {}
 
        LogString conversionPattern;
+
+       // Expected length of a formatted event excluding the message text
+       size_t expectedPatternLength;
 };
 
 IMPLEMENT_LOG4CXX_OBJECT(FMTLayout)
@@ -76,13 +82,14 @@ void FMTLayout::setOption(const LogString& option, const 
LogString& value)
 
 void FMTLayout::activateOptions(helpers::Pool&)
 {
-
+       m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
 }
 
 void FMTLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        log4cxx::helpers::Pool&) const
 {
+       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
        auto locationFull = fmt::format("{}({})",
                                                                                
 event->getLocationInformation().getFileName(),
                                                                                
 event->getLocationInformation().getLineNumber());
diff --git a/src/main/cpp/htmllayout.cpp b/src/main/cpp/htmllayout.cpp
index 53631ca4..297d3ff2 100644
--- a/src/main/cpp/htmllayout.cpp
+++ b/src/main/cpp/htmllayout.cpp
@@ -35,8 +35,12 @@ using namespace log4cxx::spi;
 
 struct HTMLLayout::HTMLLayoutPrivate
 {
-       HTMLLayoutPrivate() : locationInfo(false), title(LOG4CXX_STR("Log4cxx 
Log Messages")),
-               dateFormat() {}
+       HTMLLayoutPrivate()
+               : locationInfo(false)
+               , title(LOG4CXX_STR("Log4cxx Log Messages"))
+               , dateFormat()
+               , expectedPatternLength(100)
+               {}
 
        // Print no location info by default
        bool locationInfo; //= false
@@ -44,6 +48,9 @@ struct HTMLLayout::HTMLLayoutPrivate
        LogString title;
 
        helpers::ISO8601DateFormat dateFormat;
+
+       // Expected length of a formatted event excluding the message text
+       size_t expectedPatternLength;
 };
 
 IMPLEMENT_LOG4CXX_OBJECT(HTMLLayout)
@@ -53,6 +60,7 @@ HTMLLayout::HTMLLayout()
        : m_priv(std::make_unique<HTMLLayoutPrivate>())
 {
        m_priv->dateFormat.setTimeZone(TimeZone::getGMT());
+       m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
 }
 
 HTMLLayout::~HTMLLayout() {}
@@ -71,6 +79,7 @@ void HTMLLayout::setOption(const LogString& option,
                        LOG4CXX_STR("LOCATIONINFO"), 
LOG4CXX_STR("locationinfo")))
        {
                setLocationInfo(OptionConverter::toBoolean(value, false));
+               m_priv->expectedPatternLength = 
getFormattedEventCharacterCount() * 2;
        }
 }
 
@@ -78,6 +87,7 @@ void HTMLLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        Pool& p) const
 {
+       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
        output.append(LOG4CXX_EOL);
        output.append(LOG4CXX_STR("<tr>"));
        output.append(LOG4CXX_EOL);
diff --git a/src/main/cpp/jsonlayout.cpp b/src/main/cpp/jsonlayout.cpp
index fa133a89..d8676122 100644
--- a/src/main/cpp/jsonlayout.cpp
+++ b/src/main/cpp/jsonlayout.cpp
@@ -39,7 +39,8 @@ struct JSONLayout::JSONLayoutPrivate
                prettyPrint(false),
                dateFormat(),
                ppIndentL1(LOG4CXX_STR("  ")),
-               ppIndentL2(LOG4CXX_STR("    ")) {}
+               ppIndentL2(LOG4CXX_STR("    ")),
+               expectedPatternLength(100) {}
 
        // Print no location info by default
        bool locationInfo; //= false
@@ -49,6 +50,9 @@ struct JSONLayout::JSONLayoutPrivate
 
        LogString ppIndentL1;
        LogString ppIndentL2;
+
+       // Expected length of a formatted event excluding the message text
+       size_t expectedPatternLength;
 };
 
 JSONLayout::JSONLayout() :
@@ -85,7 +89,7 @@ LogString JSONLayout::getContentType() const
 
 void JSONLayout::activateOptions(helpers::Pool& /* p */)
 {
-
+       m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
 }
 
 void JSONLayout::setOption(const LogString& option, const LogString& value)
@@ -106,6 +110,7 @@ void JSONLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        Pool& p) const
 {
+       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
        output.append(LOG4CXX_STR("{"));
        output.append(m_priv->prettyPrint ? LOG4CXX_EOL : LOG4CXX_STR(" "));
 
diff --git a/src/main/cpp/layout.cpp b/src/main/cpp/layout.cpp
index 522044d5..02a6ac63 100644
--- a/src/main/cpp/layout.cpp
+++ b/src/main/cpp/layout.cpp
@@ -33,3 +33,20 @@ LogString Layout::getContentType() const
 void Layout::appendHeader(LogString&, log4cxx::helpers::Pool&) {}
 
 void Layout::appendFooter(LogString&, log4cxx::helpers::Pool&) {}
+
+/**
+ * The expected length of a formatted event excluding the message text
+ */
+size_t Layout::getFormattedEventCharacterCount() const
+{
+       auto exampleEvent = std::make_shared<spi::LoggingEvent>
+               ( LOG4CXX_STR("example.logger")
+               , Level::getDebug()
+               , LOG4CXX_LOCATION
+               , LogString()
+               );
+       LogString text;
+       Pool pool;
+       format(text, exampleEvent, pool);
+       return text.size();
+}
diff --git a/src/main/cpp/patternlayout.cpp b/src/main/cpp/patternlayout.cpp
index b7e985e5..4a723c30 100644
--- a/src/main/cpp/patternlayout.cpp
+++ b/src/main/cpp/patternlayout.cpp
@@ -57,9 +57,13 @@ using namespace log4cxx::pattern;
 
 struct PatternLayout::PatternLayoutPrivate
 {
-       PatternLayoutPrivate() {}
-       PatternLayoutPrivate(const LogString& pattern) :
-               conversionPattern(pattern) {}
+       PatternLayoutPrivate()
+               : expectedPatternLength(100)
+               {}
+       PatternLayoutPrivate(const LogString& pattern)
+               : conversionPattern(pattern)
+               , expectedPatternLength(100)
+               {}
 
        /**
         * Conversion pattern.
@@ -82,6 +86,9 @@ struct PatternLayout::PatternLayoutPrivate
        LogString m_infoColor = LOG4CXX_STR("\\x1B[32m"); //green
        LogString m_debugColor = LOG4CXX_STR("\\x1B[36m"); //cyan;
        LogString m_traceColor = LOG4CXX_STR("\\x1B[34m"); //blue;
+
+       // Expected length of a formatted event excluding the message text
+       size_t expectedPatternLength;
 };
 
 IMPLEMENT_LOG4CXX_OBJECT(PatternLayout)
@@ -115,6 +122,7 @@ void PatternLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        Pool& pool) const
 {
+       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
        std::vector<FormattingInfoPtr>::const_iterator formatterIter =
                m_priv->patternFields.begin();
 
@@ -199,6 +207,7 @@ void PatternLayout::activateOptions(Pool&)
                        m_priv->patternConverters.push_back(eventConverter);
                }
        }
+       m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
 }
 
 #define RULES_PUT(spec, cls) \
diff --git a/src/main/cpp/xmllayout.cpp b/src/main/cpp/xmllayout.cpp
index 987e8704..e75daa47 100644
--- a/src/main/cpp/xmllayout.cpp
+++ b/src/main/cpp/xmllayout.cpp
@@ -34,11 +34,18 @@ using namespace log4cxx::xml;
 
 struct XMLLayout::XMLLayoutPrivate
 {
-       XMLLayoutPrivate() : locationInfo(false), properties(false) {}
+       XMLLayoutPrivate()
+               : locationInfo(false)
+               , properties(false)
+               , expectedPatternLength(100)
+               {}
 
        // Print no location info by default
        bool locationInfo; //= false
        bool properties; // = false
+
+       // Expected length of a formatted event excluding the message text
+       size_t expectedPatternLength;
 };
 
 IMPLEMENT_LOG4CXX_OBJECT(XMLLayout)
@@ -46,6 +53,7 @@ IMPLEMENT_LOG4CXX_OBJECT(XMLLayout)
 XMLLayout::XMLLayout()
        : m_priv(std::make_unique<XMLLayoutPrivate>())
 {
+       m_priv->expectedPatternLength = getFormattedEventCharacterCount() * 2;
 }
 
 XMLLayout::~XMLLayout() {}
@@ -56,11 +64,13 @@ void XMLLayout::setOption(const LogString& option,
        if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("LOCATIONINFO"), 
LOG4CXX_STR("locationinfo")))
        {
                setLocationInfo(OptionConverter::toBoolean(value, false));
+               m_priv->expectedPatternLength = 
getFormattedEventCharacterCount() * 2;
        }
 
        if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("PROPERTIES"), 
LOG4CXX_STR("properties")))
        {
                setProperties(OptionConverter::toBoolean(value, false));
+               m_priv->expectedPatternLength = 
getFormattedEventCharacterCount() * 2;
        }
 }
 
@@ -68,6 +78,7 @@ void XMLLayout::format(LogString& output,
        const spi::LoggingEventPtr& event,
        Pool& p) const
 {
+       output.reserve(m_priv->expectedPatternLength + 
event->getMessage().size());
        output.append(LOG4CXX_STR("<log4j:event logger=\""));
        Transform::appendEscapingTags(output, event->getLoggerName());
        output.append(LOG4CXX_STR("\" timestamp=\""));
diff --git a/src/main/include/log4cxx/layout.h 
b/src/main/include/log4cxx/layout.h
index 1025caf2..c4a02ab6 100644
--- a/src/main/include/log4cxx/layout.h
+++ b/src/main/include/log4cxx/layout.h
@@ -75,6 +75,12 @@ class LOG4CXX_EXPORT Layout :
                The other layouts return <code>false</code>.
                */
                virtual bool ignoresThrowable() const = 0;
+
+       protected:
+               /**
+                * The expected length of a formatted event excluding the 
message text
+                */
+               size_t getFormattedEventCharacterCount() const;
 };
 LOG4CXX_PTR_DEF(Layout);
 }

Reply via email to