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);
}