]> granicus.if.org Git - icinga2/commitdiff
PerfdataWriter: Rotate and close files on Pause/Shutdown/Reload
authorMichael Friedrich <michael.friedrich@icinga.com>
Wed, 20 Feb 2019 13:20:53 +0000 (14:20 +0100)
committerMichael Friedrich <michael.friedrich@icinga.com>
Wed, 20 Feb 2019 13:20:53 +0000 (14:20 +0100)
Refactored the code into a local mutex and added
some more debug logging while at it.

lib/perfdata/perfdatawriter.cpp
lib/perfdata/perfdatawriter.hpp

index c560ef256d1d58778a56e2384036959c98d32c9c..7330f3c98b92e399f9ec79a90aeff41b914acdaa 100644 (file)
@@ -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());
 }
index 56d01d382e261fb0c72711180991e13185af167c..e7ea6aade8d40e69b00300214dbbb0b0f01eee43 100644 (file)
@@ -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);
 };