]> granicus.if.org Git - icinga2/commitdiff
Fix: GraphiteWriter: reconnect on broken socket.
authorGunnar Beutner <gunnar.beutner@netways.de>
Fri, 18 Oct 2013 07:11:21 +0000 (09:11 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Fri, 18 Oct 2013 07:11:21 +0000 (09:11 +0200)
Fixes #4883

components/perfdata/graphitewriter.cpp
lib/base/bufferedstream.cpp
lib/base/networkstream.cpp
lib/base/socket.cpp

index ab01a2f075bf6b55bcf303b95947953ccb55c060..9d990af3606d03489aedf9ce8b532745f0da9431 100644 (file)
@@ -37,6 +37,7 @@
 #include <boost/foreach.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/replace.hpp>
+#include <boost/exception/diagnostic_information.hpp>
 
 using namespace icinga;
 
@@ -198,17 +199,28 @@ void GraphiteWriter::AddServiceMetric(std::vector<String>& metrics, const Servic
 
 void GraphiteWriter::SendMetrics(const std::vector<String>& metrics)
 {
-       if (!m_Stream) {
-               Log(LogWarning, "perfdata", "GraphiteWriter not connected!");
-               return;
-       }
-
        BOOST_FOREACH(const String& metric, metrics) {
                if (metric.IsEmpty())
                        continue;
 
                Log(LogDebug, "perfdata", "GraphiteWriter: Sending metric '" + metric + "'.");
-               m_Stream->Write(metric.CStr(), metric.GetLength());
+
+               ObjectLock olock(this);
+
+               if (!m_Stream)
+                       return;
+
+               try {
+                       m_Stream->Write(metric.CStr(), metric.GetLength());
+               } catch (const std::exception& ex) {
+                       std::ostringstream msgbuf;
+                       msgbuf << "Exception thrown while writing to the Graphite socket: " << std::endl
+                               << boost::diagnostic_information(ex);
+
+                       Log(LogCritical, "base", msgbuf.str());
+
+                       m_Stream.reset();
+               }
        }
 }
 
index 8277e32c0817c2b0a6833528e42ebcda280b6b2b..682569cc52995c1915de7908f8546248d724a19c 100644 (file)
@@ -151,6 +151,9 @@ size_t BufferedStream::Read(void *buffer, size_t count)
        if (m_Exception)
                boost::rethrow_exception(m_Exception);
 
+       if (m_Eof)
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Tried to read from closed socket."));
+
        return m_RecvQ->Read(buffer, count);
 }
 
@@ -169,6 +172,9 @@ void BufferedStream::Write(const void *buffer, size_t count)
        if (m_Exception)
                boost::rethrow_exception(m_Exception);
 
+       if (m_Eof)
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Tried to write to closed socket."));
+
        m_SendQ->Write(buffer, count);
        m_WriteCV.notify_all();
 }
index ea86ff2cdc0624f2ba9b367016a70d92383f71d2..d614886eb145ecc6b4bcff819596d3255454bfe3 100644 (file)
@@ -45,6 +45,9 @@ size_t NetworkStream::Read(void *buffer, size_t count)
 {
        size_t rc;
 
+       if (m_Eof)
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Tried to read from closed socket."));
+
        try {
                rc = m_Socket->Read(buffer, count);
        } catch (...) {
@@ -70,6 +73,9 @@ void NetworkStream::Write(const void *buffer, size_t count)
 {
        size_t rc;
 
+       if (m_Eof)
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Tried to write to closed socket."));
+
        try {
                rc = m_Socket->Write(buffer, count);
        } catch (...) {
@@ -78,8 +84,11 @@ void NetworkStream::Write(const void *buffer, size_t count)
                throw;
        }
 
-       if (rc < count)
+       if (rc < count) {
+               m_Eof = true;
+
                BOOST_THROW_EXCEPTION(std::runtime_error("Short write for socket."));
+       }
 }
 
 bool NetworkStream::IsEof(void) const
index 667cbfe99a7f95d50d61c6a244e6a69fcb200f5a..32facc8582a296c8fc3ba8b64f9055d0a45aee1f 100644 (file)
@@ -216,7 +216,7 @@ void Socket::Listen(void)
 }
 
 /**
- * Processes data that is available for this socket.
+ * Sends data for the socket.
  */
 size_t Socket::Write(const void *buffer, size_t count)
 {