diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index 28ff0736e..83c2368a8 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -20,6 +20,7 @@ #include "checker/checkercomponent.hpp" #include "icinga/icingaapplication.hpp" #include "icinga/cib.hpp" +#include "icinga/perfdatavalue.hpp" #include "remote/apilistener.hpp" #include "base/dynamictype.hpp" #include "base/objectlock.hpp" @@ -36,7 +37,7 @@ REGISTER_TYPE(CheckerComponent); REGISTER_STATSFUNCTION(CheckerComponentStats, &CheckerComponent::StatsFunc); -Value CheckerComponent::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) +Value CheckerComponent::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) { Dictionary::Ptr nodes = make_shared(); @@ -51,8 +52,8 @@ Value CheckerComponent::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perf nodes->Set(checker->GetName(), stats); String perfdata_prefix = "checkercomponent_" + checker->GetName() + "_"; - perfdata->Set(perfdata_prefix + "idle", Convert::ToDouble(idle)); - perfdata->Set(perfdata_prefix + "pending", Convert::ToDouble(pending)); + perfdata->Add(make_shared(perfdata_prefix + "idle", Convert::ToDouble(idle))); + perfdata->Add(make_shared(perfdata_prefix + "pending", Convert::ToDouble(pending))); } status->Set("checkercomponent", nodes); diff --git a/components/checker/checkercomponent.hpp b/components/checker/checkercomponent.hpp index 7ed8b0745..ad83ad980 100644 --- a/components/checker/checkercomponent.hpp +++ b/components/checker/checkercomponent.hpp @@ -72,7 +72,7 @@ public: virtual void Start(void); virtual void Stop(void); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); unsigned long GetIdleCheckables(void); unsigned long GetPendingCheckables(void); diff --git a/components/compat/checkresultreader.cpp b/components/compat/checkresultreader.cpp index 436593168..cf22abb6e 100644 --- a/components/compat/checkresultreader.cpp +++ b/components/compat/checkresultreader.cpp @@ -38,7 +38,7 @@ REGISTER_TYPE(CheckResultReader); REGISTER_STATSFUNCTION(CheckResultReaderStats, &CheckResultReader::StatsFunc); -Value CheckResultReader::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value CheckResultReader::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); diff --git a/components/compat/checkresultreader.hpp b/components/compat/checkresultreader.hpp index 12655eebd..84d3d23bd 100644 --- a/components/compat/checkresultreader.hpp +++ b/components/compat/checkresultreader.hpp @@ -38,7 +38,7 @@ public: DECLARE_PTR_TYPEDEFS(CheckResultReader); DECLARE_TYPENAME(CheckResultReader); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); protected: virtual void Start(void); diff --git a/components/compat/compatlogger.cpp b/components/compat/compatlogger.cpp index 969cc7448..e4ca628e6 100644 --- a/components/compat/compatlogger.cpp +++ b/components/compat/compatlogger.cpp @@ -45,7 +45,7 @@ REGISTER_SCRIPTFUNCTION(ValidateRotationMethod, &CompatLogger::ValidateRotationM REGISTER_STATSFUNCTION(CompatLoggerStats, &CompatLogger::StatsFunc); -Value CompatLogger::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value CompatLogger::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); diff --git a/components/compat/compatlogger.hpp b/components/compat/compatlogger.hpp index 512d2a349..c29c09d48 100644 --- a/components/compat/compatlogger.hpp +++ b/components/compat/compatlogger.hpp @@ -39,7 +39,7 @@ public: DECLARE_PTR_TYPEDEFS(CompatLogger); DECLARE_TYPENAME(CompatLogger); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); static void ValidateRotationMethod(const String& location, const Dictionary::Ptr& attrs); diff --git a/components/compat/externalcommandlistener.cpp b/components/compat/externalcommandlistener.cpp index 9174bb9db..dca4ea3f5 100644 --- a/components/compat/externalcommandlistener.cpp +++ b/components/compat/externalcommandlistener.cpp @@ -31,7 +31,7 @@ REGISTER_TYPE(ExternalCommandListener); REGISTER_STATSFUNCTION(ExternalCommandListenerStats, &ExternalCommandListener::StatsFunc); -Value ExternalCommandListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value ExternalCommandListener::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); diff --git a/components/compat/externalcommandlistener.hpp b/components/compat/externalcommandlistener.hpp index 0006aec33..49494c890 100644 --- a/components/compat/externalcommandlistener.hpp +++ b/components/compat/externalcommandlistener.hpp @@ -39,7 +39,7 @@ public: DECLARE_PTR_TYPEDEFS(ExternalCommandListener); DECLARE_TYPENAME(ExternalCommandListener); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); protected: virtual void Start(void); diff --git a/components/compat/statusdatawriter.cpp b/components/compat/statusdatawriter.cpp index 328d9b9ec..e4c3549d4 100644 --- a/components/compat/statusdatawriter.cpp +++ b/components/compat/statusdatawriter.cpp @@ -48,7 +48,7 @@ REGISTER_TYPE(StatusDataWriter); REGISTER_STATSFUNCTION(StatusDataWriterStats, &StatusDataWriter::StatsFunc); -Value StatusDataWriter::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value StatusDataWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); diff --git a/components/compat/statusdatawriter.hpp b/components/compat/statusdatawriter.hpp index 9c8125bff..3024bb101 100644 --- a/components/compat/statusdatawriter.hpp +++ b/components/compat/statusdatawriter.hpp @@ -44,7 +44,7 @@ public: DECLARE_PTR_TYPEDEFS(StatusDataWriter); DECLARE_TYPENAME(StatusDataWriter); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); protected: virtual void Start(void); diff --git a/components/db_ido_mysql/idomysqlconnection.cpp b/components/db_ido_mysql/idomysqlconnection.cpp index f8a82a68e..61b4f5060 100644 --- a/components/db_ido_mysql/idomysqlconnection.cpp +++ b/components/db_ido_mysql/idomysqlconnection.cpp @@ -17,6 +17,10 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ +#include "icinga/perfdatavalue.hpp" +#include "db_ido/dbtype.hpp" +#include "db_ido/dbvalue.hpp" +#include "db_ido_mysql/idomysqlconnection.hpp" #include "base/logger_fwd.hpp" #include "base/objectlock.hpp" #include "base/convert.hpp" @@ -25,9 +29,6 @@ #include "base/dynamictype.hpp" #include "base/exception.hpp" #include "base/statsfunction.hpp" -#include "db_ido/dbtype.hpp" -#include "db_ido/dbvalue.hpp" -#include "db_ido_mysql/idomysqlconnection.hpp" #include #include @@ -38,7 +39,7 @@ using namespace icinga; REGISTER_TYPE(IdoMysqlConnection); REGISTER_STATSFUNCTION(IdoMysqlConnectionStats, &IdoMysqlConnection::StatsFunc); -Value IdoMysqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) +Value IdoMysqlConnection::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) { Dictionary::Ptr nodes = make_shared(); @@ -52,7 +53,7 @@ Value IdoMysqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& pe nodes->Set(idomysqlconnection->GetName(), stats); - perfdata->Set("idomysqlconnection_" + idomysqlconnection->GetName() + "_query_queue_items", Convert::ToDouble(items)); + perfdata->Add(make_shared("idomysqlconnection_" + idomysqlconnection->GetName() + "_query_queue_items", items)); } status->Set("idomysqlconnection", nodes); diff --git a/components/db_ido_mysql/idomysqlconnection.hpp b/components/db_ido_mysql/idomysqlconnection.hpp index 188dcaf70..aa9c11dcd 100644 --- a/components/db_ido_mysql/idomysqlconnection.hpp +++ b/components/db_ido_mysql/idomysqlconnection.hpp @@ -42,7 +42,7 @@ public: DECLARE_PTR_TYPEDEFS(IdoMysqlConnection); DECLARE_TYPENAME(IdoMysqlConnection); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); protected: virtual void Resume(void); diff --git a/components/db_ido_pgsql/idopgsqlconnection.cpp b/components/db_ido_pgsql/idopgsqlconnection.cpp index 045c4f3cc..cb14e5331 100644 --- a/components/db_ido_pgsql/idopgsqlconnection.cpp +++ b/components/db_ido_pgsql/idopgsqlconnection.cpp @@ -17,6 +17,10 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ +#include "db_ido/dbtype.hpp" +#include "db_ido/dbvalue.hpp" +#include "db_ido_pgsql/idopgsqlconnection.hpp" +#include "icinga/perfdatavalue.hpp" #include "base/logger_fwd.hpp" #include "base/objectlock.hpp" #include "base/convert.hpp" @@ -26,9 +30,6 @@ #include "base/exception.hpp" #include "base/context.hpp" #include "base/statsfunction.hpp" -#include "db_ido/dbtype.hpp" -#include "db_ido/dbvalue.hpp" -#include "db_ido_pgsql/idopgsqlconnection.hpp" #include #include @@ -40,7 +41,7 @@ REGISTER_TYPE(IdoPgsqlConnection); REGISTER_STATSFUNCTION(IdoPgsqlConnectionStats, &IdoPgsqlConnection::StatsFunc); -Value IdoPgsqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) +Value IdoPgsqlConnection::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) { Dictionary::Ptr nodes = make_shared(); @@ -54,7 +55,7 @@ Value IdoPgsqlConnection::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& pe nodes->Set(idopgsqlconnection->GetName(), stats); - perfdata->Set("idopgsqlconnection_" + idopgsqlconnection->GetName() + "_query_queue_items", Convert::ToDouble(items)); + perfdata->Add(make_shared("idopgsqlconnection_" + idopgsqlconnection->GetName() + "_query_queue_items", items)); } status->Set("idopgsqlconnection", nodes); diff --git a/components/db_ido_pgsql/idopgsqlconnection.hpp b/components/db_ido_pgsql/idopgsqlconnection.hpp index ff137dcc5..c2da9647c 100644 --- a/components/db_ido_pgsql/idopgsqlconnection.hpp +++ b/components/db_ido_pgsql/idopgsqlconnection.hpp @@ -42,7 +42,7 @@ public: DECLARE_PTR_TYPEDEFS(IdoPgsqlConnection); DECLARE_TYPENAME(IdoPgsqlConnection); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); protected: virtual void Resume(void); diff --git a/components/livestatus/livestatuslistener.cpp b/components/livestatus/livestatuslistener.cpp index 5c67c35ce..90baa8b2a 100644 --- a/components/livestatus/livestatuslistener.cpp +++ b/components/livestatus/livestatuslistener.cpp @@ -18,6 +18,7 @@ ******************************************************************************/ #include "livestatus/livestatuslistener.hpp" +#include "icinga/perfdatavalue.hpp" #include "config/configcompilercontext.hpp" #include "base/utility.hpp" #include "base/objectlock.hpp" @@ -43,7 +44,7 @@ static boost::mutex l_ComponentMutex; REGISTER_STATSFUNCTION(LivestatusListenerStats, &LivestatusListener::StatsFunc); -Value LivestatusListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) +Value LivestatusListener::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata) { Dictionary::Ptr nodes = make_shared(); @@ -53,7 +54,7 @@ Value LivestatusListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& pe nodes->Set(livestatuslistener->GetName(), stats); - perfdata->Set("livestatuslistener_" + livestatuslistener->GetName() + "_connections", Convert::ToDouble(l_Connections)); + perfdata->Add(make_shared("livestatuslistener_" + livestatuslistener->GetName() + "_connections", l_Connections)); } status->Set("livestatuslistener", nodes); diff --git a/components/livestatus/livestatuslistener.hpp b/components/livestatus/livestatuslistener.hpp index 5ddc0ac18..56672721a 100644 --- a/components/livestatus/livestatuslistener.hpp +++ b/components/livestatus/livestatuslistener.hpp @@ -39,7 +39,7 @@ public: DECLARE_PTR_TYPEDEFS(LivestatusListener); DECLARE_TYPENAME(LivestatusListener); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); static int GetClientsConnected(void); static int GetConnections(void); diff --git a/components/notification/notificationcomponent.cpp b/components/notification/notificationcomponent.cpp index 73999421a..09c08958d 100644 --- a/components/notification/notificationcomponent.cpp +++ b/components/notification/notificationcomponent.cpp @@ -34,7 +34,7 @@ REGISTER_TYPE(NotificationComponent); REGISTER_STATSFUNCTION(NotificationComponentStats, &NotificationComponent::StatsFunc); -Value NotificationComponent::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value NotificationComponent::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); diff --git a/components/notification/notificationcomponent.hpp b/components/notification/notificationcomponent.hpp index 6365e8cb0..babca9897 100644 --- a/components/notification/notificationcomponent.hpp +++ b/components/notification/notificationcomponent.hpp @@ -37,7 +37,7 @@ public: DECLARE_PTR_TYPEDEFS(NotificationComponent); DECLARE_TYPENAME(NotificationComponent); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); virtual void Start(void); diff --git a/components/perfdata/graphitewriter.cpp b/components/perfdata/graphitewriter.cpp index e806089ad..fc87a9165 100644 --- a/components/perfdata/graphitewriter.cpp +++ b/components/perfdata/graphitewriter.cpp @@ -46,7 +46,7 @@ REGISTER_TYPE(GraphiteWriter); REGISTER_STATSFUNCTION(GraphiteWriterStats, &GraphiteWriter::StatsFunc); -Value GraphiteWriter::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value GraphiteWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); @@ -134,34 +134,28 @@ void GraphiteWriter::CheckResultHandler(const Checkable::Ptr& checkable, const C void GraphiteWriter::SendPerfdata(const String& prefix, const CheckResult::Ptr& cr) { - Value pdv = cr->GetPerformanceData(); - - if (pdv.IsEmpty()) - return; - - if (!pdv.IsObjectType()) - { - CONTEXT("Processing performance data value '" + String(pdv) + "'"); - Log(LogWarning, "GraphiteWriter", "Could not send performance data: unparsed data."); - return; - } - - Dictionary::Ptr perfdata = pdv; + Array::Ptr perfdata = cr->GetPerformanceData(); ObjectLock olock(perfdata); - BOOST_FOREACH(const Dictionary::Pair& kv, perfdata) { - double valueNum; - - if (!kv.second.IsObjectType()) - valueNum = kv.second; - else - valueNum = static_cast(kv.second)->GetValue(); - - String escaped_key = kv.first; + BOOST_FOREACH(const Value& val, perfdata) { + PerfdataValue::Ptr pdv; + + if (val.IsObjectType()) + pdv = val; + else { + try { + pdv = PerfdataValue::Parse(val); + } catch (const std::exception&) { + Log(LogWarning, "GraphiteWriter", "Ignoring invalid perfdata value: " + val); + continue; + } + } + + String escaped_key = pdv->GetLabel(); SanitizeMetric(escaped_key); boost::algorithm::replace_all(escaped_key, "::", "."); - SendMetric(prefix, escaped_key, valueNum); + SendMetric(prefix, escaped_key, pdv->GetValue()); } } diff --git a/components/perfdata/graphitewriter.hpp b/components/perfdata/graphitewriter.hpp index 7eeb595a3..c2ca05191 100644 --- a/components/perfdata/graphitewriter.hpp +++ b/components/perfdata/graphitewriter.hpp @@ -41,7 +41,7 @@ public: DECLARE_PTR_TYPEDEFS(GraphiteWriter); DECLARE_TYPENAME(GraphiteWriter); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); protected: virtual void Start(void); diff --git a/components/perfdata/perfdatawriter.cpp b/components/perfdata/perfdatawriter.cpp index 213d7b9bd..92c4b6784 100644 --- a/components/perfdata/perfdatawriter.cpp +++ b/components/perfdata/perfdatawriter.cpp @@ -36,7 +36,7 @@ REGISTER_TYPE(PerfdataWriter); REGISTER_STATSFUNCTION(PerfdataWriterStats, &PerfdataWriter::StatsFunc); -Value PerfdataWriter::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value PerfdataWriter::StatsFunc(const Dictionary::Ptr& status, const Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); diff --git a/components/perfdata/perfdatawriter.hpp b/components/perfdata/perfdatawriter.hpp index e8a5bdb12..b7d48e560 100644 --- a/components/perfdata/perfdatawriter.hpp +++ b/components/perfdata/perfdatawriter.hpp @@ -40,7 +40,7 @@ public: DECLARE_PTR_TYPEDEFS(PerfdataWriter); DECLARE_TYPENAME(PerfdataWriter); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(const Dictionary::Ptr& status, const Array::Ptr& perfdata); protected: virtual void Start(void); diff --git a/lib/base/filelogger.cpp b/lib/base/filelogger.cpp index e075e8cb2..f92ced198 100644 --- a/lib/base/filelogger.cpp +++ b/lib/base/filelogger.cpp @@ -29,7 +29,7 @@ REGISTER_TYPE(FileLogger); REGISTER_STATSFUNCTION(FileLoggerStats, &FileLogger::StatsFunc); -Value FileLogger::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value FileLogger::StatsFunc(Dictionary::Ptr& status, Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); diff --git a/lib/base/filelogger.hpp b/lib/base/filelogger.hpp index 072caa6af..4130d6d0e 100644 --- a/lib/base/filelogger.hpp +++ b/lib/base/filelogger.hpp @@ -37,7 +37,7 @@ public: DECLARE_PTR_TYPEDEFS(FileLogger); DECLARE_TYPENAME(FileLogger); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata); virtual void Start(void); diff --git a/lib/base/statsfunction.cpp b/lib/base/statsfunction.cpp index cfaa50fc2..42d12b9c4 100644 --- a/lib/base/statsfunction.cpp +++ b/lib/base/statsfunction.cpp @@ -27,7 +27,7 @@ StatsFunction::StatsFunction(const Callback& function) : m_Callback(function) { } -Value StatsFunction::Invoke(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) +Value StatsFunction::Invoke(Dictionary::Ptr& status, Array::Ptr& perfdata) { return m_Callback(status, perfdata); } diff --git a/lib/base/statsfunction.hpp b/lib/base/statsfunction.hpp index d38073a5a..3f08565de 100644 --- a/lib/base/statsfunction.hpp +++ b/lib/base/statsfunction.hpp @@ -24,6 +24,7 @@ #include "base/registry.hpp" #include "base/value.hpp" #include "base/dictionary.hpp" +#include "base/array.hpp" #include namespace icinga @@ -39,11 +40,11 @@ class I2_BASE_API StatsFunction : public Object public: DECLARE_PTR_TYPEDEFS(StatsFunction); - typedef boost::function Callback; + typedef boost::function Callback; StatsFunction(const Callback& function); - Value Invoke(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + Value Invoke(Dictionary::Ptr& status, Array::Ptr& perfdata); private: Callback m_Callback; diff --git a/lib/base/sysloglogger.cpp b/lib/base/sysloglogger.cpp index 01a9cff0d..d0f26dddc 100644 --- a/lib/base/sysloglogger.cpp +++ b/lib/base/sysloglogger.cpp @@ -28,7 +28,7 @@ REGISTER_TYPE(SyslogLogger); REGISTER_STATSFUNCTION(SyslogLoggerStats, &SyslogLogger::StatsFunc); -Value SyslogLogger::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr&) +Value SyslogLogger::StatsFunc(Dictionary::Ptr& status, Array::Ptr&) { Dictionary::Ptr nodes = make_shared(); diff --git a/lib/base/sysloglogger.hpp b/lib/base/sysloglogger.hpp index 968840f48..694e44b01 100644 --- a/lib/base/sysloglogger.hpp +++ b/lib/base/sysloglogger.hpp @@ -38,7 +38,7 @@ public: DECLARE_PTR_TYPEDEFS(SyslogLogger); DECLARE_TYPENAME(SyslogLogger); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata); protected: virtual void ProcessLogEntry(const LogEntry& entry); diff --git a/lib/icinga/checkresult.ti b/lib/icinga/checkresult.ti index 8f1ff12c6..91c7e8d6b 100644 --- a/lib/icinga/checkresult.ti +++ b/lib/icinga/checkresult.ti @@ -50,7 +50,7 @@ safe class CheckResult [state, enum] ServiceState "state"; [state] String output; - [state] Value performance_data; + [state] Array::Ptr performance_data; [state] bool active { default {{{ return true; }}} diff --git a/lib/icinga/cib.cpp b/lib/icinga/cib.cpp index c6dcae7a3..245734a1d 100644 --- a/lib/icinga/cib.cpp +++ b/lib/icinga/cib.cpp @@ -238,10 +238,10 @@ HostStatistics CIB::CalculateHostStats(void) * 'perfdata' must be a flat dictionary with double values * 'status' dictionary can contain multiple levels of dictionaries */ -std::pair CIB::GetFeatureStats(void) +std::pair CIB::GetFeatureStats(void) { Dictionary::Ptr status = make_shared(); - Dictionary::Ptr perfdata = make_shared(); + Array::Ptr perfdata = make_shared(); String name; Value ret; diff --git a/lib/icinga/cib.hpp b/lib/icinga/cib.hpp index 8269f9250..c475f0daf 100644 --- a/lib/icinga/cib.hpp +++ b/lib/icinga/cib.hpp @@ -23,6 +23,7 @@ #include "icinga/i2-icinga.hpp" #include "base/ringbuffer.hpp" #include "base/dictionary.hpp" +#include "base/array.hpp" namespace icinga { @@ -84,7 +85,7 @@ public: static HostStatistics CalculateHostStats(void); static ServiceStatistics CalculateServiceStats(void); - static std::pair GetFeatureStats(void); + static std::pair GetFeatureStats(void); private: CIB(void); diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index 5fdf49592..2a7b632d9 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -306,13 +306,7 @@ void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::ve CheckResult::Ptr result = make_shared(); std::pair co = PluginUtility::ParseCheckOutput(arguments[2]); result->SetOutput(co.first); - - Value perfdata = co.second; - - if (host->GetEnablePerfdata()) - perfdata = PluginUtility::ParsePerfdata(perfdata); - - result->SetPerformanceData(perfdata); + result->SetPerformanceData(PluginUtility::SplitPerfdata(co.second)); ServiceState state; @@ -358,13 +352,7 @@ void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const std: CheckResult::Ptr result = make_shared(); std::pair co = PluginUtility::ParseCheckOutput(arguments[3]); result->SetOutput(co.first); - - Value perfdata = co.second; - - if (service->GetEnablePerfdata()) - perfdata = PluginUtility::ParsePerfdata(perfdata); - - result->SetPerformanceData(perfdata); + result->SetPerformanceData(PluginUtility::SplitPerfdata(co.second)); result->SetState(PluginUtility::ExitStatusToState(exitStatus)); result->SetScheduleStart(time); diff --git a/lib/icinga/icingaapplication.cpp b/lib/icinga/icingaapplication.cpp index f6c516665..c0393b319 100644 --- a/lib/icinga/icingaapplication.cpp +++ b/lib/icinga/icingaapplication.cpp @@ -63,7 +63,7 @@ void IcingaApplication::StaticInitialize(void) REGISTER_STATSFUNCTION(IcingaApplicationStats, &IcingaApplication::StatsFunc); -Value IcingaApplication::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) +Value IcingaApplication::StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata) { Dictionary::Ptr nodes = make_shared(); diff --git a/lib/icinga/icingaapplication.hpp b/lib/icinga/icingaapplication.hpp index 7071c4a25..4f159a8bf 100644 --- a/lib/icinga/icingaapplication.hpp +++ b/lib/icinga/icingaapplication.hpp @@ -42,7 +42,7 @@ public: int Main(void); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata); static IcingaApplication::Ptr GetInstance(void); diff --git a/lib/icinga/icingastatuswriter.cpp b/lib/icinga/icingastatuswriter.cpp index f3c8283dd..a0c52f5d1 100644 --- a/lib/icinga/icingastatuswriter.cpp +++ b/lib/icinga/icingastatuswriter.cpp @@ -34,7 +34,7 @@ REGISTER_TYPE(IcingaStatusWriter); REGISTER_STATSFUNCTION(IcingaStatusWriterStats, &IcingaStatusWriter::StatsFunc); -Value IcingaStatusWriter::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) +Value IcingaStatusWriter::StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata) { Dictionary::Ptr nodes = make_shared(); @@ -72,7 +72,7 @@ Dictionary::Ptr IcingaStatusWriter::GetStatusData(void) Dictionary::Ptr bag = make_shared(); /* features */ - std::pair stats = CIB::GetFeatureStats(); + std::pair stats = CIB::GetFeatureStats(); bag->Set("feature_status", stats.first); bag->Set("feature_perfdata", stats.second); diff --git a/lib/icinga/icingastatuswriter.hpp b/lib/icinga/icingastatuswriter.hpp index b60412abb..738abbcf6 100644 --- a/lib/icinga/icingastatuswriter.hpp +++ b/lib/icinga/icingastatuswriter.hpp @@ -35,7 +35,7 @@ public: DECLARE_PTR_TYPEDEFS(IcingaStatusWriter); DECLARE_TYPENAME(IcingaStatusWriter); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata); static Dictionary::Ptr GetStatusData(void); protected: diff --git a/lib/icinga/perfdatavalue.cpp b/lib/icinga/perfdatavalue.cpp index e34d833ee..4a0f3d601 100644 --- a/lib/icinga/perfdatavalue.cpp +++ b/lib/icinga/perfdatavalue.cpp @@ -31,9 +31,11 @@ REGISTER_TYPE(PerfdataValue); PerfdataValue::PerfdataValue(void) { } -PerfdataValue::PerfdataValue(double value, bool counter, const String& unit, - const Value& warn, const Value& crit, const Value& min, const Value& max) +PerfdataValue::PerfdataValue(String label, double value, bool counter, + const String& unit, const Value& warn, const Value& crit, const Value& min, + const Value& max) { + SetLabel(label); SetValue(value); SetCounter(counter); SetUnit(unit); @@ -43,23 +45,38 @@ PerfdataValue::PerfdataValue(double value, bool counter, const String& unit, SetMax(max); } -Value PerfdataValue::Parse(const String& perfdata) +PerfdataValue::Ptr PerfdataValue::Parse(const String& perfdata) { - size_t pos = perfdata.FindFirstNotOf("+-0123456789.e"); + size_t eqp = perfdata.FindFirstOf('='); - double value = Convert::ToDouble(perfdata.SubStr(0, pos)); + if (eqp == String::NPos) + BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid performance data value: " + perfdata)); - if (pos == String::NPos) - return value; + String label = perfdata.SubStr(0, eqp); + + if (label.GetLength() > 2 && label[0] == '\'' && label[label.GetLength() - 1] == '\'') + label = label.SubStr(1, label.GetLength() - 2); + + size_t spq = perfdata.FindFirstOf(' ', eqp); + + if (spq == String::NPos) + spq = perfdata.GetLength(); + + String valueStr = perfdata.SubStr(eqp + 1, spq - eqp - 1); + + size_t pos = valueStr.FindFirstNotOf("+-0123456789.e"); + + double value = Convert::ToDouble(valueStr.SubStr(0, pos)); std::vector tokens; - boost::algorithm::split(tokens, perfdata, boost::is_any_of(";")); + boost::algorithm::split(tokens, valueStr, boost::is_any_of(";")); bool counter = false; String unit; Value warn, crit, min, max; - unit = perfdata.SubStr(pos, tokens[0].GetLength() - pos); + if (pos != String::NPos) + unit = valueStr.SubStr(pos, tokens[0].GetLength() - pos); boost::algorithm::to_lower(unit); @@ -122,48 +139,48 @@ Value PerfdataValue::Parse(const String& perfdata) if (!max.IsEmpty()) max = max * base; - return make_shared(value, counter, unit, warn, crit, min, max); + return make_shared(label, value, counter, unit, warn, crit, min, max); } -String PerfdataValue::Format(const Value& perfdata) +String PerfdataValue::Format(void) const { - if (perfdata.IsObjectType()) { - PerfdataValue::Ptr pdv = perfdata; - std::ostringstream result; + std::ostringstream result; - result << Convert::ToString(pdv->GetValue()); + if (GetLabel().FindFirstOf(" ") != String::NPos) + result << "'" << GetLabel() << "'"; + else + result << GetLabel(); - String unit; + result << "=" << Convert::ToString(GetValue()); - if (pdv->GetCounter()) - unit = "c"; - else if (pdv->GetUnit() == "seconds") - unit = "s"; - else if (pdv->GetUnit() == "percent") - unit = "%"; - else if (pdv->GetUnit() == "bytes") - unit = "B"; + String unit; - result << unit; + if (GetCounter()) + unit = "c"; + else if (GetUnit() == "seconds") + unit = "s"; + else if (GetUnit() == "percent") + unit = "%"; + else if (GetUnit() == "bytes") + unit = "B"; - if (!pdv->GetWarn().IsEmpty()) { - result << ";" << pdv->GetWarn(); + result << unit; - if (!pdv->GetCrit().IsEmpty()) { - result << ";" << pdv->GetCrit(); + if (!GetWarn().IsEmpty()) { + result << ";" << Convert::ToString(GetWarn()); - if (!pdv->GetMin().IsEmpty()) { - result << ";" << pdv->GetMin(); + if (!GetCrit().IsEmpty()) { + result << ";" << Convert::ToString(GetCrit()); - if (!pdv->GetMax().IsEmpty()) { - result << ";" << pdv->GetMax(); - } + if (!GetMin().IsEmpty()) { + result << ";" << Convert::ToString(GetMin()); + + if (!GetMax().IsEmpty()) { + result << ";" << Convert::ToString(GetMax()); } } } - - return result.str(); - } else { - return perfdata; } + + return result.str(); } diff --git a/lib/icinga/perfdatavalue.hpp b/lib/icinga/perfdatavalue.hpp index 6d299e03c..019f590aa 100644 --- a/lib/icinga/perfdatavalue.hpp +++ b/lib/icinga/perfdatavalue.hpp @@ -33,12 +33,12 @@ public: PerfdataValue(void); - PerfdataValue(double value, bool counter = false, const String& unit = "", + PerfdataValue(String label, double value, bool counter = false, const String& unit = "", const Value& warn = Empty, const Value& crit = Empty, const Value& min = Empty, const Value& max = Empty); - static Value Parse(const String& perfdata); - static String Format(const Value& perfdata); + static PerfdataValue::Ptr Parse(const String& perfdata); + String Format(void) const; }; } diff --git a/lib/icinga/perfdatavalue.ti b/lib/icinga/perfdatavalue.ti index 0c6ad3702..752d2f1a9 100644 --- a/lib/icinga/perfdatavalue.ti +++ b/lib/icinga/perfdatavalue.ti @@ -5,6 +5,7 @@ namespace icinga safe class PerfdataValue { + [state] String label; [state] double value; [state] bool counter; [state] String unit; diff --git a/lib/icinga/pluginutility.cpp b/lib/icinga/pluginutility.cpp index ab34b9821..715ea66ee 100644 --- a/lib/icinga/pluginutility.cpp +++ b/lib/icinga/pluginutility.cpp @@ -220,80 +220,73 @@ std::pair PluginUtility::ParseCheckOutput(const String& output) return std::make_pair(text, perfdata); } -Value PluginUtility::ParsePerfdata(const String& perfdata) +Array::Ptr PluginUtility::SplitPerfdata(const String& perfdata) { - try { - Dictionary::Ptr result = make_shared(); + Array::Ptr result = make_shared(); - size_t begin = 0; - String multi_prefix; + size_t begin = 0; + String multi_prefix; - for (;;) { - size_t eqp = perfdata.FindFirstOf('=', begin); + for (;;) { + size_t eqp = perfdata.FindFirstOf('=', begin); - if (eqp == String::NPos) - break; + if (eqp == String::NPos) + break; - String key = perfdata.SubStr(begin, eqp - begin); + String label = perfdata.SubStr(begin, eqp - begin); - if (key.GetLength() > 2 && key[0] == '\'' && key[key.GetLength() - 1] == '\'') - key = key.SubStr(1, key.GetLength() - 2); + if (label.GetLength() > 2 && label[0] == '\'' && label[label.GetLength() - 1] == '\'') + label = label.SubStr(1, label.GetLength() - 2); - size_t multi_index = key.RFind("::"); + size_t multi_index = label.RFind("::"); - if (multi_index != String::NPos) - multi_prefix = ""; + if (multi_index != String::NPos) + multi_prefix = ""; - size_t spq = perfdata.FindFirstOf(' ', eqp); + size_t spq = perfdata.FindFirstOf(' ', eqp); - if (spq == String::NPos) - spq = perfdata.GetLength(); + if (spq == String::NPos) + spq = perfdata.GetLength(); - String value = perfdata.SubStr(eqp + 1, spq - eqp - 1); + String value = perfdata.SubStr(eqp + 1, spq - eqp - 1); - if (!multi_prefix.IsEmpty()) - key = multi_prefix + "::" + key; + if (!multi_prefix.IsEmpty()) + label = multi_prefix + "::" + label; - result->Set(key, PerfdataValue::Parse(value)); + String pdv; + if (label.FindFirstOf(" ") != String::NPos) + pdv = "'" + label + "'=" + value; + else + pdv = label + "=" + value; - if (multi_index != String::NPos) - multi_prefix = key.SubStr(0, multi_index); + result->Add(pdv); - begin = spq + 1; - } + if (multi_index != String::NPos) + multi_prefix = label.SubStr(0, multi_index); - return result; - } catch (const std::exception& ex) { - Log(LogWarning, "PluginUtility", "Error parsing performance data '" + perfdata + "': " + ex.what()); - return perfdata; + begin = spq + 1; } + + return result; } -String PluginUtility::FormatPerfdata(const Value& perfdata) +String PluginUtility::FormatPerfdata(const Array::Ptr& perfdata) { std::ostringstream result; - if (!perfdata.IsObjectType()) - return perfdata; - - Dictionary::Ptr dict = perfdata; - - ObjectLock olock(dict); + ObjectLock olock(perfdata); bool first = true; - BOOST_FOREACH(const Dictionary::Pair& kv, dict) { - String key; - if (kv.first.FindFirstOf(" ") != String::NPos) - key = "'" + kv.first + "'"; - else - key = kv.first; - + BOOST_FOREACH(const Value& pdv, perfdata) { if (!first) result << " "; else first = false; - result << key << "=" << PerfdataValue::Format(kv.second); + if (pdv.IsObjectType()) + result << static_cast(pdv)->Format(); + else + result << pdv; } return result.str(); diff --git a/lib/icinga/pluginutility.hpp b/lib/icinga/pluginutility.hpp index 94a6819d8..309aaa26f 100644 --- a/lib/icinga/pluginutility.hpp +++ b/lib/icinga/pluginutility.hpp @@ -46,8 +46,8 @@ public: static ServiceState ExitStatusToState(int exitStatus); static std::pair ParseCheckOutput(const String& output); - static Value ParsePerfdata(const String& perfdata); - static String FormatPerfdata(const Value& perfdata); + static Array::Ptr SplitPerfdata(const String& perfdata); + static String FormatPerfdata(const Array::Ptr& perfdata); private: PluginUtility(void); diff --git a/lib/methods/clusterchecktask.cpp b/lib/methods/clusterchecktask.cpp index 51cc0c65c..efbe4ad08 100644 --- a/lib/methods/clusterchecktask.cpp +++ b/lib/methods/clusterchecktask.cpp @@ -52,7 +52,7 @@ void ClusterCheckTask::ScriptFunc(const Checkable::Ptr& checkable, const CheckRe Dictionary::Ptr status = stats.first; /* use feature stats perfdata */ - std::pair feature_stats = CIB::GetFeatureStats(); + std::pair feature_stats = CIB::GetFeatureStats(); cr->SetPerformanceData(feature_stats.second); String connected_endpoints = FormatArray(status->Get("conn_endpoints")); diff --git a/lib/methods/icingachecktask.cpp b/lib/methods/icingachecktask.cpp index 47d5adeb0..445f367ec 100644 --- a/lib/methods/icingachecktask.cpp +++ b/lib/methods/icingachecktask.cpp @@ -21,6 +21,7 @@ #include "icinga/cib.hpp" #include "icinga/service.hpp" #include "icinga/icingaapplication.hpp" +#include "icinga/perfdatavalue.hpp" #include "base/application.hpp" #include "base/objectlock.hpp" #include "base/utility.hpp" @@ -38,58 +39,58 @@ void IcingaCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResul if (interval > 60) interval = 60; - Dictionary::Ptr perfdata = make_shared(); + Array::Ptr perfdata = make_shared(); - perfdata->Set("active_host_checks", CIB::GetActiveHostChecksStatistics(interval) / interval); - perfdata->Set("passive_host_checks", CIB::GetPassiveHostChecksStatistics(interval) / interval); - perfdata->Set("active_host_checks_1min", CIB::GetActiveHostChecksStatistics(60)); - perfdata->Set("passive_host_checks_1min", CIB::GetPassiveHostChecksStatistics(60)); - perfdata->Set("active_host_checks_5min", CIB::GetActiveHostChecksStatistics(60 * 5)); - perfdata->Set("passive_host_checks_5min", CIB::GetPassiveHostChecksStatistics(60 * 5)); - perfdata->Set("active_host_checks_15min", CIB::GetActiveHostChecksStatistics(60 * 15)); - perfdata->Set("passive_host_checks_15min", CIB::GetPassiveHostChecksStatistics(60 * 15)); + perfdata->Add(make_shared("active_host_checks", CIB::GetActiveHostChecksStatistics(interval) / interval)); + perfdata->Add(make_shared("passive_host_checks", CIB::GetPassiveHostChecksStatistics(interval) / interval)); + perfdata->Add(make_shared("active_host_checks_1min", CIB::GetActiveHostChecksStatistics(60))); + perfdata->Add(make_shared("passive_host_checks_1min", CIB::GetPassiveHostChecksStatistics(60))); + perfdata->Add(make_shared("active_host_checks_5min", CIB::GetActiveHostChecksStatistics(60 * 5))); + perfdata->Add(make_shared("passive_host_checks_5min", CIB::GetPassiveHostChecksStatistics(60 * 5))); + perfdata->Add(make_shared("active_host_checks_15min", CIB::GetActiveHostChecksStatistics(60 * 15))); + perfdata->Add(make_shared("passive_host_checks_15min", CIB::GetPassiveHostChecksStatistics(60 * 15))); - perfdata->Set("active_service_checks", CIB::GetActiveServiceChecksStatistics(interval) / interval); - perfdata->Set("passive_service_checks", CIB::GetPassiveServiceChecksStatistics(interval) / interval); - perfdata->Set("active_service_checks_1min", CIB::GetActiveServiceChecksStatistics(60)); - perfdata->Set("passive_service_checks_1min", CIB::GetPassiveServiceChecksStatistics(60)); - perfdata->Set("active_service_checks_5min", CIB::GetActiveServiceChecksStatistics(60 * 5)); - perfdata->Set("passive_service_checks_5min", CIB::GetPassiveServiceChecksStatistics(60 * 5)); - perfdata->Set("active_service_checks_15min", CIB::GetActiveServiceChecksStatistics(60 * 15)); - perfdata->Set("passive_service_checks_15min", CIB::GetPassiveServiceChecksStatistics(60 * 15)); + perfdata->Add(make_shared("active_service_checks", CIB::GetActiveServiceChecksStatistics(interval) / interval)); + perfdata->Add(make_shared("passive_service_checks", CIB::GetPassiveServiceChecksStatistics(interval) / interval)); + perfdata->Add(make_shared("active_service_checks_1min", CIB::GetActiveServiceChecksStatistics(60))); + perfdata->Add(make_shared("passive_service_checks_1min", CIB::GetPassiveServiceChecksStatistics(60))); + perfdata->Add(make_shared("active_service_checks_5min", CIB::GetActiveServiceChecksStatistics(60 * 5))); + perfdata->Add(make_shared("passive_service_checks_5min", CIB::GetPassiveServiceChecksStatistics(60 * 5))); + perfdata->Add(make_shared("active_service_checks_15min", CIB::GetActiveServiceChecksStatistics(60 * 15))); + perfdata->Add(make_shared("passive_service_checks_15min", CIB::GetPassiveServiceChecksStatistics(60 * 15))); CheckableCheckStatistics scs = CIB::CalculateServiceCheckStats(); - perfdata->Set("min_latency", scs.min_latency); - perfdata->Set("max_latency", scs.max_latency); - perfdata->Set("avg_latency", scs.avg_latency); - perfdata->Set("min_execution_time", scs.min_latency); - perfdata->Set("max_execution_time", scs.max_latency); - perfdata->Set("avg_execution_time", scs.avg_execution_time); + perfdata->Add(make_shared("min_latency", scs.min_latency)); + perfdata->Add(make_shared("max_latency", scs.max_latency)); + perfdata->Add(make_shared("avg_latency", scs.avg_latency)); + perfdata->Add(make_shared("min_execution_time", scs.min_latency)); + perfdata->Add(make_shared("max_execution_time", scs.max_latency)); + perfdata->Add(make_shared("avg_execution_time", scs.avg_execution_time)); ServiceStatistics ss = CIB::CalculateServiceStats(); - perfdata->Set("num_services_ok", ss.services_ok); - perfdata->Set("num_services_warning", ss.services_warning); - perfdata->Set("num_services_critical", ss.services_critical); - perfdata->Set("num_services_unknown", ss.services_unknown); - perfdata->Set("num_services_pending", ss.services_pending); - perfdata->Set("num_services_unreachable", ss.services_unreachable); - perfdata->Set("num_services_flapping", ss.services_flapping); - perfdata->Set("num_services_in_downtime", ss.services_in_downtime); - perfdata->Set("num_services_acknowledged", ss.services_acknowledged); + perfdata->Add(make_shared("num_services_ok", ss.services_ok)); + perfdata->Add(make_shared("num_services_warning", ss.services_warning)); + perfdata->Add(make_shared("num_services_critical", ss.services_critical)); + perfdata->Add(make_shared("num_services_unknown", ss.services_unknown)); + perfdata->Add(make_shared("num_services_pending", ss.services_pending)); + perfdata->Add(make_shared("num_services_unreachable", ss.services_unreachable)); + perfdata->Add(make_shared("num_services_flapping", ss.services_flapping)); + perfdata->Add(make_shared("num_services_in_downtime", ss.services_in_downtime)); + perfdata->Add(make_shared("num_services_acknowledged", ss.services_acknowledged)); double uptime = Utility::GetTime() - Application::GetStartTime(); - perfdata->Set("uptime", uptime); + perfdata->Add(make_shared("uptime", uptime)); HostStatistics hs = CIB::CalculateHostStats(); - perfdata->Set("num_hosts_up", hs.hosts_up); - perfdata->Set("num_hosts_down", hs.hosts_down); - perfdata->Set("num_hosts_unreachable", hs.hosts_unreachable); - perfdata->Set("num_hosts_flapping", hs.hosts_flapping); - perfdata->Set("num_hosts_in_downtime", hs.hosts_in_downtime); - perfdata->Set("num_hosts_acknowledged", hs.hosts_acknowledged); + perfdata->Add(make_shared("num_hosts_up", hs.hosts_up)); + perfdata->Add(make_shared("num_hosts_down", hs.hosts_down)); + perfdata->Add(make_shared("num_hosts_unreachable", hs.hosts_unreachable)); + perfdata->Add(make_shared("num_hosts_flapping", hs.hosts_flapping)); + perfdata->Add(make_shared("num_hosts_in_downtime", hs.hosts_in_downtime)); + perfdata->Add(make_shared("num_hosts_acknowledged", hs.hosts_acknowledged)); cr->SetOutput("Icinga 2 has been running for " + Utility::FormatDuration(uptime) + ". Version: " + Application::GetVersion()); diff --git a/lib/methods/nullchecktask.cpp b/lib/methods/nullchecktask.cpp index e3f5142ac..b0e558d83 100644 --- a/lib/methods/nullchecktask.cpp +++ b/lib/methods/nullchecktask.cpp @@ -21,6 +21,7 @@ # include #endif /* _WIN32 */ #include "methods/nullchecktask.hpp" +#include "icinga/perfdatavalue.hpp" #include "base/utility.hpp" #include "base/convert.hpp" #include "base/scriptfunction.hpp" @@ -35,8 +36,8 @@ void NullCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResult: String output = "Hello from "; output += Utility::GetFQDN(); - Dictionary::Ptr perfdata = make_shared(); - perfdata->Set("time", Convert::ToDouble(Utility::GetTime())); + Array::Ptr perfdata = make_shared(); + perfdata->Add(make_shared("time", Convert::ToDouble(Utility::GetTime()))); cr->SetOutput(output); cr->SetPerformanceData(perfdata); diff --git a/lib/methods/pluginchecktask.cpp b/lib/methods/pluginchecktask.cpp index 39716cce2..e261f56fd 100644 --- a/lib/methods/pluginchecktask.cpp +++ b/lib/methods/pluginchecktask.cpp @@ -68,13 +68,7 @@ void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, co std::pair co = PluginUtility::ParseCheckOutput(output); cr->SetCommand(commandLine); cr->SetOutput(co.first); - - Value perfdata = co.second; - - if (checkable->GetEnablePerfdata()) - perfdata = PluginUtility::ParsePerfdata(perfdata); - - cr->SetPerformanceData(perfdata); + cr->SetPerformanceData(PluginUtility::SplitPerfdata(co.second)); cr->SetState(PluginUtility::ExitStatusToState(pr.ExitStatus)); cr->SetExitStatus(pr.ExitStatus); cr->SetExecutionStart(pr.ExecutionStart); diff --git a/lib/methods/randomchecktask.cpp b/lib/methods/randomchecktask.cpp index f4f78111b..6034a9a45 100644 --- a/lib/methods/randomchecktask.cpp +++ b/lib/methods/randomchecktask.cpp @@ -20,8 +20,8 @@ #ifndef _WIN32 # include #endif /* _WIN32 */ -#include "icinga/icingaapplication.hpp" #include "methods/randomchecktask.hpp" +#include "icinga/perfdatavalue.hpp" #include "base/utility.hpp" #include "base/convert.hpp" #include "base/scriptfunction.hpp" @@ -36,8 +36,8 @@ void RandomCheckTask::ScriptFunc(const Checkable::Ptr& service, const CheckResul String output = "Hello from "; output += Utility::GetFQDN(); - Dictionary::Ptr perfdata = make_shared(); - perfdata->Set("time", Convert::ToDouble(Utility::GetTime())); + Array::Ptr perfdata = make_shared(); + perfdata->Add(make_shared("time", Convert::ToDouble(Utility::GetTime()))); cr->SetOutput(output); cr->SetPerformanceData(perfdata); diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index d2e19a284..d2015f345 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -712,7 +712,7 @@ void ApiListener::ReplayLog(const ApiClient::Ptr& client) } } -Value ApiListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) +Value ApiListener::StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata) { Dictionary::Ptr nodes = make_shared(); std::pair stats; @@ -724,8 +724,8 @@ Value ApiListener::StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata) stats = listener->GetStatus(); - BOOST_FOREACH(Dictionary::Pair const& kv, stats.second) - perfdata->Set("api_" + kv.first, kv.second); + BOOST_FOREACH(const Dictionary::Pair& kv, stats.second) + perfdata->Add("'api_" + kv.first + "'=" + Convert::ToString(kv.second)); status->Set("api", stats.first); diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index 4d0c925d9..855ae2df7 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -58,7 +58,7 @@ public: void RelayMessage(const MessageOrigin& origin, const DynamicObject::Ptr& secobj, const Dictionary::Ptr& message, bool log); - static Value StatsFunc(Dictionary::Ptr& status, Dictionary::Ptr& perfdata); + static Value StatsFunc(Dictionary::Ptr& status, Array::Ptr& perfdata); std::pair GetStatus(void); void AddAnonymousClient(const ApiClient::Ptr& aclient); diff --git a/test/base-serialize.cpp b/test/base-serialize.cpp index 1e9b86985..26d6dc471 100644 --- a/test/base-serialize.cpp +++ b/test/base-serialize.cpp @@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE(dictionary) BOOST_AUTO_TEST_CASE(object) { - PerfdataValue::Ptr pdv = make_shared(100, true, "bytes"); + PerfdataValue::Ptr pdv = make_shared("size", 100, true, "bytes"); PerfdataValue::Ptr result = Deserialize(Serialize(pdv)); diff --git a/test/icinga-perfdata.cpp b/test/icinga-perfdata.cpp index acca81a00..a84b0de1e 100644 --- a/test/icinga-perfdata.cpp +++ b/test/icinga-perfdata.cpp @@ -27,30 +27,34 @@ BOOST_AUTO_TEST_SUITE(icinga_perfdata) BOOST_AUTO_TEST_CASE(empty) { - Dictionary::Ptr pd = PluginUtility::ParsePerfdata(""); + Array::Ptr pd = PluginUtility::SplitPerfdata(""); BOOST_CHECK(pd->GetLength() == 0); } BOOST_AUTO_TEST_CASE(simple) { - Dictionary::Ptr pd = PluginUtility::ParsePerfdata("test=123456"); - BOOST_CHECK(pd->Get("test") == 123456); + PerfdataValue::Ptr pdv = PerfdataValue::Parse("test=123456"); + BOOST_CHECK(pdv->GetLabel() == "test"); + BOOST_CHECK(pdv->GetValue() == 123456); - String str = PluginUtility::FormatPerfdata(pd); + String str = pdv->Format(); BOOST_CHECK(str == "test=123456"); } BOOST_AUTO_TEST_CASE(quotes) { - Dictionary::Ptr pd = PluginUtility::ParsePerfdata("'hello world'=123456"); - BOOST_CHECK(pd->Get("hello world") == 123456); + Array::Ptr pd = PluginUtility::SplitPerfdata("'hello world'=123456"); + BOOST_CHECK(pd->GetLength() == 1); + + PerfdataValue::Ptr pdv = PerfdataValue::Parse("'hello world'=123456"); + BOOST_CHECK(pdv->GetLabel() == "hello world"); + BOOST_CHECK(pdv->GetValue() == 123456); } BOOST_AUTO_TEST_CASE(multiple) { - Dictionary::Ptr pd = PluginUtility::ParsePerfdata("testA=123456 testB=123456"); - BOOST_CHECK(pd->Get("testA") == 123456); - BOOST_CHECK(pd->Get("testB") == 123456); + Array::Ptr pd = PluginUtility::SplitPerfdata("testA=123456 testB=123456"); + BOOST_CHECK(pd->GetLength() == 2); String str = PluginUtility::FormatPerfdata(pd); BOOST_CHECK(str == "testA=123456 testB=123456"); @@ -58,9 +62,7 @@ BOOST_AUTO_TEST_CASE(multiple) BOOST_AUTO_TEST_CASE(uom) { - Dictionary::Ptr pd = PluginUtility::ParsePerfdata("test=123456B"); - - PerfdataValue::Ptr pv = pd->Get("test"); + PerfdataValue::Ptr pv = PerfdataValue::Parse("test=123456B"); BOOST_CHECK(pv); BOOST_CHECK(pv->GetValue() == 123456); @@ -71,13 +73,10 @@ BOOST_AUTO_TEST_CASE(uom) BOOST_CHECK(pv->GetMin() == Empty); BOOST_CHECK(pv->GetMax() == Empty); - String str = PluginUtility::FormatPerfdata(pd); + String str = pv->Format(); BOOST_CHECK(str == "test=123456B"); - pd = PluginUtility::ParsePerfdata("test=1000ms;200;500"); - BOOST_CHECK(pd); - - pv = pd->Get("test"); + pv = PerfdataValue::Parse("test=1000ms;200;500"); BOOST_CHECK(pv); BOOST_CHECK(pv->GetValue() == 1); @@ -85,10 +84,7 @@ BOOST_AUTO_TEST_CASE(uom) BOOST_CHECK(pv->GetWarn() == 0.2); BOOST_CHECK(pv->GetCrit() == 0.5); - pd = PluginUtility::ParsePerfdata("test=1000ms"); - BOOST_CHECK(pd); - - pv = pd->Get("test"); + pv = PerfdataValue::Parse("test=1000ms"); BOOST_CHECK(pv); BOOST_CHECK(pv->GetValue() == 1); @@ -98,15 +94,13 @@ BOOST_AUTO_TEST_CASE(uom) BOOST_CHECK(pv->GetMin() == Empty); BOOST_CHECK(pv->GetMax() == Empty); - str = PluginUtility::FormatPerfdata(pd); + str = pv->Format(); BOOST_CHECK(str == "test=1s"); } BOOST_AUTO_TEST_CASE(warncritminmax) { - Dictionary::Ptr pd = PluginUtility::ParsePerfdata("test=123456B;1000;2000;3000;4000"); - - PerfdataValue::Ptr pv = pd->Get("test"); + PerfdataValue::Ptr pv = PerfdataValue::Parse("test=123456B;1000;2000;3000;4000"); BOOST_CHECK(pv); BOOST_CHECK(pv->GetValue() == 123456); @@ -117,21 +111,20 @@ BOOST_AUTO_TEST_CASE(warncritminmax) BOOST_CHECK(pv->GetMin() == 3000); BOOST_CHECK(pv->GetMax() == 4000); - String str = PluginUtility::FormatPerfdata(pd); - BOOST_CHECK(str == "test=123456B;1000;2000;3000;4000"); + BOOST_CHECK(pv->Format() == "test=123456B;1000;2000;3000;4000"); } BOOST_AUTO_TEST_CASE(invalid) { - BOOST_CHECK(PluginUtility::ParsePerfdata("test=1,23456") == "test=1,23456"); - BOOST_CHECK(PluginUtility::ParsePerfdata("test=123456;10%;20%") == "test=123456;10%;20%"); + BOOST_CHECK_THROW(PerfdataValue::Parse("test=1,23456"), boost::exception); + BOOST_CHECK_THROW(PerfdataValue::Parse("test=123456;10%;20%"), boost::exception); } BOOST_AUTO_TEST_CASE(multi) { - Dictionary::Ptr pd = PluginUtility::ParsePerfdata("test::a=3 b=4"); - BOOST_CHECK(pd->Get("test::a") == 3); - BOOST_CHECK(pd->Get("test::b") == 4); + Array::Ptr pd = PluginUtility::SplitPerfdata("test::a=3 b=4"); + BOOST_CHECK(pd->Get(0) == "test::a=3"); + BOOST_CHECK(pd->Get(1) == "test::b=4"); } BOOST_AUTO_TEST_SUITE_END()