From 4d28a01b84ba0b422a8c605c4e091ed5851cd173 Mon Sep 17 00:00:00 2001 From: Julian Brost Date: Thu, 16 Dec 2021 14:49:50 +0100 Subject: [PATCH] InfluxdbWriter: use atomic_size_t to data buffer size from stats function m_DataBuffer may be modified concurrently while StatsFunc() is called, thus it's unsafe to call size() on it. As write access to m_DataBuffer is already synchronized by only modifying it from the single work queue thread, instead of adding a mutex, this commit adds a new std::atomic_size_t which is additionally updated when modifying m_DataBuffer and can safely be accessed in StatsFunc(). --- lib/perfdata/influxdbwriter.cpp | 4 +++- lib/perfdata/influxdbwriter.hpp | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/perfdata/influxdbwriter.cpp b/lib/perfdata/influxdbwriter.cpp index c2e29f1a2..55eea910c 100644 --- a/lib/perfdata/influxdbwriter.cpp +++ b/lib/perfdata/influxdbwriter.cpp @@ -89,7 +89,7 @@ void InfluxdbWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& for (const InfluxdbWriter::Ptr& influxdbwriter : ConfigType::GetObjectsByType()) { size_t workQueueItems = influxdbwriter->m_WorkQueue.GetLength(); double workQueueItemRate = influxdbwriter->m_WorkQueue.GetTaskCount(60) / 60.0; - size_t dataBufferItems = influxdbwriter->m_DataBuffer.size(); + size_t dataBufferItems = influxdbwriter->m_DataBufferSize; nodes.emplace_back(influxdbwriter->GetName(), new Dictionary({ { "work_queue_items", workQueueItems }, @@ -426,6 +426,7 @@ void InfluxdbWriter::SendMetric(const Checkable::Ptr& checkable, const Dictionar // Buffer the data point m_DataBuffer.emplace_back(msgbuf.str()); + m_DataBufferSize = m_DataBuffer.size(); // Flush if we've buffered too much to prevent excessive memory use if (static_cast(m_DataBuffer.size()) >= GetFlushThreshold()) { @@ -471,6 +472,7 @@ void InfluxdbWriter::FlushWQ() String body = boost::algorithm::join(m_DataBuffer, "\n"); m_DataBuffer.clear(); + m_DataBufferSize = 0; OptionalTlsStream stream; diff --git a/lib/perfdata/influxdbwriter.hpp b/lib/perfdata/influxdbwriter.hpp index 39344bf2e..26d148364 100644 --- a/lib/perfdata/influxdbwriter.hpp +++ b/lib/perfdata/influxdbwriter.hpp @@ -10,6 +10,7 @@ #include "base/timer.hpp" #include "base/tlsstream.hpp" #include "base/workqueue.hpp" +#include #include namespace icinga @@ -40,6 +41,7 @@ private: Timer::Ptr m_FlushTimer; WorkQueue m_WorkQueue{10000000, 1}; std::vector m_DataBuffer; + std::atomic_size_t m_DataBufferSize{0}; void CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr); void CheckResultHandlerWQ(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr);