]> granicus.if.org Git - icinga2/commitdiff
Fix newline terminator for bulk requests in ElasticsearchWriter
authorMichael Friedrich <michael.friedrich@icinga.com>
Thu, 7 Dec 2017 10:11:03 +0000 (11:11 +0100)
committerMichael Friedrich <michael.friedrich@icinga.com>
Thu, 7 Dec 2017 16:07:44 +0000 (17:07 +0100)
This enables compatibility with 6.x.

This commit also fixes an incorrect HTTP response parsing
which could lead into false positives.

Analysis and fix in https://github.com/Icinga/icinga2/issues/5795#issuecomment-349920587

fixes #5795

refs #5840

lib/perfdata/elasticsearchwriter.cpp

index 69221fd88ff8b943517b6a4cc519573448015586..2171752cacde19be617715e08bda92d035722bdd 100644 (file)
@@ -395,6 +395,11 @@ void ElasticsearchWriter::Flush(void)
        String body = boost::algorithm::join(m_DataBuffer, "\n");
        m_DataBuffer.clear();
 
+       /* Elasticsearch 6.x requires a new line. This is compatible to 5.x.
+        * Tested with 6.0.0 and 5.6.4.
+        */
+       body += "\n";
+
        SendRequest(body);
 }
 
@@ -454,12 +459,20 @@ void ElasticsearchWriter::SendRequest(const String& body)
 
        try {
                resp.Parse(context, true);
+               while (resp.Parse(context, true) && !resp.Complete)
+                       ; /* Do nothing */
        } catch (const std::exception& ex) {
                Log(LogWarning, "ElasticsearchWriter")
-                       << "Cannot read from HTTP API on host '" << GetHost() << "' port '" << GetPort() << "'.";
+                   << "Failed to parse HTTP response from host '" << GetHost() << "' port '" << GetPort() << "': " << DiagnosticInformation(ex, false);
                throw ex;
        }
 
+       if (!resp.Complete) {
+               Log(LogWarning, "ElasticsearchWriter")
+                   << "Failed to read a complete HTTP response from the Elasticsearch server.";
+               return;
+       }
+
        if (resp.StatusCode > 299) {
                if (resp.StatusCode == 401) {
                        /* More verbose error logging with Elasticsearch is hidden behind a proxy. */
@@ -478,10 +491,6 @@ void ElasticsearchWriter::SendRequest(const String& body)
                Log(LogWarning, "ElasticsearchWriter")
                    << "Unexpected response code " << resp.StatusCode;
 
-               /* Finish parsing the headers and body. */
-               while (!resp.Complete)
-                       resp.Parse(context, true);
-
                String contentType = resp.Headers->Get("content-type");
 
                if (contentType != "application/json") {
@@ -508,6 +517,8 @@ void ElasticsearchWriter::SendRequest(const String& body)
 
                Log(LogCritical, "ElasticsearchWriter")
                    << "Elasticsearch error message:\n" << error;
+
+               return;
        }
 }