]> granicus.if.org Git - icinga2/commitdiff
Fix performance data processing in GelfWriter feature 5262/head
authorMichael Friedrich <michael.friedrich@icinga.com>
Mon, 15 May 2017 11:46:43 +0000 (13:46 +0200)
committerMichael Friedrich <michael.friedrich@icinga.com>
Mon, 15 May 2017 11:46:43 +0000 (13:46 +0200)
Includes fixes for possible crashes on empty check results.

fixes #4666

lib/perfdata/gelfwriter.cpp

index 2707640e4167ae69711c9f5000654a62aa20b08d..b8627b81bec049501c7b323ed26efd0675c1aba9 100644 (file)
@@ -99,7 +99,7 @@ void GelfWriter::CheckResultHandler(const Checkable::Ptr& checkable, const Check
        Host::Ptr host;
        Service::Ptr service;
        tie(host, service) = GetHostService(checkable);
-       double ts = cr->GetExecutionEnd();
+       double ts = Utility::GetTime();
 
        Dictionary::Ptr fields = new Dictionary();
 
@@ -120,17 +120,18 @@ void GelfWriter::CheckResultHandler(const Checkable::Ptr& checkable, const Check
        fields->Set("_current_check_attempt", checkable->GetCheckAttempt());
        fields->Set("_max_check_attempts", checkable->GetMaxCheckAttempts());
 
-       fields->Set("_latency", cr->CalculateLatency());
-       fields->Set("_execution_time", cr->CalculateExecutionTime());
-       fields->Set("_reachable",  checkable->IsReachable());
+       fields->Set("_reachable", checkable->IsReachable());
 
        if (cr) {
+               fields->Set("_latency", cr->CalculateLatency());
+               fields->Set("_execution_time", cr->CalculateExecutionTime());
                fields->Set("short_message", CompatUtility::GetCheckResultOutput(cr));
                fields->Set("full_message", cr->GetOutput());
                fields->Set("_check_source", cr->GetCheckSource());
+               ts = cr->GetExecutionEnd();
        }
 
-       if (GetEnableSendPerfdata()) {
+       if (cr && GetEnableSendPerfdata()) {
                Array::Ptr perfdata = cr->GetPerformanceData();
 
                if (perfdata) {
@@ -143,29 +144,29 @@ void GelfWriter::CheckResultHandler(const Checkable::Ptr& checkable, const Check
                                else {
                                        try {
                                                pdv = PerfdataValue::Parse(val);
-
-                                               String escaped_key = pdv->GetLabel();
-                                               boost::replace_all(escaped_key, " ", "_");
-                                               boost::replace_all(escaped_key, ".", "_");
-                                               boost::replace_all(escaped_key, "\\", "_");
-                                               boost::algorithm::replace_all(escaped_key, "::", ".");
-
-                                               fields->Set("_" + escaped_key, pdv->GetValue());
-
-                                               if (pdv->GetMin())
-                                                       fields->Set("_" + escaped_key + "_min", pdv->GetMin());
-                                               if (pdv->GetMax())
-                                                       fields->Set("_" + escaped_key + "_max", pdv->GetMax());
-                                               if (pdv->GetWarn())
-                                                       fields->Set("_" + escaped_key + "_warn", pdv->GetWarn());
-                                               if (pdv->GetCrit())
-                                                       fields->Set("_" + escaped_key + "_crit", pdv->GetCrit());
                                        } catch (const std::exception&) {
                                                Log(LogWarning, "GelfWriter")
                                                    << "Ignoring invalid perfdata value: '" << val << "' for object '"
-                                                   << checkable-GetName() << "'.";
+                                                   << checkable->GetName() << "'.";
                                        }
                                }
+
+                               String escaped_key = pdv->GetLabel();
+                               boost::replace_all(escaped_key, " ", "_");
+                               boost::replace_all(escaped_key, ".", "_");
+                               boost::replace_all(escaped_key, "\\", "_");
+                               boost::algorithm::replace_all(escaped_key, "::", ".");
+
+                               fields->Set("_" + escaped_key, pdv->GetValue());
+
+                               if (pdv->GetMin())
+                                       fields->Set("_" + escaped_key + "_min", pdv->GetMin());
+                               if (pdv->GetMax())
+                                       fields->Set("_" + escaped_key + "_max", pdv->GetMax());
+                               if (pdv->GetWarn())
+                                       fields->Set("_" + escaped_key + "_warn", pdv->GetWarn());
+                               if (pdv->GetCrit())
+                                       fields->Set("_" + escaped_key + "_crit", pdv->GetCrit());
                        }
                }
        }
@@ -185,7 +186,7 @@ void GelfWriter::NotificationToUserHandler(const Notification::Ptr& notification
        Host::Ptr host;
        Service::Ptr service;
        tie(host, service) = GetHostService(checkable);
-       double ts = cr->GetExecutionEnd();
+       double ts = Utility::GetTime();
 
        String notification_type_str = Notification::NotificationTypeToString(notification_type);
 
@@ -197,8 +198,10 @@ void GelfWriter::NotificationToUserHandler(const Notification::Ptr& notification
 
        String output;
 
-       if (cr)
+       if (cr) {
                output = CompatUtility::GetCheckResultOutput(cr);
+               ts = cr->GetExecutionEnd();
+       }
 
        Dictionary::Ptr fields = new Dictionary();
 
@@ -231,7 +234,7 @@ void GelfWriter::StateChangeHandler(const Checkable::Ptr& checkable, const Check
        Host::Ptr host;
        Service::Ptr service;
        tie(host, service) = GetHostService(checkable);
-       double ts = cr->GetExecutionEnd();
+       double ts = Utility::GetTime();
 
        Dictionary::Ptr fields = new Dictionary();
 
@@ -255,6 +258,7 @@ void GelfWriter::StateChangeHandler(const Checkable::Ptr& checkable, const Check
                fields->Set("short_message", CompatUtility::GetCheckResultOutput(cr));
                fields->Set("full_message", cr->GetOutput());
                fields->Set("_check_source", cr->GetCheckSource());
+               ts = cr->GetExecutionEnd();
        }
 
        SendLogMessage(ComposeGelfMessage(fields, GetSource(), ts));