This is an automated email from the ASF dual-hosted git repository. swebb2066 pushed a commit to branch next_abi_socket_appender in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git
commit cbf6ca0347d7c44c9352f40cb62d53e3f903e29e Author: Stephen Webb <[email protected]> AuthorDate: Fri May 8 11:46:15 2026 +1000 Simplify socket appender sub-classing by enhancing SocketAppenderSkeleton --- src/main/cpp/nteventlogappender.cpp | 2 +- src/main/cpp/socketappenderskeleton.cpp | 155 ++++++++++++--------- src/main/cpp/xmlsocketappender.cpp | 51 +++---- .../include/log4cxx/net/socketappenderskeleton.h | 90 +++++++++--- src/main/include/log4cxx/net/xmlsocketappender.h | 74 ++++------ src/main/include/log4cxx/nt/nteventlogappender.h | 4 +- .../log4cxx/private/socketappenderskeleton_priv.h | 25 +++- 7 files changed, 224 insertions(+), 177 deletions(-) diff --git a/src/main/cpp/nteventlogappender.cpp b/src/main/cpp/nteventlogappender.cpp index 553d107c..fec9447a 100644 --- a/src/main/cpp/nteventlogappender.cpp +++ b/src/main/cpp/nteventlogappender.cpp @@ -223,7 +223,7 @@ void NTEventLogAppender::append( LOG4CXX_APPEND_FORMAL_PARAMETERS ) LogString oss; Pool tempPool; - this->m_priv->layout->format(oss, event, tempPool); + this->m_priv->layout->format(oss, event); wchar_t* msgs = Transcoder::wencode(oss, tempPool); BOOL bSuccess = ::ReportEventW( priv->hEventLog, diff --git a/src/main/cpp/socketappenderskeleton.cpp b/src/main/cpp/socketappenderskeleton.cpp index 930a74f4..00ca2aae 100644 --- a/src/main/cpp/socketappenderskeleton.cpp +++ b/src/main/cpp/socketappenderskeleton.cpp @@ -18,14 +18,16 @@ #define __STDC_CONSTANT_MACROS #include <log4cxx/net/socketappenderskeleton.h> #include <log4cxx/helpers/loglog.h> +#include <log4cxx/helpers/charsetencoder.h> #include <log4cxx/helpers/optionconverter.h> #include <log4cxx/helpers/stringhelper.h> #include <log4cxx/spi/loggingevent.h> #include <log4cxx/helpers/threadutility.h> #include <log4cxx/helpers/transcoder.h> #include <log4cxx/helpers/bytearrayoutputstream.h> +#include <log4cxx/helpers/outputstreamwriter.h> +#include <log4cxx/helpers/socketoutputstream.h> #include <log4cxx/helpers/threadutility.h> -#include <log4cxx/private/appenderskeleton_priv.h> #include <log4cxx/private/socketappenderskeleton_priv.h> #include <functional> #include <chrono> @@ -41,7 +43,11 @@ SocketAppenderSkeleton::SocketAppenderSkeleton(int defaultPort, int reconnection { } +#if LOG4CXX_ABI_VERSION <= 15 SocketAppenderSkeleton::SocketAppenderSkeleton(helpers::InetAddressPtr address, int port, int reconnectionDelay) +#else +SocketAppenderSkeleton::SocketAppenderSkeleton(const helpers::InetAddressPtr& address, int port, int reconnectionDelay) +#endif : AppenderSkeleton(std::make_unique<SocketAppenderSkeletonPriv>(address, port, reconnectionDelay)) { } @@ -62,8 +68,7 @@ SocketAppenderSkeleton::~SocketAppenderSkeleton() void SocketAppenderSkeleton::activateOptions( LOG4CXX_ACTIVATE_OPTIONS_FORMAL_PARAMETERS ) { - Pool my_pool; - connect(my_pool); + _priv->connect(); } void SocketAppenderSkeleton::close() @@ -72,38 +77,37 @@ void SocketAppenderSkeleton::close() _priv->close(); } -void SocketAppenderSkeleton::connect(Pool& p) +void SocketAppenderSkeleton::SocketAppenderSkeletonPriv::connect() { - if (_priv->address == 0) + if (this->address == 0) { LogLog::error(LogString(LOG4CXX_STR("No remote host is set for Appender named \"")) + - _priv->name + LOG4CXX_STR("\".")); + this->name + LOG4CXX_STR("\".")); } else { - _priv->close(); + this->close(); try { if (LogLog::isDebugEnabled()) { LogString msg(LOG4CXX_STR("Connecting to [") - + _priv->address->toString() + LOG4CXX_STR(":")); - StringHelper::toString(_priv->port, msg); + + this->address->toString() + LOG4CXX_STR(":")); + StringHelper::toString(this->port, msg); msg += LOG4CXX_STR("]."); LogLog::debug(msg); } - SocketPtr socket = Socket::create(_priv->address, _priv->port); - setSocket(socket, p); + this->setOutputSink(Socket::create(this->address, this->port)); } catch (SocketException& e) { LogString msg = LOG4CXX_STR("Could not connect to [") - + _priv->address->toString() + LOG4CXX_STR(":"); - StringHelper::toString(_priv->port, msg); + + this->address->toString() + LOG4CXX_STR(":"); + StringHelper::toString(this->port, msg); msg += LOG4CXX_STR("]."); - fireConnector(); // fire the connector thread + this->fireConnector(); // fire the connector thread LogLog::warn(msg, e); } } @@ -133,95 +137,99 @@ void SocketAppenderSkeleton::setOption(const LogString& option, const LogString& } } +void SocketAppenderSkeleton::SocketAppenderSkeletonPriv::fireConnector() +{ + std::lock_guard<std::recursive_mutex> lock(this->mutex); + if (this->taskName.empty()) + { + this->taskName = this->name + LOG4CXX_STR(":") + + this->address->toString() + LOG4CXX_STR(":"); + StringHelper::toString(this->port, this->taskName); + } + auto taskManager = ThreadUtility::instancePtr(); + if (!taskManager->value().hasPeriodicTask(this->taskName)) + { + if (LogLog::isDebugEnabled()) + { + LogString msg(LOG4CXX_STR("Waiting ")); + StringHelper::toString(this->reconnectionDelay, msg); + msg += LOG4CXX_STR(" ms before retrying [") + + this->address->toString() + LOG4CXX_STR(":"); + StringHelper::toString(this->port, msg); + msg += LOG4CXX_STR("]."); + LogLog::debug(msg); + } + taskManager->value().addPeriodicTask(this->taskName + , std::bind(&SocketAppenderSkeleton::SocketAppenderSkeletonPriv::retryConnect, this) + , std::chrono::milliseconds(this->reconnectionDelay) + ); + } + this->taskManager = taskManager; +} + +#if LOG4CXX_ABI_VERSION <= 15 void SocketAppenderSkeleton::fireConnector() { - std::lock_guard<std::recursive_mutex> lock(_priv->mutex); - if (_priv->taskName.empty()) - { - _priv->taskName = _priv->name + LOG4CXX_STR(":") - + _priv->address->toString() + LOG4CXX_STR(":"); - StringHelper::toString(_priv->port, _priv->taskName); - } - auto taskManager = ThreadUtility::instancePtr(); - if (!taskManager->value().hasPeriodicTask(_priv->taskName)) - { - if (LogLog::isDebugEnabled()) - { - LogString msg(LOG4CXX_STR("Waiting ")); - StringHelper::toString(_priv->reconnectionDelay, msg); - msg += LOG4CXX_STR(" ms before retrying [") - + _priv->address->toString() + LOG4CXX_STR(":"); - StringHelper::toString(_priv->port, msg); - msg += LOG4CXX_STR("]."); - LogLog::debug(msg); - } - taskManager->value().addPeriodicTask(_priv->taskName - , std::bind(&SocketAppenderSkeleton::retryConnect, this) - , std::chrono::milliseconds(_priv->reconnectionDelay) - ); - } - _priv->taskManager = taskManager; + _priv->fireConnector(); } +#endif -void SocketAppenderSkeleton::retryConnect() +void SocketAppenderSkeleton::SocketAppenderSkeletonPriv::retryConnect() { - if (is_closed()) + if (this->closed) { - if (auto pManager = _priv->taskManager.lock()) - pManager->value().removePeriodicTask(_priv->taskName); + if (auto pManager = this->taskManager.lock()) + pManager->value().removePeriodicTask(this->taskName); } else { - Pool p; - SocketPtr socket; try { if (LogLog::isDebugEnabled()) { LogString msg(LOG4CXX_STR("Attempting connection to [") - + _priv->address->toString() + LOG4CXX_STR(":")); - StringHelper::toString(_priv->port, msg); + + this->address->toString() + LOG4CXX_STR(":")); + StringHelper::toString(this->port, msg); msg += LOG4CXX_STR("]."); LogLog::debug(msg); } - socket = Socket::create(_priv->address, _priv->port); - setSocket(socket, p); + this->setOutputSink(Socket::create(this->address, this->port)); if (LogLog::isDebugEnabled()) { LogString msg(LOG4CXX_STR("Connection established to [") - + _priv->address->toString() + LOG4CXX_STR(":")); - StringHelper::toString(_priv->port, msg); + + this->address->toString() + LOG4CXX_STR(":")); + StringHelper::toString(this->port, msg); msg += LOG4CXX_STR("]."); LogLog::debug(msg); } - if (auto pManager = _priv->taskManager.lock()) - pManager->value().removePeriodicTask(_priv->taskName); + if (auto pManager = this->taskManager.lock()) + pManager->value().removePeriodicTask(this->taskName); return; } catch (ConnectException& e) { LogLog::warn(LOG4CXX_STR("Remote host ") - + _priv->address->toString() + + this->address->toString() + LOG4CXX_STR(" refused connection."), e); } catch (IOException& e) { LogString msg(LOG4CXX_STR("Could not connect to [") - + _priv->address->toString() + LOG4CXX_STR(":")); - StringHelper::toString(_priv->port, msg); + + this->address->toString() + LOG4CXX_STR(":")); + StringHelper::toString(this->port, msg); msg += LOG4CXX_STR("]."); LogLog::warn(msg, e); } - if (_priv->reconnectionDelay > 0) + if (this->reconnectionDelay > 0) { if (LogLog::isDebugEnabled()) { LogString msg(LOG4CXX_STR("Waiting ")); - StringHelper::toString(_priv->reconnectionDelay, msg); + StringHelper::toString(this->reconnectionDelay, msg); msg += LOG4CXX_STR(" ms before retrying [") - + _priv->address->toString() + LOG4CXX_STR(":"); - StringHelper::toString(_priv->port, msg); + + this->address->toString() + LOG4CXX_STR(":"); + StringHelper::toString(this->port, msg); msg += LOG4CXX_STR("]."); LogLog::debug(msg); } @@ -229,17 +237,30 @@ void SocketAppenderSkeleton::retryConnect() } } +void SocketAppenderSkeleton::SocketAppenderSkeletonPriv::setOutputSink(const SocketPtr& socket) +{ + OutputStreamPtr os = std::make_shared<SocketOutputStream>(socket); + auto charset = CharsetEncoder::getUTF8Encoder(); + this->outputSink = std::make_shared<OutputStreamWriter>(os, charset); +} + void SocketAppenderSkeleton::SocketAppenderSkeletonPriv::close() { if (this->taskName.empty()) ; else if (auto pManager = this->taskManager.lock()) pManager->value().removePeriodicTask(this->taskName); -} - -bool SocketAppenderSkeleton::is_closed() -{ - return _priv->closed; + if (this->outputSink) + { + try + { + this->outputSink->close(); + this->outputSink.reset(); + } + catch (std::exception&) + { + } + } } void SocketAppenderSkeleton::setRemoteHost(const LogString& host) @@ -283,7 +304,7 @@ void SocketAppenderSkeleton::setReconnectionDelay(int reconnectionDelay1) { pManager->value().removePeriodicTask(_priv->taskName); pManager->value().addPeriodicTask(_priv->taskName - , std::bind(&SocketAppenderSkeleton::retryConnect, this) + , std::bind(&SocketAppenderSkeleton::SocketAppenderSkeletonPriv::retryConnect, _priv) , std::chrono::milliseconds(_priv->reconnectionDelay) ); } diff --git a/src/main/cpp/xmlsocketappender.cpp b/src/main/cpp/xmlsocketappender.cpp index 7793626b..60484633 100644 --- a/src/main/cpp/xmlsocketappender.cpp +++ b/src/main/cpp/xmlsocketappender.cpp @@ -17,15 +17,12 @@ #include <log4cxx/net/xmlsocketappender.h> #include <log4cxx/helpers/loglog.h> -#include <log4cxx/helpers/outputstreamwriter.h> -#include <log4cxx/helpers/charsetencoder.h> #include <log4cxx/helpers/optionconverter.h> #include <log4cxx/helpers/stringhelper.h> #include <log4cxx/xml/xmllayout.h> #include <log4cxx/level.h> #include <log4cxx/helpers/transform.h> #include <log4cxx/helpers/transcoder.h> -#include <log4cxx/helpers/socketoutputstream.h> #include <log4cxx/private/appenderskeleton_priv.h> #include <log4cxx/private/socketappenderskeleton_priv.h> @@ -45,9 +42,9 @@ struct XMLSocketAppender::XMLSocketAppenderPriv : public SocketAppenderSkeletonP XMLSocketAppenderPriv(const LogString& host, int port, int delay) : SocketAppenderSkeletonPriv( host, port, delay ) {} - LOG4CXX_NS::helpers::WriterPtr writer; - - void close() override; +#if LOG4CXX_ABI_VERSION <= 15 + LOG4CXX_NS::helpers::WriterPtr unused_writer; +#endif }; IMPLEMENT_LOG4CXX_OBJECT(XMLSocketAppender) @@ -60,7 +57,9 @@ int XMLSocketAppender::DEFAULT_PORT = 4560; // The default reconnection delay (30000 milliseconds or 30 seconds). int XMLSocketAppender::DEFAULT_RECONNECTION_DELAY = 30000; +#if LOG4CXX_ABI_VERSION <= 15 const int XMLSocketAppender::MAX_EVENT_LEN = 1024; +#endif XMLSocketAppender::XMLSocketAppender() : SocketAppenderSkeleton(std::make_unique<XMLSocketAppenderPriv>(DEFAULT_PORT, DEFAULT_RECONNECTION_DELAY)) @@ -68,7 +67,11 @@ XMLSocketAppender::XMLSocketAppender() _priv->layout = std::make_shared<XMLLayout>(); } +#if LOG4CXX_ABI_VERSION <= 15 XMLSocketAppender::XMLSocketAppender(InetAddressPtr address1, int port1) +#else +XMLSocketAppender::XMLSocketAppender(const InetAddressPtr& address1, int port1) +#endif : SocketAppenderSkeleton(std::make_unique<XMLSocketAppenderPriv>(address1, port1, DEFAULT_RECONNECTION_DELAY)) { _priv->layout = std::make_shared<XMLLayout>(); @@ -84,8 +87,6 @@ XMLSocketAppender::XMLSocketAppender(const LogString& host, int port1) XMLSocketAppender::~XMLSocketAppender() { - if (_priv->setClosed()) - _priv->close(); } @@ -99,57 +100,39 @@ int XMLSocketAppender::getDefaultPort() const return DEFAULT_PORT; } +#if LOG4CXX_ABI_VERSION <= 15 void XMLSocketAppender::setSocket(LOG4CXX_NS::helpers::SocketPtr& socket, Pool& p) { - OutputStreamPtr os = std::make_shared<SocketOutputStream>(socket); - CharsetEncoderPtr charset(CharsetEncoder::getUTF8Encoder()); - std::lock_guard<std::recursive_mutex> lock(_priv->mutex); - _priv->writer = std::make_shared<OutputStreamWriter>(os, charset); + _priv->setOutputSink(socket); } -#if LOG4CXX_ABI_VERSION <= 15 + void XMLSocketAppender::cleanUp(Pool& p) { _priv->close(); } #endif -void XMLSocketAppender::XMLSocketAppenderPriv::close() -{ - SocketAppenderSkeletonPriv::close(); - if (this->writer) - { - try - { - this->writer->close(); - this->writer = nullptr; - } - catch (std::exception&) - { - } - } -} - void XMLSocketAppender::append( LOG4CXX_APPEND_FORMAL_PARAMETERS ) { - if (_priv->writer) + if (_priv->outputSink) { LogString output; _priv->layout->format(output, event); try { - _priv->writer->write(output); - _priv->writer->flush(); + _priv->outputSink->write(output); + _priv->outputSink->flush(); } catch (std::exception& e) { - _priv->writer = nullptr; + _priv->outputSink.reset(); LogLog::warn(LOG4CXX_STR("Detected problem with connection: "), e); if (getReconnectionDelay() > 0) { - fireConnector(); + _priv->fireConnector(); } } } diff --git a/src/main/include/log4cxx/net/socketappenderskeleton.h b/src/main/include/log4cxx/net/socketappenderskeleton.h index afb0c530..c96f50ec 100644 --- a/src/main/include/log4cxx/net/socketappenderskeleton.h +++ b/src/main/include/log4cxx/net/socketappenderskeleton.h @@ -19,9 +19,11 @@ #define _LOG4CXX_NET_SOCKET_APPENDER_SKELETON_H #include <log4cxx/appenderskeleton.h> +#include <log4cxx/helpers/inetaddress.h> +#if LOG4CXX_ABI_VERSION <= 15 #include <log4cxx/helpers/socket.h> -#include <thread> -#include <condition_variable> +#endif + namespace LOG4CXX_NS { @@ -30,7 +32,53 @@ namespace net { /** - * Abstract base class for SocketAppender and XMLSocketAppender +Abstract base class that sends spi::LoggingEvent elements to a remote server. + +\anchor socket_appender_properties +This appender has the following properties: + +- The event will be logged with the same time stamp, +NDC, location info as if it were logged locally by +the client. + +- Remote logging uses the TCP protocol, +so if the server is reachable, +log events will eventually arrive at the server. + +- If the remote server is down, the logging requests are simply dropped. +However, if and when the server comes back up, +then event transmission is resumed transparently. +This transparent reconneciton is performed by a <em>connector</em> +task which periodically attempts to connect to the server. + +- Logging events are automatically <em>buffered</em> by the +native TCP implementation. This means that if the link to server +is slow but still faster than the rate of (log) event production +by the client, the client will not be affected by the slow +network connection. However, if the network connection is slower +then the rate of event production, then the client can only +progress at the network rate. In particular, if the network link +to the the server is down, the client will be blocked. +On the other hand, if the network link is up, but the server +is down, the client will not be blocked when making log requests +but the log events will be lost due to server unavailability. + +- If the application hosting this appender exits before it is closed, +either explicitly or subsequent to destruction, +then there might be untransmitted data in the pipe which might be lost. + +To avoid lost data, it is usually sufficient to +#close the appender either explicitly or by +calling the LogManager#shutdown method +before exiting the application. + +A periodic task will connect when the server becomes available. +It does this by attempting to open a new connection every +<code>reconnectionDelay</code> milliseconds. + +The periodic task stops trying whenever a connection is established. +It will restart attempting to open a new connection to the server +when a previously open connection is droppped. */ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton { @@ -44,8 +92,11 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton /** Connects to remote server at <code>address</code> and <code>port</code>. */ +#if LOG4CXX_ABI_VERSION <= 15 SocketAppenderSkeleton(helpers::InetAddressPtr address, int port, int reconnectionDelay); - +#else + SocketAppenderSkeleton(const helpers::InetAddressPtr& address, int port, int reconnectionDelay); +#endif /** Connects to remote server at <code>host</code> and <code>port</code>. */ @@ -61,7 +112,7 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton void close() override; - +#if LOG4CXX_ABI_VERSION <= 15 /** * This appender does not use a layout. Hence, this method * returns <code>false</code>. @@ -71,7 +122,7 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton { return false; } - +#endif /** * The <b>RemoteHost</b> option takes a string value which should be * the host name of the server where a @@ -123,7 +174,12 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton */ int getReconnectionDelay() const; +#if LOG4CXX_ABI_VERSION <= 15 + /** + @deprecated This method will be removed in a future version. + */ void fireConnector(); +#endif /** \copybrief AppenderSkeleton::setOption() @@ -145,9 +201,15 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton protected: SocketAppenderSkeleton(std::unique_ptr<SocketAppenderSkeletonPriv> priv); - virtual void setSocket(LOG4CXX_NS::helpers::SocketPtr& socket, LOG4CXX_NS::helpers::Pool& p) = 0; - #if LOG4CXX_ABI_VERSION <= 15 + /** + @deprecated This method will be removed in a future version. + */ + virtual void setSocket(helpers::SocketPtr& socket, helpers::Pool& p) = 0; + + /** + @deprecated This method will be removed in a future version. + */ virtual void cleanUp(LOG4CXX_NS::helpers::Pool& p) = 0; #endif virtual int getDefaultDelay() const = 0; @@ -155,19 +217,7 @@ class LOG4CXX_EXPORT SocketAppenderSkeleton : public AppenderSkeleton virtual int getDefaultPort() const = 0; private: - void connect(LOG4CXX_NS::helpers::Pool& p); - /** - The Connector will reconnect when the server becomes available - again. It does this by attempting to open a new connection every - <code>reconnectionDelay</code> milliseconds. - - <p>It stops trying whenever a connection is established. It will - restart to try reconnect to the server when previously open - connection is droppped. - */ - void retryConnect(); - bool is_closed(); SocketAppenderSkeleton(const SocketAppenderSkeleton&); SocketAppenderSkeleton& operator=(const SocketAppenderSkeleton&); diff --git a/src/main/include/log4cxx/net/xmlsocketappender.h b/src/main/include/log4cxx/net/xmlsocketappender.h index f22f036f..562bf00f 100644 --- a/src/main/include/log4cxx/net/xmlsocketappender.h +++ b/src/main/include/log4cxx/net/xmlsocketappender.h @@ -19,7 +19,6 @@ #define _LOG4CXX_NET_XML_SOCKET_APPENDER_H #include <log4cxx/net/socketappenderskeleton.h> -#include <log4cxx/helpers/writer.h> namespace LOG4CXX_NS { @@ -47,53 +46,7 @@ running on the same system as the application: </log4j:configuration> ~~~ -<p>XMLSocketAppender has the following properties: - -- The event will be logged with the same time stamp, -NDC, location info as if it were logged locally by -the client. - -- Remote logging uses the TCP protocol. Consequently, if -the server is reachable, then log events will eventually arrive -at the server. - -- If the remote server is down, the logging requests are -simply dropped. However, if and when the server comes back up, -then event transmission is resumed transparently. This -transparent reconneciton is performed by a <em>connector</em> -thread which periodically attempts to connect to the server. - -- Logging events are automatically <em>buffered</em> by the -native TCP implementation. This means that if the link to server -is slow but still faster than the rate of (log) event production -by the client, the client will not be affected by the slow -network connection. However, if the network connection is slower -then the rate of event production, then the client can only -progress at the network rate. In particular, if the network link -to the the server is down, the client will be blocked. -@n @n On the other hand, if the network link is up, but the server -is down, the client will not be blocked when making log requests -but the log events will be lost due to server unavailability. - -- Even if an <code>XMLSocketAppender</code> is no longer -attached to any logger, it will not be destroyed in -the presence of a connector thread. A connector thread exists -only if the connection to the server is down. To avoid this -destruction problem, you should #close the the -<code>XMLSocketAppender</code> explicitly. See also next item. -@n @n Long lived applications which create/destroy many -<code>XMLSocketAppender</code> instances should be aware of this -destruction problem. Most other applications can safely -ignore it. - -- If the application hosting the <code>XMLSocketAppender</code> -exits before the <code>XMLSocketAppender</code> is closed either -explicitly or subsequent to destruction, then there might -be untransmitted data in the pipe which might be lost. -@n @n To avoid lost data, it is usually sufficient to -#close the <code>XMLSocketAppender</code> either explicitly or by -calling the LogManager#shutdown method -before exiting the application. +See \ref socket_appender_properties "SocketAppenderSkeleton" for more information on the behaviour this appender. */ class LOG4CXX_EXPORT XMLSocketAppender : public SocketAppenderSkeleton @@ -109,10 +62,12 @@ class LOG4CXX_EXPORT XMLSocketAppender : public SocketAppenderSkeleton */ static int DEFAULT_RECONNECTION_DELAY; +#if LOG4CXX_ABI_VERSION <= 15 /** Unused */ static const int MAX_EVENT_LEN; +#endif DECLARE_LOG4CXX_OBJECT(XMLSocketAppender) BEGIN_LOG4CXX_CAST_MAP() @@ -126,7 +81,11 @@ class LOG4CXX_EXPORT XMLSocketAppender : public SocketAppenderSkeleton /** Connects to remote server at <code>address</code> and <code>port</code>. */ +#if LOG4CXX_ABI_VERSION <= 15 XMLSocketAppender(helpers::InetAddressPtr address, int port); +#else + XMLSocketAppender(const helpers::InetAddressPtr& address, int port); +#endif /** Connects to remote server at <code>host</code> and <code>port</code>. @@ -135,10 +94,27 @@ class LOG4CXX_EXPORT XMLSocketAppender : public SocketAppenderSkeleton using SocketAppenderSkeleton::activateOptions; +#if 15 < LOG4CXX_ABI_VERSION + /** + * This appender has a default layout. + * @returns false + */ + bool requiresLayout() const override + { + return false; + } +#endif + protected: +#if LOG4CXX_ABI_VERSION <= 15 + /** + @deprecated This method will be removed in a future version. + */ void setSocket(LOG4CXX_NS::helpers::SocketPtr& socket, helpers::Pool& p) override; -#if LOG4CXX_ABI_VERSION <= 15 + /** + @deprecated This method will be removed in a future version. + */ void cleanUp(helpers::Pool& p) override; #endif int getDefaultDelay() const override; diff --git a/src/main/include/log4cxx/nt/nteventlogappender.h b/src/main/include/log4cxx/nt/nteventlogappender.h index 2ebbf969..d88154a7 100644 --- a/src/main/include/log4cxx/nt/nteventlogappender.h +++ b/src/main/include/log4cxx/nt/nteventlogappender.h @@ -69,8 +69,8 @@ class LOG4CXX_EXPORT NTEventLogAppender : public AppenderSkeleton void setOption(const LogString& option, const LogString& value) override; /** - * The SocketAppender does not use a layout. Hence, this method - * returns <code>false</code>. + * This appender does need a layout. + * returns <code>true</code>. * */ bool requiresLayout() const override diff --git a/src/main/include/log4cxx/private/socketappenderskeleton_priv.h b/src/main/include/log4cxx/private/socketappenderskeleton_priv.h index 4e31bb29..e92f0f4e 100644 --- a/src/main/include/log4cxx/private/socketappenderskeleton_priv.h +++ b/src/main/include/log4cxx/private/socketappenderskeleton_priv.h @@ -19,8 +19,9 @@ #include <log4cxx/net/socketappenderskeleton.h> #include <log4cxx/private/appenderskeleton_priv.h> -#include <log4cxx/helpers/inetaddress.h> +#include <log4cxx/helpers/socket.h> #include <log4cxx/helpers/threadutility.h> +#include <log4cxx/helpers/writer.h> namespace LOG4CXX_NS { @@ -38,7 +39,7 @@ struct SocketAppenderSkeleton::SocketAppenderSkeletonPriv : public AppenderSkele locationInfo(false) { } - SocketAppenderSkeletonPriv(helpers::InetAddressPtr address, int defaultPort, int reconnectionDelay) : + SocketAppenderSkeletonPriv(const helpers::InetAddressPtr& address, int defaultPort, int reconnectionDelay) : AppenderSkeletonPrivate(), remoteHost(), address(address), @@ -56,8 +57,10 @@ struct SocketAppenderSkeleton::SocketAppenderSkeletonPriv : public AppenderSkele locationInfo(false) { } - virtual ~SocketAppenderSkeletonPriv() + ~SocketAppenderSkeletonPriv() { + if (this->setClosed()) + this->close(); } /** @@ -73,7 +76,7 @@ struct SocketAppenderSkeleton::SocketAppenderSkeletonPriv : public AppenderSkele int port; int reconnectionDelay; bool locationInfo; - virtual void close(); + void close(); /** Manages asynchronous reconnection attempts. @@ -84,6 +87,20 @@ struct SocketAppenderSkeleton::SocketAppenderSkeletonPriv : public AppenderSkele The reconnection task name. */ LogString taskName; + + /** + The sink for formatted logging events. + */ + helpers::WriterPtr outputSink; + + void connect(); + + void fireConnector(); + + void setOutputSink(const helpers::SocketPtr& socket); + + void retryConnect(); + }; } // namespace net
