From: Simon Murray Date: Thu, 28 Jul 2016 12:29:37 +0000 (+0100) Subject: Verbose InfluxDB Error Logging X-Git-Tag: v2.7.0~80^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fc2c2d9a294a103605f78720bf08d9f7f2c37d25;p=icinga2 Verbose InfluxDB Error Logging On a non 204 response we parse the HTTP response until complete e.g. do the headers and body, not just the header. A new interface is added to the response to allow us to determine the body size so that it may be read out and buffered. The body is parsed and any error message printed out. In the event that the parsing fails the raw body is dumped out; better than nothing! fixes #4411 Signed-off-by: Michael Friedrich --- diff --git a/lib/perfdata/influxdbwriter.cpp b/lib/perfdata/influxdbwriter.cpp index 14e54da8d..e1f99e160 100644 --- a/lib/perfdata/influxdbwriter.cpp +++ b/lib/perfdata/influxdbwriter.cpp @@ -34,6 +34,7 @@ #include "base/convert.hpp" #include "base/utility.hpp" #include "base/stream.hpp" +#include "base/json.hpp" #include "base/networkstream.hpp" #include "base/exception.hpp" #include "base/statsfunction.hpp" @@ -43,6 +44,7 @@ #include #include #include +#include using namespace icinga; @@ -507,6 +509,36 @@ void InfluxdbWriter::FlushHandler(const String& body) if (resp.StatusCode != 204) { Log(LogWarning, "InfluxdbWriter") << "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") { + Log(LogWarning, "InfluxdbWriter") + << "Unexpected Content-Type: " << contentType; + return; + } + + size_t responseSize = resp.GetBodySize(); + boost::scoped_array buffer(new char[responseSize + 1]); + resp.ReadBody(buffer.get(), responseSize); + buffer.get()[responseSize] = '\0'; + + Dictionary::Ptr jsonResponse; + try { + jsonResponse = JsonDecode(buffer.get()); + } catch (...) { + Log(LogWarning, "InfluxdbWriter") + << "Unable to parse JSON response:\n" << buffer.get(); + return; + } + + String error = jsonResponse->Get("error"); + + Log(LogCritical, "InfluxdbWriter") + << "InfluxDB error message:\n" << error; } } diff --git a/lib/remote/httpresponse.cpp b/lib/remote/httpresponse.cpp index 9c897365f..d66758690 100644 --- a/lib/remote/httpresponse.cpp +++ b/lib/remote/httpresponse.cpp @@ -241,6 +241,14 @@ size_t HttpResponse::ReadBody(char *data, size_t count) return m_Body->Read(data, count, true); } +size_t HttpResponse::GetBodySize(void) const +{ + if (!m_Body) + return 0; + else + return m_Body->GetAvailableBytes(); +} + bool HttpResponse::IsPeerConnected(void) const { return !m_Stream->IsEof(); diff --git a/lib/remote/httpresponse.hpp b/lib/remote/httpresponse.hpp index 0df52580e..0bd686292 100644 --- a/lib/remote/httpresponse.hpp +++ b/lib/remote/httpresponse.hpp @@ -55,6 +55,7 @@ public: bool Parse(StreamReadContext& src, bool may_wait); size_t ReadBody(char *data, size_t count); + size_t GetBodySize(void) const; void SetStatus(int code, const String& message); void AddHeader(const String& key, const String& value);