Skip to content

Commit

Permalink
Reduce logging overhead when the output is unchanged by encoding (#249)
Browse files Browse the repository at this point in the history
* Enable LOG4CXX_MULTI_PROCESS when LOG4CXX_MULTIPROCESS_ROLLING_FILE_APPENDER is enabled
  • Loading branch information
swebb2066 authored Aug 10, 2023
1 parent 78d8e82 commit b36f3b7
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ if(LOG4CXX_NETWORKING_SUPPORT)
endif()

if(LOG4CXX_MULTIPROCESS_ROLLING_FILE_APPENDER)
target_compile_definitions(log4cxx PRIVATE LOG4CXX_MULTI_PROCESS)
list(APPEND extra_classes
multiprocessrollingfileappender.cpp
)
Expand Down
16 changes: 16 additions & 0 deletions src/main/cpp/charsetencoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <apr_xlate.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/transcoder.h>
#include <algorithm>

#if !defined(LOG4CXX)
#define LOG4CXX 1
Expand Down Expand Up @@ -644,3 +645,18 @@ void CharsetEncoder::encode(CharsetEncoderPtr& enc,
dst.put(Transcoder::LOSSCHAR);
}
}

bool CharsetEncoder::isTriviallyCopyable(const LogString& src, const CharsetEncoderPtr& enc)
{
bool result;
#if !LOG4CXX_CHARSET_EBCDIC
if (dynamic_cast<LocaleCharsetEncoder*>(enc.get()))
{
result = src.end() == std::find_if(src.begin(), src.end()
, [](const logchar& ch) -> bool { return 0x80 <= (unsigned int)ch; });
}
else
#endif
result = !!dynamic_cast<TrivialCharsetEncoder*>(enc.get());
return result;
}
30 changes: 19 additions & 11 deletions src/main/cpp/outputstreamwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,29 @@ void OutputStreamWriter::flush(Pool& p)

void OutputStreamWriter::write(const LogString& str, Pool& p)
{
if (str.length() > 0)
if (str.empty())
return;
if (CharsetEncoder::isTriviallyCopyable(str, m_priv->enc))
{
ByteBuffer buf((char*)str.data(), str.size() * sizeof (logchar));
m_priv->out->write(buf, p);
}
else
{
enum { BUFSIZE = 1024 };
char stackData[BUFSIZE];
char* rawbuf = stackData;
size_t bufSize = BUFSIZE;
#ifdef LOG4CXX_MULTI_PROCESS
std::vector<char> heapData;
// Ensure the logging event is a single write system call to keep events from each process separate
size_t bufSize = str.length() * 2;
char* rawbuf = new char[bufSize];
ByteBuffer buf(rawbuf, (size_t) bufSize);
#else
enum { BUFSIZE = 1024 };
char rawbuf[BUFSIZE];
ByteBuffer buf(rawbuf, (size_t) BUFSIZE);
if (bufSize < str.length() * 2)
{
heapData.resize(bufSize = str.length() * 2);
rawbuf = heapData.data();
}
#endif
ByteBuffer buf(rawbuf, bufSize);
m_priv->enc->reset();
LogString::const_iterator iter = str.begin();

Expand All @@ -105,9 +116,6 @@ void OutputStreamWriter::write(const LogString& str, Pool& p)
m_priv->enc->flush(buf);
buf.flip();
m_priv->out->write(buf, p);
#ifdef LOG4CXX_MULTI_PROCESS
delete []rawbuf;
#endif
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/main/include/log4cxx/helpers/charsetencoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ class LOG4CXX_EXPORT CharsetEncoder : public Object
return (stat != 0);
}

/**
* Is the data of \c src unchanged by \c enc.
*
*/
static bool isTriviallyCopyable(const LogString& src, const CharsetEncoderPtr& enc);


private:
/**
Expand Down

0 comments on commit b36f3b7

Please sign in to comment.