void InfluxdbWriter::Flush(void) { Stream::Ptr stream = Connect(); // Unable to connect, play it safe and lose the data points // to avoid a memory leak if (!stream.get()) { m_DataBuffer->Clear(); return; } Url::Ptr url = new Url(); url->SetScheme(GetSslEnable() ? "https" : "http"); url->SetHost(GetHost()); url->SetPort(GetPort()); std::vector<String> path; path.push_back("write"); url->SetPath(path); url->AddQueryElement("db", GetDatabase()); url->AddQueryElement("precision", "s"); if (!GetUsername().IsEmpty()) url->AddQueryElement("u", GetUsername()); if (!GetPassword().IsEmpty()) url->AddQueryElement("p", GetPassword()); // Ensure you hold a lock against m_DataBuffer so that things // don't go missing after creating the body and clearing the buffer String body = Utility::Join(m_DataBuffer, '\n', false); m_DataBuffer->Clear(); HttpRequest req(stream); req.RequestMethod = "POST"; req.RequestUrl = url; try { req.WriteBody(body.CStr(), body.GetLength()); req.Finish(); } catch (const std::exception&) { Log(LogWarning, "InfluxdbWriter") << "Cannot write to TCP socket on host '" << GetHost() << "' port '" << GetPort() << "'."; return; } HttpResponse resp(stream, req); StreamReadContext context; try { resp.Parse(context, true); } catch (const std::exception&) { Log(LogWarning, "InfluxdbWriter") << "Cannot read from TCP socket from host '" << GetHost() << "' port '" << GetPort() << "'."; return; } if (resp.StatusCode != 204) { Log(LogWarning, "InfluxdbWriter") << "Unexpected response code " << resp.StatusCode; } }
void InfluxdbWriter::Flush() { String body = boost::algorithm::join(m_DataBuffer, "\n"); m_DataBuffer.clear(); Stream::Ptr stream; try { stream = Connect(); } catch (const std::exception& ex) { Log(LogWarning, "InfluxDbWriter") << "Flush failed, cannot connect to InfluxDB."; return; } if (!stream) return; Url::Ptr url = new Url(); url->SetScheme(GetSslEnable() ? "https" : "http"); url->SetHost(GetHost()); url->SetPort(GetPort()); std::vector<String> path; path.emplace_back("write"); url->SetPath(path); url->AddQueryElement("db", GetDatabase()); url->AddQueryElement("precision", "s"); if (!GetUsername().IsEmpty()) url->AddQueryElement("u", GetUsername()); if (!GetPassword().IsEmpty()) url->AddQueryElement("p", GetPassword()); HttpRequest req(stream); req.RequestMethod = "POST"; req.RequestUrl = url; try { req.WriteBody(body.CStr(), body.GetLength()); req.Finish(); } catch (const std::exception& ex) { Log(LogWarning, "InfluxdbWriter") << "Cannot write to TCP socket on host '" << GetHost() << "' port '" << GetPort() << "'."; throw ex; } HttpResponse resp(stream, req); StreamReadContext context; try { while (resp.Parse(context, true) && !resp.Complete) ; /* Do nothing */ } catch (const std::exception& ex) { Log(LogWarning, "InfluxdbWriter") << "Failed to parse HTTP response from host '" << GetHost() << "' port '" << GetPort() << "': " << DiagnosticInformation(ex); throw ex; } if (!resp.Complete) { Log(LogWarning, "InfluxdbWriter") << "Failed to read a complete HTTP response from the InfluxDB server."; return; } if (resp.StatusCode != 204) { Log(LogWarning, "InfluxdbWriter") << "Unexpected response code: " << resp.StatusCode; 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<char> 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; return; } }