diff --git a/src/main/cpp/fmtlayout.cpp b/src/main/cpp/fmtlayout.cpp index 38e01a281..79aa7f6a5 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 53631ca40..297d3ff22 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()) { 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("")); output.append(LOG4CXX_EOL); diff --git a/src/main/cpp/jsonlayout.cpp b/src/main/cpp/jsonlayout.cpp index fa133a89d..d86761224 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 522044d54..02a6ac63e 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 + ( 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 b7e985e5e..4a723c30a 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::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 987e87041..e75daa47e 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()) { + 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("getLoggerName()); output.append(LOG4CXX_STR("\" timestamp=\"")); diff --git a/src/main/include/log4cxx/layout.h b/src/main/include/log4cxx/layout.h index 1025caf20..c4a02ab67 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 false. */ 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); }