summaryrefslogtreecommitdiff
path: root/ext/Log4Qt/src/telnetappender.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ext/Log4Qt/src/telnetappender.cpp')
-rw-r--r--ext/Log4Qt/src/telnetappender.cpp255
1 files changed, 255 insertions, 0 deletions
diff --git a/ext/Log4Qt/src/telnetappender.cpp b/ext/Log4Qt/src/telnetappender.cpp
new file mode 100644
index 0000000..4c96e9f
--- /dev/null
+++ b/ext/Log4Qt/src/telnetappender.cpp
@@ -0,0 +1,255 @@
+/******************************************************************************
+ *
+ * package: Log4Qt
+ * file: telnetappender.cpp
+ * created: July 2010
+ * author: Andreas Bacher
+ *
+ *
+ * Copyright 2010 Andreas Bacher
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * Dependencies
+ ******************************************************************************/
+
+#include "telnetappender.h"
+
+#include <QtCore/QDebug>
+
+#include <QtNetwork/QTcpServer>
+#include <QtNetwork/QTcpSocket>
+#include <QtNetwork/QHostAddress>
+
+#include "layout.h"
+#include "loggingevent.h"
+
+namespace Log4Qt {
+ /**************************************************************************
+ * Declarations
+ **************************************************************************/
+
+ /**************************************************************************
+ * C helper functions
+ **************************************************************************/
+
+ /**************************************************************************
+ * Class implementation: TelnetAppender
+ **************************************************************************/
+
+ TelnetAppender::TelnetAppender(QObject *pParent) :
+ AppenderSkeleton(false, pParent), mAddress(QHostAddress::Any), mPort(23),
+ mpTcpServer(0), mImmediateFlush(false)
+ {
+ }
+
+ TelnetAppender::TelnetAppender(Layout *pLayout, QObject *pParent) :
+ AppenderSkeleton(false, pParent), mAddress(QHostAddress::Any), mPort(23),
+ mpTcpServer(0), mImmediateFlush(false)
+ {
+ setLayout(pLayout);
+ }
+
+ TelnetAppender::TelnetAppender(Layout *pLayout, int port, QObject *pParent) :
+ AppenderSkeleton(false, pParent), mAddress(QHostAddress::Any), mPort(port),
+ mpTcpServer(0), mImmediateFlush(false)
+ {
+ setLayout(pLayout);
+ }
+
+ TelnetAppender::TelnetAppender(Layout *pLayout, const QHostAddress& address,
+ int port, QObject *pParent) :
+ AppenderSkeleton(false, pParent), mAddress(address), mPort(port),
+ mpTcpServer(0), mImmediateFlush(false)
+ {
+ setLayout(pLayout);
+ }
+
+ TelnetAppender::~TelnetAppender()
+ {
+ close();
+ }
+
+ void TelnetAppender::activateOptions()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ closeServer();
+ openServer();
+
+ AppenderSkeleton::activateOptions();
+ }
+
+ void TelnetAppender::close()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (isClosed())
+ return;
+
+ AppenderSkeleton::close();
+ closeServer();
+ }
+
+ void TelnetAppender::setAddress(const QHostAddress& address)
+ {
+ mAddress = address;
+ }
+
+ QHostAddress TelnetAppender::address() const
+ {
+ return mAddress;
+ }
+
+ void TelnetAppender::setPort(int port)
+ {
+ mPort = port;
+ }
+
+ int TelnetAppender::port() const
+ {
+ return mPort;
+ }
+
+ void TelnetAppender::setWelcomeMessage(const QString & welcomeMessage)
+ {
+ mWelcomeMessage = welcomeMessage;
+ }
+
+ bool TelnetAppender::requiresLayout() const
+ {
+ return true;
+ }
+
+ void TelnetAppender::append(const LoggingEvent &rEvent)
+ {
+ // Q_ASSERT_X(, "TelnetAppender::append()", "Lock must be held by caller");
+ Q_ASSERT_X(layout(), "TelnetAppender::append()", "Layout must not be null");
+
+ QString message(layout()->format(rEvent));
+
+ Q_FOREACH (QTcpSocket * pClientConnection, mTcpSockets)
+ {
+ pClientConnection->write(message.toLocal8Bit().constData());
+ if (immediateFlush())
+ pClientConnection->flush();
+ }
+ }
+
+ bool TelnetAppender::checkEntryConditions() const
+ {
+ // Q_ASSERT_X(, "TelnetAppender::checkEntryConditions()", "Lock must be held by caller")
+
+ if (!mpTcpServer && !mpTcpServer->isListening()) {
+ LogError
+ e =
+ LOG4QT_QCLASS_ERROR(QT_TR_NOOP("Use of appender '%1' without a listing telnet server"),
+ APPENDER_TELNET_SERVER_NOT_RUNNING);
+ e << name();
+ logger()->error(e);
+ return false;
+ }
+
+ return AppenderSkeleton::checkEntryConditions();
+ }
+
+ void TelnetAppender::openServer()
+ {
+ mpTcpServer = new QTcpServer(this);
+ connect(mpTcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
+ mpTcpServer->listen(mAddress, mPort);
+ }
+
+ void TelnetAppender::closeServer()
+ {
+ if (mpTcpServer)
+ mpTcpServer->close();
+
+ Q_FOREACH(QTcpSocket * pClientConnection, mTcpSockets)
+ delete pClientConnection;
+
+ mTcpSockets.clear();
+
+ delete mpTcpServer;
+ mpTcpServer = 0;
+ }
+
+ QList<QTcpSocket*> TelnetAppender::clients() const
+ {
+ return mTcpSockets;
+ }
+
+#ifndef QT_NO_DEBUG_STREAM
+ QDebug TelnetAppender::debug(QDebug &rDebug) const
+ {
+ QString layout_name;
+ if (layout())
+ layout_name = layout()->name();
+
+ rDebug.nospace() << "TelnetAppender(" << "name:" << name() << " "
+ << "filter:" << firstFilter() << "isactive:" << isActive()
+ << "isclosed:" << isClosed() << "layout:" << layout_name
+ << "referencecount:" << referenceCount() << " " << "threshold:"
+ << threshold().toString() << "address:" << address() << "port:"
+ << port() << " " << ")";
+ return rDebug.space();
+ }
+#endif // QT_NO_DEBUG_STREAM
+ bool TelnetAppender::handleIoErrors() const
+ {
+ // Q_ASSERT_X(, "FileAppender::handleIoErrors()", "Lock must be held by caller")
+ return false;
+ }
+
+ void TelnetAppender::onNewConnection()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ if (mpTcpServer && mpTcpServer->hasPendingConnections()) {
+ QTcpSocket * pClientConnection = mpTcpServer->nextPendingConnection();
+ if (pClientConnection) {
+ mTcpSockets.append(pClientConnection);
+ connect(pClientConnection, SIGNAL(disconnected()), this,
+ SLOT(onClientDisconnected()));
+ sendWelcomeMessage(pClientConnection);
+ }
+ }
+ }
+
+ void TelnetAppender::sendWelcomeMessage(QTcpSocket * pClientConnection)
+ {
+ if (mWelcomeMessage.isEmpty())
+ return;
+
+ pClientConnection->write(mWelcomeMessage.toLocal8Bit().constData());
+ }
+
+ void TelnetAppender::onClientDisconnected()
+ {
+ QMutexLocker locker(&mObjectGuard);
+
+ QTcpSocket* pClientConnection = qobject_cast<QTcpSocket*> (sender());
+ if (pClientConnection) {
+ mTcpSockets.removeOne(pClientConnection);
+ pClientConnection->deleteLater();
+ }
+ }
+
+/******************************************************************************
+ * Implementation: Operators, Helper
+ ******************************************************************************/
+
+} // namespace Log4Qt