From 388999a86fc82cf9e8ac2f13f9a5aa52bbc3b72f Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Wed, 20 Feb 2019 14:20:53 +0100 Subject: [PATCH] PerfdataWriter: Rotate and close files on Pause/Shutdown/Reload Refactored the code into a local mutex and added some more debug logging while at it. --- lib/perfdata/perfdatawriter.cpp | 31 +++++++++++++++++++++++++++---- lib/perfdata/perfdatawriter.hpp | 10 ++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/lib/perfdata/perfdatawriter.cpp b/lib/perfdata/perfdatawriter.cpp index c560ef256..7330f3c98 100644 --- a/lib/perfdata/perfdatawriter.cpp +++ b/lib/perfdata/perfdatawriter.cpp @@ -83,6 +83,14 @@ void PerfdataWriter::Resume() void PerfdataWriter::Pause() { +#ifdef I2_DEBUG + //m_HostOutputFile << "\n# Pause the feature" << "\n\n"; + //m_ServiceOutputFile << "\n# Pause the feature" << "\n\n"; +#endif /* I2_DEBUG */ + + /* Force a rotation closing the file stream. */ + RotateAllFiles(); + Log(LogInformation, "PerfdataWriter") << "'" << GetName() << "' paused."; @@ -125,7 +133,8 @@ void PerfdataWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C String line = MacroProcessor::ResolveMacros(GetServiceFormatTemplate(), resolvers, cr, nullptr, &PerfdataWriter::EscapeMacroMetric); { - ObjectLock olock(this); + boost::mutex::scoped_lock lock(m_StreamMutex); + if (!m_ServiceOutputFile.good()) return; @@ -135,7 +144,8 @@ void PerfdataWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C String line = MacroProcessor::ResolveMacros(GetHostFormatTemplate(), resolvers, cr, nullptr, &PerfdataWriter::EscapeMacroMetric); { - ObjectLock olock(this); + boost::mutex::scoped_lock lock(m_StreamMutex); + if (!m_HostOutputFile.good()) return; @@ -146,13 +156,20 @@ void PerfdataWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C void PerfdataWriter::RotateFile(std::ofstream& output, const String& temp_path, const String& perfdata_path) { - ObjectLock olock(this); + Log(LogDebug, "PerfdataWriter") + << "Rotating perfdata files."; + + boost::mutex::scoped_lock lock(m_StreamMutex); if (output.good()) { output.close(); if (Utility::PathExists(temp_path)) { String finalFile = perfdata_path + "." + Convert::ToString((long)Utility::GetTime()); + + Log(LogDebug, "PerfdataWriter") + << "Closed output file and renaming into '" << finalFile << "'."; + if (rename(temp_path.CStr(), finalFile.CStr()) < 0) { BOOST_THROW_EXCEPTION(posix_error() << boost::errinfo_api_function("rename") @@ -164,9 +181,10 @@ void PerfdataWriter::RotateFile(std::ofstream& output, const String& temp_path, output.open(temp_path.CStr()); - if (!output.good()) + if (!output.good()) { Log(LogWarning, "PerfdataWriter") << "Could not open perfdata file '" << temp_path << "' for writing. Perfdata will be lost."; + } } void PerfdataWriter::RotationTimerHandler() @@ -174,6 +192,11 @@ void PerfdataWriter::RotationTimerHandler() if (IsPaused()) return; + RotateAllFiles(); +} + +void PerfdataWriter::RotateAllFiles() +{ RotateFile(m_ServiceOutputFile, GetServiceTempPath(), GetServicePerfdataPath()); RotateFile(m_HostOutputFile, GetHostTempPath(), GetHostPerfdataPath()); } diff --git a/lib/perfdata/perfdatawriter.hpp b/lib/perfdata/perfdatawriter.hpp index 56d01d382..e7ea6aade 100644 --- a/lib/perfdata/perfdatawriter.hpp +++ b/lib/perfdata/perfdatawriter.hpp @@ -51,14 +51,16 @@ protected: void Pause() override; private: + Timer::Ptr m_RotationTimer; + std::ofstream m_ServiceOutputFile; + std::ofstream m_HostOutputFile; + boost::mutex m_StreamMutex; + void CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr); static Value EscapeMacroMetric(const Value& value); - Timer::Ptr m_RotationTimer; void RotationTimerHandler(); - - std::ofstream m_ServiceOutputFile; - std::ofstream m_HostOutputFile; + void RotateAllFiles(); void RotateFile(std::ofstream& output, const String& temp_path, const String& perfdata_path); }; -- 2.40.0